RPCs always contain an input, hence we do not need specializations.
Collapse the three classes into a single one.
Change-Id: Icdd126a8d6b1c6d352eaedf3efdd7b85e96c5f18
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
*/
package org.opendaylight.mdsal.binding.dom.adapter.invoke;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Throwables;
import com.google.common.util.concurrent.ListenableFuture;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
-import java.util.Optional;
import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
-import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.RpcService;
import org.opendaylight.yangtools.yang.common.RpcResult;
-abstract class RpcMethodInvoker {
+final class RpcMethodInvoker {
+ private static final MethodType INVOCATION_SIGNATURE = MethodType.methodType(ListenableFuture.class,
+ RpcService.class, DataObject.class);
- private static final Lookup LOOKUP = MethodHandles.publicLookup();
+ private final MethodHandle handle;
- abstract ListenableFuture<RpcResult<?>> invokeOn(RpcService impl, DataObject input);
+ @VisibleForTesting
+ RpcMethodInvoker(final MethodHandle handle) {
+ this.handle = handle.asType(INVOCATION_SIGNATURE);
+ }
+
+ static RpcMethodInvoker from(final Method method) {
+ BindingReflections.resolveRpcInputClass(method)
+ .orElseThrow(() -> new IllegalArgumentException("Method " + method + " does not have an input argument"));
- protected static RpcMethodInvoker from(final Method method) {
final MethodHandle methodHandle;
try {
- methodHandle = LOOKUP.unreflect(method);
+ methodHandle = MethodHandles.publicLookup().unreflect(method);
} catch (IllegalAccessException e) {
- throw new IllegalStateException("Lookup on public method failed.",e);
+ throw new IllegalStateException("Lookup on public method failed.", e);
}
- final Optional<Class<? extends DataContainer>> input = BindingReflections.resolveRpcInputClass(method);
- if (input.isPresent()) {
- return new RpcMethodInvokerWithInput(methodHandle);
+ return new RpcMethodInvoker(methodHandle);
+ }
+
+ @SuppressWarnings("checkstyle:illegalCatch")
+ ListenableFuture<RpcResult<?>> invokeOn(final RpcService impl, final DataObject input) {
+ try {
+ return (ListenableFuture<RpcResult<?>>) handle.invokeExact(impl,input);
+ } catch (Throwable e) {
+ Throwables.throwIfUnchecked(e);
+ throw new IllegalStateException(e);
}
- return new RpcMethodInvokerWithoutInput(methodHandle);
}
}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.mdsal.binding.dom.adapter.invoke;
-
-import com.google.common.base.Throwables;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodType;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.RpcService;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-
-class RpcMethodInvokerWithInput extends RpcMethodInvoker {
- private static final MethodType INVOCATION_SIGNATURE = MethodType.methodType(ListenableFuture.class,
- RpcService.class, DataObject.class);
-
- private final MethodHandle handle;
-
- RpcMethodInvokerWithInput(final MethodHandle methodHandle) {
- this.handle = methodHandle.asType(INVOCATION_SIGNATURE);
- }
-
- @Override
- @SuppressWarnings("checkstyle:illegalCatch")
- ListenableFuture<RpcResult<?>> invokeOn(final RpcService impl, final DataObject input) {
- try {
- return (ListenableFuture<RpcResult<?>>) handle.invokeExact(impl,input);
- } catch (Throwable e) {
- Throwables.throwIfUnchecked(e);
- throw new IllegalStateException(e);
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.mdsal.binding.dom.adapter.invoke;
-
-import com.google.common.base.Throwables;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodType;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.RpcService;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-
-class RpcMethodInvokerWithoutInput extends RpcMethodInvoker {
-
- private static final MethodType INVOCATION_SIGNATURE = MethodType.methodType(ListenableFuture.class,
- RpcService.class);
- private final MethodHandle handle;
-
- RpcMethodInvokerWithoutInput(final MethodHandle methodHandle) {
- this.handle = methodHandle.asType(INVOCATION_SIGNATURE);
- }
-
- @Override
- @SuppressWarnings("checkstyle:illegalCatch")
- ListenableFuture<RpcResult<?>> invokeOn(final RpcService impl, final DataObject input) {
- try {
- return (ListenableFuture<RpcResult<?>>) handle.invokeExact(impl);
- } catch (Throwable e) {
- Throwables.throwIfUnchecked(e);
- throw new IllegalStateException(e);
- }
- }
-}
\ No newline at end of file
package org.opendaylight.mdsal.binding.dom.adapter.invoke;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import org.opendaylight.yangtools.yang.common.QName;
public class AbstractMappedRpcInvokerTest {
-
@Test
public void invokeRpcTest() throws Exception {
- final Method methodWithoutInput =
- TestRpcService.class.getDeclaredMethod("methodWithoutInput", RpcService.class);
final Method methodWithInput =
TestRpcService.class.getDeclaredMethod("methodWithInput", RpcService.class, DataObject.class);
methodWithInput.setAccessible(true);
- methodWithoutInput.setAccessible(true);
final RpcService rpcService = new TestRpcService();
final TestRpcInvokerImpl testRpcInvoker =
new TestRpcInvokerImpl(ImmutableMap.of(
- "(test)tstWithoutInput", methodWithoutInput,
"(test)tstWithInput", methodWithInput));
- assertTrue(testRpcInvoker.map.get("(test)tstWithInput") instanceof RpcMethodInvokerWithInput);
- assertTrue(testRpcInvoker.map.get("(test)tstWithoutInput") instanceof RpcMethodInvokerWithoutInput);
-
- final Crate crateWithoutInput =
- (Crate) testRpcInvoker.invokeRpc(rpcService, QName.create("test", "tstWithoutInput"), null).get();
- assertEquals(TestRpcService.methodWithoutInput(rpcService).get().getRpcService(),
- crateWithoutInput.getRpcService());
- assertFalse(crateWithoutInput.getDataObject().isPresent());
+ assertTrue(testRpcInvoker.map.get("(test)tstWithInput") instanceof RpcMethodInvoker);
final DataObject dataObject = mock(DataObject.class);
final Crate crateWithInput =
assertEquals(dataObject, crateWithInput.getDataObject().get());
}
- private class TestRpcInvokerImpl extends AbstractMappedRpcInvoker<String> {
-
+ private static class TestRpcInvokerImpl extends AbstractMappedRpcInvoker<String> {
TestRpcInvokerImpl(final Map<String, Method> map) {
super(map);
}
}
RpcService getRpcService() {
- return this.rpcService;
+ return rpcService;
}
Optional<DataObject> getDataObject() {
- return this.dataObject.get();
+ return dataObject.get();
}
}
static class TestRpcService implements RpcService {
- static ListenableFuture<Crate> methodWithoutInput(final RpcService testArgument) {
- return Futures.immediateFuture(new Crate(testArgument, null));
- }
-
static ListenableFuture<Crate> methodWithInput(final RpcService testArgument, final DataObject testArgument2) {
return Futures.immediateFuture(new Crate(testArgument, testArgument2));
}
package org.opendaylight.mdsal.binding.dom.adapter.invoke;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.RpcService;
-public class RpcMethodInvokerWithInputTest {
-
+public class RpcMethodInvokerTest {
private static final TestImplClassWithInput TEST_IMPL_CLASS = new TestImplClassWithInput();
@Test
public void invokeOnTest() throws Exception {
final MethodHandle methodHandle = MethodHandles.lookup().unreflect(
TestImplClassWithInput.class.getDeclaredMethod("testMethod", RpcService.class, DataObject.class));
- final RpcMethodInvokerWithInput rpcMethodInvokerWithInput = new RpcMethodInvokerWithInput(methodHandle);
+ final RpcMethodInvoker rpcMethodInvokerWithInput = new RpcMethodInvoker(methodHandle);
assertNotNull(rpcMethodInvokerWithInput.invokeOn(TEST_IMPL_CLASS, null));
}
- @Test(expected = InternalError.class)
+ @Test
public void invokeOnWithException() throws Exception {
final MethodHandle methodHandle = MethodHandles.lookup().unreflect(TestImplClassWithInput.class
.getDeclaredMethod("testMethodWithException", RpcService.class, DataObject.class));
- final RpcMethodInvokerWithInput rpcMethodInvokerWithInput = new RpcMethodInvokerWithInput(methodHandle);
- rpcMethodInvokerWithInput.invokeOn(TEST_IMPL_CLASS, null);
+ final RpcMethodInvoker rpcMethodInvokerWithInput = new RpcMethodInvoker(methodHandle);
+
+ assertThrows(InternalError.class, () -> rpcMethodInvokerWithInput.invokeOn(TEST_IMPL_CLASS, null));
}
- private static final class TestImplClassWithInput implements RpcService {
+ static final class TestImplClassWithInput implements RpcService {
static ListenableFuture<?> testMethod(final RpcService testArg, final DataObject data) {
return Futures.immediateFuture(null);
}
- static ListenableFuture<?> testMethodWithException(final RpcService testArg, final DataObject data)
- throws Exception {
+ static ListenableFuture<?> testMethodWithException(final RpcService testArg, final DataObject data) {
throw new InternalError();
}
}
+++ /dev/null
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.mdsal.binding.dom.adapter.invoke;
-
-import static org.junit.Assert.assertNotNull;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import org.junit.Test;
-import org.opendaylight.yangtools.yang.binding.RpcService;
-
-public class RpcMethodInvokerWithoutInputTest {
-
- private static final TestImplClassWithoutInput TEST_IMPL_CLASS = new TestImplClassWithoutInput();
-
- @Test
- public void invokeOnTest() throws Exception {
- final MethodHandle methodHandle = MethodHandles.lookup().unreflect(
- TestImplClassWithoutInput.class.getDeclaredMethod("testMethod", RpcService.class));
- final RpcMethodInvokerWithoutInput invokerWithoutInput = new RpcMethodInvokerWithoutInput(methodHandle);
- assertNotNull(invokerWithoutInput.invokeOn(TEST_IMPL_CLASS, null));
- }
-
- @Test(expected = InternalError.class)
- public void invokeOnWithException() throws Exception {
- final MethodHandle methodHandle = MethodHandles.lookup().unreflect(
- TestImplClassWithoutInput.class.getDeclaredMethod("testMethodWithException", RpcService.class));
- final RpcMethodInvokerWithoutInput invokerWithoutInput = new RpcMethodInvokerWithoutInput(methodHandle);
- invokerWithoutInput.invokeOn(TEST_IMPL_CLASS, null);
- }
-
- private static final class TestImplClassWithoutInput implements RpcService {
-
- @SuppressWarnings("unused")
- static ListenableFuture<?> testMethod(final RpcService testArgument) {
- return Futures.immediateFuture(null);
- }
-
- @SuppressWarnings("unused")
- static ListenableFuture<?> testMethodWithException(final RpcService testArgument) throws Exception {
- throw new InternalError();
- }
- }
-}
\ No newline at end of file