final var rpcs = createQNameToMethod(currentSerializer(), type);
return new BindingRpcAdapterRegistration<>(implementation, getDelegate().registerRpcImplementation(
- new LegacyDOMRpcImplementationAdapter<>(adapterContext(), type, rpcs, implementation),
+ new LegacyDOMRpcImplementationAdapter<>(adapterContext(), type, implementation, rpcs),
createDomRpcIdentifiers(rpcs.keySet(), rpcContextPaths)));
}
*/
package org.opendaylight.mdsal.binding.dom.adapter;
+import static com.google.common.base.Verify.verifyNotNull;
import static java.util.Objects.requireNonNull;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
import com.google.common.util.concurrent.ListenableFuture;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ExecutionException;
-import org.opendaylight.mdsal.binding.dom.adapter.invoke.RpcServiceInvoker;
+import org.opendaylight.mdsal.binding.dom.adapter.invoke.RpcMethodInvoker;
import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
import org.opendaylight.yangtools.yang.binding.RpcService;
@Deprecated(since = "11.0.0", forRemoval = true)
final class LegacyDOMRpcImplementationAdapter<T extends RpcService> extends AbstractDOMRpcImplementationAdapter {
- private static final Cache<Class<?>, RpcServiceInvoker> SERVICE_INVOKERS = CacheBuilder.newBuilder().weakKeys()
- .build();
+ private static final Cache<Class<?>, ImmutableMap<QName, RpcMethodInvoker>> CLASS_INVOKERS =
+ CacheBuilder.newBuilder().weakKeys().build();
- private final RpcServiceInvoker invoker;
+ private final ImmutableMap<QName, RpcMethodInvoker> invokers;
private final T delegate;
- LegacyDOMRpcImplementationAdapter(final AdapterContext adapterContext, final Class<T> type,
- final Map<QName, Method> localNameToMethod, final T delegate) {
+ LegacyDOMRpcImplementationAdapter(final AdapterContext adapterContext, final Class<T> type, final T delegate,
+ final Map<QName, Method> qnameToMethod) {
// FIXME: do not use BindingReflections here
super(adapterContext, YangConstants.operationInputQName(BindingReflections.getQNameModule(type)).intern());
+ this.delegate = requireNonNull(delegate);
try {
- invoker = SERVICE_INVOKERS.get(type, () -> RpcServiceInvoker.from(localNameToMethod));
+ invokers = CLASS_INVOKERS.get(type,
+ () -> ImmutableMap.copyOf(Maps.transformValues(qnameToMethod, RpcMethodInvoker::from)));
} catch (ExecutionException e) {
throw new IllegalArgumentException("Failed to create invokers for type " + type, e);
}
-
- this.delegate = requireNonNull(delegate);
}
@Override
ListenableFuture<RpcResult<?>> invokeRpc(final CurrentAdapterSerializer serializer, final DOMRpcIdentifier rpc,
final ContainerNode input) {
- final QName rpcType = rpc.getType();
- final var bindingInput = input != null ? deserialize(serializer, rpcType, input) : null;
- return invoker.invokeRpc(delegate, rpcType, bindingInput);
+ final var rpcType = rpc.getType();
+ return verifyNotNull(invokers.get(rpcType)).invokeOn(delegate, deserialize(serializer, rpc.getType(), input));
}
}
+++ /dev/null
-/*
- * Copyright (c) 2015 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 com.google.common.base.Preconditions.checkArgument;
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMap.Builder;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.lang.reflect.Method;
-import java.util.Map;
-import java.util.Map.Entry;
-import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.RpcService;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Deprecated(since = "11.0.0", forRemoval = true)
-abstract class AbstractMappedRpcInvoker<T> extends RpcServiceInvoker {
- private static final Logger LOG = LoggerFactory.getLogger(AbstractMappedRpcInvoker.class);
-
- @VisibleForTesting
- final Map<T, RpcMethodInvoker> map;
-
- protected AbstractMappedRpcInvoker(final Map<T, Method> map) {
- final Builder<T, RpcMethodInvoker> b = ImmutableMap.builder();
-
- for (Entry<T, Method> e : map.entrySet()) {
- if (BindingReflections.isRpcMethod(e.getValue())) {
- b.put(e.getKey(), RpcMethodInvoker.from(e.getValue()));
- } else {
- LOG.debug("Method {} is not an RPC method, ignoring it", e.getValue());
- }
- }
-
- this.map = b.build();
- }
-
- protected abstract T qnameToKey(QName qname);
-
- @Override
- public final ListenableFuture<RpcResult<?>> invokeRpc(final RpcService impl, final QName rpcName,
- final DataObject input) {
- requireNonNull(impl, "Implementation must be supplied");
-
- RpcMethodInvoker invoker = map.get(qnameToKey(rpcName));
- checkArgument(invoker != null, "Supplied RPC is not valid for implementation %s", impl);
- return invoker.invokeOn(impl, input);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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 java.util.Objects.requireNonNull;
-
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.QNameModule;
-
-@Deprecated(since = "11.0.0", forRemoval = true)
-final class LocalNameRpcServiceInvoker extends AbstractMappedRpcInvoker<String> {
- private final QNameModule module;
-
- private LocalNameRpcServiceInvoker(final QNameModule module, final Map<String, Method> map) {
- super(map);
- this.module = requireNonNull(module);
- }
-
- static RpcServiceInvoker instanceFor(final QNameModule module, final Map<QName, Method> qnameToMethod) {
- final Map<String, Method> map = new HashMap<>();
- for (Entry<QName, Method> e : qnameToMethod.entrySet()) {
- map.put(e.getKey().getLocalName(), e.getValue());
- }
-
- return new LocalNameRpcServiceInvoker(module, map);
- }
-
- @Override
- protected String qnameToKey(final QName qname) {
- if (module.equals(qname.getModule())) {
- return qname.getLocalName();
- } else {
- return null;
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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 java.lang.reflect.Method;
-import java.util.Map;
-import org.opendaylight.yangtools.yang.common.QName;
-
-@Deprecated(since = "11.0.0", forRemoval = true)
-final class QNameRpcServiceInvoker extends AbstractMappedRpcInvoker<QName> {
- private QNameRpcServiceInvoker(final Map<QName, Method> qnameToMethod) {
- super(qnameToMethod);
- }
-
- static RpcServiceInvoker instanceFor(final Map<QName, Method> qnameToMethod) {
- return new QNameRpcServiceInvoker(qnameToMethod);
- }
-
- @Override
- protected QName qnameToKey(final QName qname) {
- return qname;
- }
-}
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
+import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.RpcService;
import org.opendaylight.yangtools.yang.common.RpcResult;
@Deprecated(since = "11.0.0", forRemoval = true)
-final class RpcMethodInvoker {
+public final class RpcMethodInvoker {
private static final MethodType INVOCATION_SIGNATURE = MethodType.methodType(ListenableFuture.class,
RpcService.class, DataObject.class);
this.handle = handle.asType(INVOCATION_SIGNATURE);
}
- static RpcMethodInvoker from(final Method method) {
- final MethodHandle methodHandle;
+ public static @NonNull RpcMethodInvoker from(final Method method) {
try {
- methodHandle = MethodHandles.publicLookup().unreflect(method);
+ return new RpcMethodInvoker(MethodHandles.publicLookup().unreflect(method));
} catch (IllegalAccessException e) {
throw new IllegalStateException("Lookup on public method failed.", e);
}
-
- return new RpcMethodInvoker(methodHandle);
}
@SuppressWarnings("checkstyle:illegalCatch")
- ListenableFuture<RpcResult<?>> invokeOn(final RpcService impl, final DataObject input) {
+ public @NonNull ListenableFuture<RpcResult<?>> invokeOn(final RpcService impl, final DataObject input) {
try {
- return (ListenableFuture<RpcResult<?>>) handle.invokeExact(impl,input);
+ return (ListenableFuture<RpcResult<?>>) handle.invokeExact(impl, input);
} catch (Throwable e) {
Throwables.throwIfUnchecked(e);
throw new IllegalStateException(e);
+++ /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 static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import java.lang.reflect.Method;
-import java.util.Map;
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.RpcService;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Provides single method invocation of RPCs on supplied instance.
- *
- * <p>
- * RPC Service invoker provides common invocation interface for any subtype of {@link RpcService} via
- * {@link #invokeRpc(RpcService, QName, DataObject)} method.
- */
-@Deprecated(since = "11.0.0", forRemoval = true)
-public abstract class RpcServiceInvoker {
- private static final Logger LOG = LoggerFactory.getLogger(RpcServiceInvoker.class);
-
- /**
- * Creates an RPCServiceInvoker for specified QName-<Method mapping.
- *
- * @param qnameToMethod translation mapping, must not be null nor empty.
- * @return An {@link RpcServiceInvoker} instance.
- */
- public static RpcServiceInvoker from(final Map<QName, Method> qnameToMethod) {
- checkArgument(!qnameToMethod.isEmpty());
- QNameModule module = null;
-
- for (QName qname : qnameToMethod.keySet()) {
- if (module != null) {
- if (!module.equals(qname.getModule())) {
- LOG.debug("QNames from different modules {} and {}, falling back to QName map", module,
- qname.getModule());
- return QNameRpcServiceInvoker.instanceFor(qnameToMethod);
- }
- } else {
- module = qname.getModule();
- }
- }
-
- // All module are equal, which means we can use localName only
- return LocalNameRpcServiceInvoker.instanceFor(module, qnameToMethod);
- }
-
- /**
- * Invokes supplied RPC on provided implementation of RPC Service.
- *
- * @param impl Imlementation on which RPC should be invoked.
- * @param rpcName Name of RPC to be invoked.
- * @param input Input data for RPC.
- * @return Future which will complete once rpc procesing is finished.
- */
- public abstract ListenableFuture<RpcResult<?>> invokeRpc(@NonNull RpcService impl, @NonNull QName rpcName,
- @Nullable DataObject input);
-}
+++ /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;
-
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.mock;
-
-import java.util.Map;
-import org.junit.Test;
-import org.opendaylight.mdsal.binding.dom.codec.spi.BindingDOMCodecServices;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.bi.ba.rpcservice.rev140701.OpendaylightTestRpcServiceService;
-import org.opendaylight.yangtools.yang.common.QName;
-
-@Deprecated(since = "11.0.0", forRemoval = true)
-public class LegacyDOMRpcImplementationAdapterTest {
- @Test
- public void basicTest() throws Exception {
- final var codecServices = mock(BindingDOMCodecServices.class);
- final var testMethod = getClass().getDeclaredMethod("testMethod");
- final var rpcType = QName.create("tst", "test");
- final var adapter = new LegacyDOMRpcImplementationAdapter<>(new ConstantAdapterContext(codecServices),
- OpendaylightTestRpcServiceService.class, Map.of(rpcType, testMethod),
- mock(OpendaylightTestRpcServiceService.class));
- assertNotNull(adapter);
- }
-
- private void testMethod() {
- //NOOP
- }
-}
\ No newline at end of file
+++ /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.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.lang.reflect.Method;
-import java.util.Map;
-import java.util.Optional;
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
-import org.junit.Test;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.RpcService;
-import org.opendaylight.yangtools.yang.common.QName;
-
-@Deprecated(since = "11.0.0", forRemoval = true)
-public class AbstractMappedRpcInvokerTest {
- @Test
- public void invokeRpcTest() throws Exception {
- final Method methodWithInput =
- TestRpcService.class.getDeclaredMethod("methodWithInput", RpcService.class, DataObject.class);
-
- methodWithInput.setAccessible(true);
-
- final RpcService rpcService = new TestRpcService();
-
- final TestRpcInvokerImpl testRpcInvoker =
- new TestRpcInvokerImpl(ImmutableMap.of(
- "(test)tstWithInput", methodWithInput));
-
- assertTrue(testRpcInvoker.map.get("(test)tstWithInput") instanceof RpcMethodInvoker);
-
- final DataObject dataObject = mock(DataObject.class);
- final Crate crateWithInput =
- (Crate) testRpcInvoker.invokeRpc(rpcService, QName.create("test", "tstWithInput"), dataObject).get();
- assertEquals(TestRpcService.methodWithInput(rpcService, dataObject).get().getRpcService(),
- crateWithInput.getRpcService());
- assertTrue(crateWithInput.getDataObject().isPresent());
- assertEquals(dataObject, crateWithInput.getDataObject().get());
- }
-
- private static class TestRpcInvokerImpl extends AbstractMappedRpcInvoker<String> {
- TestRpcInvokerImpl(final Map<String, Method> map) {
- super(map);
- }
-
- @Override
- protected String qnameToKey(final QName qname) {
- return qname.toString();
- }
- }
-
- static class Crate {
- private final RpcService rpcService;
- private final ThreadLocal<Optional<DataObject>> dataObject;
-
- Crate(final @NonNull RpcService rpcService, final @Nullable DataObject dataObject) {
- this.rpcService = rpcService;
- this.dataObject =
- ThreadLocal.withInitial(() -> dataObject == null ? Optional.empty() : Optional.of(dataObject));
- }
-
- RpcService getRpcService() {
- return rpcService;
- }
-
- Optional<DataObject> getDataObject() {
- return dataObject.get();
- }
- }
-
- static class TestRpcService implements RpcService {
- static ListenableFuture<Crate> methodWithInput(final RpcService testArgument, final DataObject testArgument2) {
- return Futures.immediateFuture(new Crate(testArgument, testArgument2));
- }
- }
-}
-
+++ /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 static org.mockito.Mockito.mock;
-
-import com.google.common.collect.ImmutableMap;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.yangtools.yang.binding.RpcService;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.common.Revision;
-import org.opendaylight.yangtools.yang.common.XMLNamespace;
-
-@Deprecated(since = "11.0.0", forRemoval = true)
-public class LocalNameRpcServiceInvokerTest {
-
- private static RpcServiceInvoker rpcServiceInvoker;
- private static final QNameModule Q_NAME_MODULE = QNameModule.create(XMLNamespace.of("testURI"),
- Revision.of("2017-10-26"));
- private static final RpcService RPC_SERVICE = mock(RpcService.class);
-
- @BeforeClass
- public static void setUp() throws Exception {
- rpcServiceInvoker = LocalNameRpcServiceInvoker.instanceFor(
- Q_NAME_MODULE, ImmutableMap.of(QName.create(Q_NAME_MODULE, "test"),
- Object.class.getDeclaredMethod("hashCode")));
-
- assertNotNull(rpcServiceInvoker);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void qnameToKeyTest() throws Exception {
- rpcServiceInvoker.invokeRpc(RPC_SERVICE, QName.create(Q_NAME_MODULE, "test"), null);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void qnameToKeyWithNullTest() throws Exception {
- rpcServiceInvoker.invokeRpc(RPC_SERVICE, QName.create("", "test"), null);
- }
-}
+++ /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 static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-
-import com.google.common.collect.ImmutableMap;
-import org.junit.Test;
-import org.opendaylight.yangtools.yang.binding.RpcService;
-import org.opendaylight.yangtools.yang.common.QName;
-
-@Deprecated(since = "11.0.0", forRemoval = true)
-public class QNameRpcServiceInvokerTest {
- @Test
- public void instanceForTest() throws Exception {
- assertNotNull(QNameRpcServiceInvoker.instanceFor(ImmutableMap.of()));
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void qnameToKeyTest() throws Exception {
- final RpcService rpcService = mock(RpcService.class);
- QNameRpcServiceInvoker.instanceFor(ImmutableMap.of()).invokeRpc(rpcService, QName.create("", "test"), null);
- fail("Expected exception: constructed with empty map");
- }
-}
\ No newline at end of file
+++ /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 java.lang.reflect.Method;
-import java.util.Map;
-import org.junit.Test;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.common.Revision;
-import org.opendaylight.yangtools.yang.common.XMLNamespace;
-
-@Deprecated(since = "11.0.0", forRemoval = true)
-public class RpcServiceInvokerTest {
- @Test
- public void fromTest() throws Exception {
- final Method method = this.getClass().getDeclaredMethod("testMethod");
- method.setAccessible(true);
- assertNotNull(RpcServiceInvoker.from(Map.of(
- QName.create(QNameModule.create(XMLNamespace.of("testURI"), Revision.of("2017-10-26")),"test"), method,
- QName.create(QNameModule.create(XMLNamespace.of("testURI2"), Revision.of("2017-10-26")),"test"), method)));
- assertNotNull(RpcServiceInvoker.from(Map.of(
- QName.create(QNameModule.create(XMLNamespace.of("testURI"), Revision.of("2017-10-26")), "test"), method)));
- }
-
- private void testMethod() {
- // NOOP
- }
-}