CheckedFuture is deprecated.
This breaks the controller - corresppnding patch is
https://git.opendaylight.org/gerrit/#/c/74366/
Change-Id: I08f396b872699512171a24732d9473ca96b89778
Signed-off-by: Tom Pantelis <tompantelis@gmail.com>
import com.google.common.base.Preconditions;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
-import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.ListenableFuture;
import java.lang.reflect.Method;
import java.util.HashMap;
import org.opendaylight.mdsal.binding.dom.adapter.invoke.RpcServiceInvoker;
import org.opendaylight.mdsal.binding.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
-import org.opendaylight.mdsal.dom.api.DOMRpcException;
import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
import org.opendaylight.mdsal.dom.api.DOMRpcResult;
@Nonnull
@Override
- public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(@Nonnull final DOMRpcIdentifier rpc,
- final NormalizedNode<?, ?> input) {
+ public FluentFuture<DOMRpcResult> invokeRpc(@Nonnull final DOMRpcIdentifier rpc, final NormalizedNode<?, ?> input) {
final SchemaPath schemaPath = rpc.getType();
final DataObject bindingInput = input != null ? deserialize(rpc.getType(), input) : null;
return invoker.invokeRpc(delegate, schemaPath.getLastComponent(), input);
}
- private CheckedFuture<DOMRpcResult, DOMRpcException> transformResult(
- final ListenableFuture<RpcResult<?>> bindingResult) {
+ private FluentFuture<DOMRpcResult> transformResult(final ListenableFuture<RpcResult<?>> bindingResult) {
return LazyDOMRpcResultFuture.create(codec, bindingResult);
}
}
package org.opendaylight.mdsal.binding.dom.adapter;
import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.AbstractFuture;
+import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import org.opendaylight.mdsal.binding.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
import org.opendaylight.mdsal.dom.api.DOMRpcException;
import org.opendaylight.mdsal.dom.api.DOMRpcResult;
+import org.opendaylight.mdsal.dom.api.DefaultDOMRpcException;
import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
+import org.opendaylight.yangtools.util.concurrent.ExceptionMapper;
import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-final class LazyDOMRpcResultFuture implements CheckedFuture<DOMRpcResult, DOMRpcException>, BindingRpcFutureAware {
+final class LazyDOMRpcResultFuture extends AbstractFuture<DOMRpcResult> implements BindingRpcFutureAware {
+ private static final ExceptionMapper<DOMRpcException> DOM_RPC_EX_MAPPER =
+ new ExceptionMapper<DOMRpcException>("rpc", DOMRpcException.class) {
+ @Override
+ protected DOMRpcException newWithCause(String message, Throwable cause) {
+ return cause instanceof DOMRpcException ? (DOMRpcException)cause
+ : new DefaultDOMRpcException("RPC failed", cause);
+ }
+ };
private final ListenableFuture<RpcResult<?>> bindingFuture;
private final BindingNormalizedNodeCodecRegistry codec;
this.codec = Preconditions.checkNotNull(codec, "codec");
}
- static CheckedFuture<DOMRpcResult, DOMRpcException> create(final BindingNormalizedNodeCodecRegistry codec,
+ static FluentFuture<DOMRpcResult> create(final BindingNormalizedNodeCodecRegistry codec,
final ListenableFuture<RpcResult<?>> bindingResult) {
return new LazyDOMRpcResultFuture(bindingResult, codec);
}
if (result != null) {
return result;
}
- return transformIfNecessary(bindingFuture.get());
+
+ try {
+ return transformIfNecessary(bindingFuture.get());
+ } catch (ExecutionException e) {
+ throw new ExecutionException(e.getMessage(), DOM_RPC_EX_MAPPER.apply(e));
+ }
}
@Override
if (result != null) {
return result;
}
- return transformIfNecessary(bindingFuture.get(timeout, unit));
- }
-
- @Override
- public DOMRpcResult checkedGet() throws DOMRpcException {
- try {
- return get();
- } catch (InterruptedException | ExecutionException e) {
- // FIXME: Add exception mapping
- throw new RuntimeException(e);
- }
- }
- @Override
- public DOMRpcResult checkedGet(final long timeout, final TimeUnit unit) throws TimeoutException, DOMRpcException {
try {
- return get(timeout, unit);
- } catch (InterruptedException | ExecutionException e) {
- // FIXME: Add exception mapping
- throw new RuntimeException(e);
+ return transformIfNecessary(bindingFuture.get(timeout, unit));
+ } catch (ExecutionException e) {
+ throw new ExecutionException(e.getMessage(), DOM_RPC_EX_MAPPER.apply(e));
}
}
}
return new DefaultDOMRpcResult(input.getErrors());
}
-
}
--- /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.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multimap;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.mdsal.binding.api.RpcConsumerRegistry;
+import org.opendaylight.mdsal.binding.api.RpcProviderService;
+import org.opendaylight.mdsal.binding.dom.adapter.test.util.BindingBrokerTestFactory;
+import org.opendaylight.mdsal.binding.dom.adapter.test.util.BindingTestContext;
+import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
+import org.opendaylight.mdsal.dom.api.DOMRpcProviderService;
+import org.opendaylight.mdsal.dom.api.DOMRpcResult;
+import org.opendaylight.mdsal.dom.api.DOMRpcService;
+import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.md.sal.knock.knock.rev180723.KnockKnockInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.md.sal.knock.knock.rev180723.KnockKnockInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.md.sal.knock.knock.rev180723.KnockKnockOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.md.sal.knock.knock.rev180723.KnockKnockOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.md.sal.knock.knock.rev180723.OpendaylightKnockKnockRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.Top;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListKey;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.util.concurrent.FluentFutures;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+public class BindingDOMRpcIntegrationTest {
+ private static final InstanceIdentifier<TopLevelList> BA_NODE_ID = InstanceIdentifier.create(Top.class)
+ .child(TopLevelList.class, new TopLevelListKey("a"));
+
+ private static final QName KNOCK_KNOCK_QNAME = QName.create(KnockKnockOutput.QNAME, "knock-knock");
+ private static final SchemaPath KNOCK_KNOCK_PATH = SchemaPath.create(true, KNOCK_KNOCK_QNAME);
+
+ private RpcProviderService baRpcProviderService;
+ private RpcConsumerRegistry baRpcConsumerService;
+ private DOMRpcProviderService biRpcProviderService;
+ private BindingTestContext testContext;
+ private DOMRpcService biRpcService;
+ private final OpendaylightKnockKnockRpcServiceImpl knockRpcImpl = new OpendaylightKnockKnockRpcServiceImpl();
+
+ @Before
+ public void setup() throws Exception {
+ BindingBrokerTestFactory testFactory = new BindingBrokerTestFactory();
+ testFactory.setExecutor(MoreExecutors.newDirectExecutorService());
+ testContext = testFactory.getTestContext();
+
+ testContext.setSchemaModuleInfos(ImmutableSet.of(
+ BindingReflections.getModuleInfo(OpendaylightKnockKnockRpcService.class),
+ BindingReflections.getModuleInfo(Top.class)));
+ testContext.start();
+ baRpcProviderService = testContext.getBindingRpcProviderRegistry();
+ baRpcConsumerService = testContext.getBindingRpcConsumerRegistry();
+ biRpcProviderService = testContext.getDomRpcRegistry();
+ biRpcService = testContext.getDomRpcInvoker();
+ }
+
+ @Test
+ public void testBindingRegistrationWithDOMInvocation()
+ throws InterruptedException, ExecutionException, TimeoutException {
+ knockRpcImpl.registerTo(baRpcProviderService, BA_NODE_ID).setKnockKnockResult(knockResult(true, "open"));
+
+ final OpendaylightKnockKnockRpcService baKnockService =
+ baRpcConsumerService.getRpcService(OpendaylightKnockKnockRpcService.class);
+ assertNotSame(knockRpcImpl, baKnockService);
+
+ KnockKnockInput baKnockKnockInput = knockKnock(BA_NODE_ID).setQuestion("who's there?").build();
+
+ ContainerNode biKnockKnockInput = toDOMKnockKnockInput(baKnockKnockInput);
+ DOMRpcResult domResult = biRpcService.invokeRpc(KNOCK_KNOCK_PATH, biKnockKnockInput).get(5, TimeUnit.SECONDS);
+ assertNotNull(domResult);
+ assertNotNull(domResult.getResult());
+ assertTrue("Binding KnockKnock service was not invoked",
+ knockRpcImpl.getReceivedKnocks().containsKey(BA_NODE_ID));
+ assertEquals(baKnockKnockInput, knockRpcImpl.getReceivedKnocks().get(BA_NODE_ID).iterator().next());
+ }
+
+ @Test
+ public void testDOMRegistrationWithBindingInvocation()
+ throws InterruptedException, ExecutionException, TimeoutException {
+ KnockKnockOutput baKnockKnockOutput = new KnockKnockOutputBuilder().setAnswer("open").build();
+
+ biRpcProviderService.registerRpcImplementation((rpc, input) ->
+ FluentFutures.immediateFluentFuture(new DefaultDOMRpcResult(testContext.getCodec()
+ .getCodecFactory().toNormalizedNodeRpcData(baKnockKnockOutput))),
+ DOMRpcIdentifier.create(KNOCK_KNOCK_PATH, testContext.getCodec().toNormalized(BA_NODE_ID)));
+
+ final OpendaylightKnockKnockRpcService baKnockService =
+ baRpcConsumerService.getRpcService(OpendaylightKnockKnockRpcService.class);
+ Future<RpcResult<KnockKnockOutput>> baResult = baKnockService.knockKnock(knockKnock(BA_NODE_ID)
+ .setQuestion("Who's there?").build());
+ assertNotNull(baResult);
+ assertEquals(baKnockKnockOutput, baResult.get(5, TimeUnit.SECONDS).getResult());
+ }
+
+ @Test
+ public void testBindingRpcShortcut() throws InterruptedException, ExecutionException, TimeoutException {
+ final ListenableFuture<RpcResult<KnockKnockOutput>> baKnockResult = knockResult(true, "open");
+ knockRpcImpl.registerTo(baRpcProviderService, BA_NODE_ID).setKnockKnockResult(baKnockResult);
+
+ final OpendaylightKnockKnockRpcService baKnockService =
+ baRpcConsumerService.getRpcService(OpendaylightKnockKnockRpcService.class);
+
+ KnockKnockInput baKnockKnockInput = knockKnock(BA_NODE_ID).setQuestion("who's there?").build();
+ ListenableFuture<RpcResult<KnockKnockOutput>> future = baKnockService.knockKnock(baKnockKnockInput);
+
+ final RpcResult<KnockKnockOutput> rpcResult = future.get(5, TimeUnit.SECONDS);
+
+ assertEquals(baKnockResult.get().getResult().getClass(), rpcResult.getResult().getClass());
+ assertSame(baKnockResult.get().getResult(), rpcResult.getResult());
+ assertSame(baKnockKnockInput, knockRpcImpl.getReceivedKnocks().get(BA_NODE_ID).iterator().next());
+ }
+
+ private static ListenableFuture<RpcResult<KnockKnockOutput>> knockResult(final boolean success,
+ final String answer) {
+ KnockKnockOutput output = new KnockKnockOutputBuilder().setAnswer(answer).build();
+ RpcResult<KnockKnockOutput> result = RpcResultBuilder.<KnockKnockOutput>status(success).withResult(output)
+ .build();
+ return Futures.immediateFuture(result);
+ }
+
+ private static KnockKnockInputBuilder knockKnock(final InstanceIdentifier<TopLevelList> listId) {
+ KnockKnockInputBuilder builder = new KnockKnockInputBuilder();
+ builder.setKnockerId(listId);
+ return builder;
+ }
+
+ private ContainerNode toDOMKnockKnockInput(final KnockKnockInput from) {
+ return testContext.getCodec().getCodecFactory().toNormalizedNodeRpcData(from);
+ }
+
+ private static class OpendaylightKnockKnockRpcServiceImpl implements OpendaylightKnockKnockRpcService {
+ private ListenableFuture<RpcResult<KnockKnockOutput>> knockKnockResult;
+ private final Multimap<InstanceIdentifier<?>, KnockKnockInput> receivedKnocks = HashMultimap.create();
+ private ObjectRegistration<OpendaylightKnockKnockRpcServiceImpl> registration;
+
+ OpendaylightKnockKnockRpcServiceImpl setKnockKnockResult(
+ final ListenableFuture<RpcResult<KnockKnockOutput>> kkOutput) {
+ this.knockKnockResult = kkOutput;
+ return this;
+ }
+
+ Multimap<InstanceIdentifier<?>, KnockKnockInput> getReceivedKnocks() {
+ return receivedKnocks;
+ }
+
+ OpendaylightKnockKnockRpcServiceImpl registerTo(final RpcProviderService registry,
+ InstanceIdentifier<?>... paths) {
+ registration = registry.registerRpcImplementation(OpendaylightKnockKnockRpcService.class, this,
+ ImmutableSet.copyOf(paths));
+ assertNotNull(registration);
+ return this;
+ }
+
+ @Override
+ public ListenableFuture<RpcResult<KnockKnockOutput>> knockKnock(KnockKnockInput input) {
+ receivedKnocks.put(input.getKnockerId(), input);
+ return knockKnockResult;
+ }
+ }
+}
+++ /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 com.google.common.collect.ImmutableSet;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.concurrent.Executors;
-import org.junit.Test;
-import org.opendaylight.mdsal.binding.dom.adapter.test.util.BindingBrokerTestFactory;
-import org.opendaylight.mdsal.binding.dom.adapter.test.util.BindingTestContext;
-import org.opendaylight.mdsal.dom.api.DOMRpcProviderService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.bi.ba.rpcservice.rev140701.OpendaylightTestRpcServiceService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.bi.ba.rpcservice.rev140701.RockTheHouseInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.bi.ba.rpcservice.rev140701.RockTheHouseOutput;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-
-public class BindingDOMRpcProviderServiceAdapterTest {
-
- @Test
- public void basicTest() throws Exception {
- final DOMRpcProviderService providerService = mock(DOMRpcProviderService.class);
- final BindingBrokerTestFactory testFactory = new BindingBrokerTestFactory();
- testFactory.setExecutor(Executors.newCachedThreadPool());
-
- final BindingTestContext testContext = testFactory.getTestContext();
- testContext.start();
-
- final BindingDOMRpcProviderServiceAdapter adapter =
- new BindingDOMRpcProviderServiceAdapter(providerService, testContext.getCodec());
-
- assertNotNull(adapter.registerRpcImplementation(OpendaylightTestRpcServiceService.class, new TestImpl()));
- assertNotNull(adapter.registerRpcImplementation(OpendaylightTestRpcServiceService.class, new TestImpl(),
- ImmutableSet.of()));
- }
-
- private class TestImpl implements OpendaylightTestRpcServiceService {
-
- @Override
- public ListenableFuture<RpcResult<RockTheHouseOutput>> rockTheHouse(final RockTheHouseInput input) {
- return null;
- }
- }
-}
\ No newline at end of file
verify(future).addListener(any(), any());
assertTrue(lazyDOMRpcResultFuture.isCancelled() && lazyDOMRpcResultFuture.isDone());
- assertEquals(lazyDOMRpcResultFuture.checkedGet(), lazyDOMRpcResultFuture.get(1, TimeUnit.SECONDS));
+ assertEquals(lazyDOMRpcResultFuture.get(), lazyDOMRpcResultFuture.get(1, TimeUnit.SECONDS));
final Field result = LazyDOMRpcResultFuture.class.getDeclaredField("result");
result.setAccessible(true);
result.set(lazyDOMRpcResultFuture, null);
- assertEquals(lazyDOMRpcResultFuture.checkedGet(1, TimeUnit.SECONDS), lazyDOMRpcResultFuture.get());
+ assertEquals(lazyDOMRpcResultFuture.get(1, TimeUnit.SECONDS), lazyDOMRpcResultFuture.get());
result.set(lazyDOMRpcResultFuture, null);
doReturn(new Object()).when(domRpcResult).getResult();
public void checkedGetWithException() throws Throwable {
doThrow(InterruptedException.class).when(future).get();
try {
- lazyDOMRpcResultFuture.checkedGet();
+ lazyDOMRpcResultFuture.get();
} catch (RuntimeException e) {
throw e.getCause();
}
public void checkedGetWithException2() throws Throwable {
doThrow(InterruptedException.class).when(future).get(1, TimeUnit.SECONDS);
try {
- lazyDOMRpcResultFuture.checkedGet(1, TimeUnit.SECONDS);
+ lazyDOMRpcResultFuture.get(1, TimeUnit.SECONDS);
} catch (RuntimeException e) {
throw e.getCause();
}
}
-}
\ No newline at end of file
+}
import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
+import java.util.Set;
import javassist.ClassPool;
import org.opendaylight.mdsal.binding.api.DataBroker;
import org.opendaylight.mdsal.binding.api.MountPointService;
import org.opendaylight.mdsal.binding.api.NotificationPublishService;
import org.opendaylight.mdsal.binding.api.NotificationService;
import org.opendaylight.mdsal.binding.api.RpcConsumerRegistry;
+import org.opendaylight.mdsal.binding.api.RpcProviderService;
import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMDataBrokerAdapter;
import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMMountPointServiceAdapter;
import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMNotificationPublishServiceAdapter;
private DOMNotificationService domListenService;
-
+ private Set<YangModuleInfo> schemaModuleInfos;
public DOMDataBroker getDomAsyncDataBroker() {
return newDOMDataBroker;
mockSchemaService.registerSchemaContextListener(codec);
}
- private void updateYangSchema(final ImmutableSet<YangModuleInfo> moduleInfos) {
+ private void updateYangSchema(final Set<YangModuleInfo> moduleInfos) {
mockSchemaService.changeSchema(getContext(moduleInfos));
}
- private static SchemaContext getContext(final ImmutableSet<YangModuleInfo> moduleInfos) {
+ private static SchemaContext getContext(final Set<YangModuleInfo> moduleInfos) {
final ModuleInfoBackedContext ctx = ModuleInfoBackedContext.create();
ctx.addModuleInfos(moduleInfos);
return ctx.tryToCreateSchemaContext().get();
startBindingBroker();
startForwarding();
- if (startWithSchema) {
+
+ if (schemaModuleInfos != null) {
+ updateYangSchema(schemaModuleInfos);
+ } else if (this.startWithSchema) {
loadYangSchemaFromClasspath();
}
}
return domRouter.getRpcService();
}
+ public RpcProviderService getBindingRpcProviderRegistry() {
+ return baProviderRpc;
+ }
+
+ public RpcConsumerRegistry getBindingRpcConsumerRegistry() {
+ return baConsumerRpc;
+ }
+
@Override
public void close() throws Exception {
public DataBroker getDataBroker() {
return dataBroker;
}
+
+ public void setSchemaModuleInfos(Set<YangModuleInfo> moduleInfos) {
+ this.schemaModuleInfos = moduleInfos;
+ }
}
--- /dev/null
+module opendaylight-knock-knock-rpc {
+ namespace "urn:opendaylight:params:xml:ns:yang:md:sal:knock-knock";
+ prefix knock-knock;
+
+ import yang-ext {prefix ext;}
+ import opendaylight-test-routed-rpc {prefix routed;}
+
+ revision 2018-07-23 {
+ }
+
+ rpc knock-knock {
+ input {
+ leaf knocker-id {
+ ext:context-reference routed:test-context;
+ type instance-identifier;
+ }
+
+ leaf question {
+ type string;
+ }
+ }
+
+ output {
+ leaf answer {
+ type string;
+ }
+ }
+ }
+}
type string;
}
}
-
- rpc knock-knock {
- input {
- leaf knocker-id {
- ext:context-reference routed:test-context;
- type instance-identifier;
- }
-
- leaf question {
- type string;
- }
- }
-
- output {
- leaf answer {
- type string;
- }
- }
- }
}
import com.google.common.base.Preconditions;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.JdkFutureAdapters;
import com.google.common.util.concurrent.ListenableFuture;
import java.lang.reflect.Method;
import org.opendaylight.mdsal.binding.javav2.runtime.reflection.BindingReflections;
import org.opendaylight.mdsal.binding.javav2.spec.base.Operation;
import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
-import org.opendaylight.mdsal.dom.api.DOMRpcException;
import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
import org.opendaylight.mdsal.dom.api.DOMRpcResult;
-import org.opendaylight.yangtools.util.concurrent.ExceptionMapper;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
@SuppressWarnings("deprecation")
@Nonnull
@Override
- public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(@Nonnull final DOMRpcIdentifier rpc,
+ public FluentFuture<DOMRpcResult> invokeRpc(@Nonnull final DOMRpcIdentifier rpc,
@Nullable final NormalizedNode<?, ?> input) {
final SchemaPath schemaPath = rpc.getType();
final TreeNode bindingInput = input != null ? deserialize(rpc.getType(), input) : null;
final ListenableFuture<RpcResult<?>> bindingResult = invoke(schemaPath, bindingInput);
- return Futures.makeChecked(transformResult(bindingResult),
- new ExceptionMapper<DOMRpcException>("invokeRPc", DOMRpcException.class) {
-
- @Override
- protected DOMRpcException newWithCause(final String message, final Throwable cause) {
- return new DOMRpcInvokeException(message, cause);
- }
- });
- }
-
- private class DOMRpcInvokeException extends DOMRpcException {
-
- private static final long serialVersionUID = 1L;
-
- protected DOMRpcInvokeException(final String message, final Throwable cause) {
- super(message, cause);
- }
+ return transformResult(bindingResult);
}
@Override
return JdkFutureAdapters.listenInPoolThread(invoker.invoke(delegate, schemaPath.getLastComponent(), input));
}
- private ListenableFuture<DOMRpcResult>
- transformResult(final ListenableFuture<RpcResult<?>> bindingResult) {
+ private FluentFuture<DOMRpcResult> transformResult(final ListenableFuture<RpcResult<?>> bindingResult) {
return LazyDOMOperationResultFuture.create(codec, bindingResult);
}
}
import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.AbstractFuture;
+import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import javax.annotation.Nonnull;
import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.dom.api.DOMRpcException;
import org.opendaylight.mdsal.dom.api.DOMRpcResult;
+import org.opendaylight.mdsal.dom.api.DefaultDOMRpcException;
import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
+import org.opendaylight.yangtools.util.concurrent.ExceptionMapper;
import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
* DOM operation result from Binding.
*/
@Beta
-final class LazyDOMOperationResultFuture implements ListenableFuture<DOMRpcResult> {
+final class LazyDOMOperationResultFuture extends AbstractFuture<DOMRpcResult> {
+ private static final ExceptionMapper<DOMRpcException> DOM_RPC_EX_MAPPER =
+ new ExceptionMapper<DOMRpcException>("rpc", DOMRpcException.class) {
+ @Override
+ protected DOMRpcException newWithCause(String message, Throwable cause) {
+ return cause instanceof DOMRpcException ? (DOMRpcException)cause
+ : new DefaultDOMRpcException("RPC failed", cause);
+ }
+ };
private final ListenableFuture<RpcResult<?>> bindingFuture;
private final BindingNormalizedNodeCodecRegistry codec;
this.codec = Preconditions.checkNotNull(codec, "codec");
}
- static ListenableFuture<DOMRpcResult> create(final BindingNormalizedNodeCodecRegistry codec,
+ static FluentFuture<DOMRpcResult> create(final BindingNormalizedNodeCodecRegistry codec,
final ListenableFuture<RpcResult<?>> bindingResult) {
return new LazyDOMOperationResultFuture(bindingResult, codec);
}
if (result != null) {
return result;
}
- return transformIfNecessary(bindingFuture.get());
+
+ try {
+ return transformIfNecessary(bindingFuture.get());
+ } catch (ExecutionException e) {
+ throw new ExecutionException(e.getMessage(), DOM_RPC_EX_MAPPER.apply(e));
+ }
}
@Override
if (result != null) {
return result;
}
- return transformIfNecessary(bindingFuture.get(timeout, unit));
+
+ try {
+ return transformIfNecessary(bindingFuture.get(timeout, unit));
+ } catch (ExecutionException e) {
+ throw new ExecutionException(e.getMessage(), DOM_RPC_EX_MAPPER.apply(e));
+ }
}
@Override
return new DefaultDOMRpcResult(input.getErrors());
}
-}
\ No newline at end of file
+}
*/
package org.opendaylight.mdsal.dom.api;
-import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
*
* @param rpc RPC identifier which was invoked
* @param input Input arguments, null if the RPC does not take any.
- * @return A {@link CheckedFuture} which will return either a result structure,
+ * @return A {@link FluentFuture} which will return either a result structure,
* or report a subclass of {@link DOMRpcException} reporting a transport
* error.
*/
- @Nonnull CheckedFuture<DOMRpcResult, DOMRpcException>
- invokeRpc(@Nonnull DOMRpcIdentifier rpc, @Nullable NormalizedNode<?, ?> input);
+ @Nonnull FluentFuture<DOMRpcResult> invokeRpc(@Nonnull DOMRpcIdentifier rpc, @Nullable NormalizedNode<?, ?> input);
/**
* Return the relative invocation cost of this implementation. Default implementation return 0.
*/
package org.opendaylight.mdsal.dom.api;
-import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
*
* @param type SchemaPath of the RPC to be invoked
* @param input Input arguments, null if the RPC does not take any.
- * @return A {@link CheckedFuture} which will return either a result structure,
+ * @return A {@link FluentFuture} which will return either a result structure,
* or report a subclass of {@link DOMRpcException} reporting a transport
* error.
*/
- @Nonnull CheckedFuture<DOMRpcResult, DOMRpcException>
- invokeRpc(@Nonnull SchemaPath type, @Nullable NormalizedNode<?, ?> input);
+ @Nonnull FluentFuture<DOMRpcResult> invokeRpc(@Nonnull SchemaPath type, @Nullable NormalizedNode<?, ?> input);
/**
* Register a {@link DOMRpcAvailabilityListener} with this service to receive notifications
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.Maps;
-import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.opendaylight.mdsal.dom.api.DOMRpcAvailabilityListener;
-import org.opendaylight.mdsal.dom.api.DOMRpcException;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
import org.opendaylight.mdsal.dom.api.DOMRpcResult;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
return v.isEmpty() ? null : newInstance(v);
}
- protected abstract CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(NormalizedNode<?, ?> input);
+ protected abstract FluentFuture<DOMRpcResult> invokeRpc(NormalizedNode<?, ?> input);
protected abstract AbstractDOMRpcRoutingTableEntry newInstance(
Map<YangInstanceIdentifier, List<DOMRpcImplementation>> impls);
import com.google.common.collect.MapDifference.ValueDifference;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ThreadFactory;
import javax.annotation.concurrent.GuardedBy;
import org.opendaylight.mdsal.dom.api.DOMRpcAvailabilityListener;
-import org.opendaylight.mdsal.dom.api.DOMRpcException;
import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException;
import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
import org.opendaylight.yangtools.concepts.AbstractRegistration;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.util.concurrent.FluentFutures;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
private final class RpcServiceFacade implements DOMRpcService {
@Override
- public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(final SchemaPath type,
- final NormalizedNode<?, ?> input) {
+ public FluentFuture<DOMRpcResult> invokeRpc(final SchemaPath type, final NormalizedNode<?, ?> input) {
final AbstractDOMRpcRoutingTableEntry entry = routingTable.getEntry(type);
if (entry == null) {
- return Futures.immediateFailedCheckedFuture(
+ return FluentFutures.immediateFailedFluentFuture(
new DOMRpcImplementationNotAvailableException("No implementation of RPC %s available", type));
}
package org.opendaylight.mdsal.dom.broker;
import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import java.util.List;
import java.util.Map;
-import org.opendaylight.mdsal.dom.api.DOMRpcException;
import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
import org.opendaylight.mdsal.dom.api.DOMRpcResult;
}
@Override
- protected CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(final NormalizedNode<?, ?> input) {
+ protected FluentFuture<DOMRpcResult> invokeRpc(final NormalizedNode<?, ?> input) {
return getImplementations(YangInstanceIdentifier.EMPTY).get(0).invokeRpc(rpcId, input);
}
List<DOMRpcImplementation>> impls) {
return new GlobalDOMRpcRoutingTableEntry(rpcId, impls);
}
-}
\ No newline at end of file
+}
package org.opendaylight.mdsal.dom.broker;
import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.FluentFuture;
import java.util.List;
import java.util.Map;
import java.util.Optional;
-import org.opendaylight.mdsal.dom.api.DOMRpcException;
import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException;
import org.opendaylight.mdsal.dom.api.DOMRpcResult;
+import org.opendaylight.yangtools.util.concurrent.FluentFutures;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
}
@Override
- protected CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(final NormalizedNode<?, ?> input) {
+ protected FluentFuture<DOMRpcResult> invokeRpc(final NormalizedNode<?, ?> input) {
final Optional<NormalizedNode<?, ?>> maybeKey = NormalizedNodes.findNode(input, keyId);
// Routing key is present, attempt to deliver as a routed RPC
return impls.get(0).invokeRpc(globalRpcId, input);
}
- return Futures.<DOMRpcResult, DOMRpcException>immediateFailedCheckedFuture(
+ return FluentFutures.immediateFailedFluentFuture(
new DOMRpcImplementationNotAvailableException("No implementation of RPC %s available", getSchemaPath()));
}
*/
package org.opendaylight.mdsal.dom.broker;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.FluentFuture;
import java.util.List;
import java.util.Map;
-import org.opendaylight.mdsal.dom.api.DOMRpcException;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException;
import org.opendaylight.mdsal.dom.api.DOMRpcResult;
+import org.opendaylight.yangtools.util.concurrent.FluentFutures;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
final class UnknownDOMRpcRoutingTableEntry extends AbstractDOMRpcRoutingTableEntry {
- private final CheckedFuture<DOMRpcResult, DOMRpcException> unknownRpc;
+ private final FluentFuture<DOMRpcResult> unknownRpc;
UnknownDOMRpcRoutingTableEntry(final SchemaPath schemaPath, final Map<YangInstanceIdentifier,
List<DOMRpcImplementation>> impls) {
super(schemaPath, impls);
- unknownRpc = Futures.<DOMRpcResult, DOMRpcException>immediateFailedCheckedFuture(
+ unknownRpc = FluentFutures.immediateFailedFluentFuture(
new DOMRpcImplementationNotAvailableException("SchemaPath %s is not resolved to an RPC", schemaPath));
}
@Override
- protected CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(final NormalizedNode<?, ?> input) {
+ protected FluentFuture<DOMRpcResult> invokeRpc(final NormalizedNode<?, ?> input) {
return unknownRpc;
}
List<DOMRpcImplementation>> impls) {
return new UnknownDOMRpcRoutingTableEntry(getSchemaPath(), impls);
}
-}
\ No newline at end of file
+}
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import org.junit.Test;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException;
public class GlobalDOMRpcRoutingTableEntryTest extends TestUtils {
@Test
- public void basicTest() throws Exception {
+ public void basicTest() throws InterruptedException, TimeoutException {
final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> rpcImplementations = new HashMap<>();
final List<DOMRpcImplementation> rpcImplementation = new ArrayList<>();
final RpcDefinition rpcDefinition = mock(RpcDefinition.class);
try {
globalDOMRpcRoutingTableEntry.newInstance(rpcImplementations)
- .invokeRpc(TEST_CONTAINER).checkedGet();
+ .invokeRpc(TEST_CONTAINER).get(5, TimeUnit.SECONDS);
fail("Expected DOMRpcImplementationNotAvailableException");
- } catch (DOMRpcImplementationNotAvailableException e) {
- assertTrue(e.getMessage().contains(EXCEPTION_TEXT));
+ } catch (ExecutionException e) {
+ assertTrue(e.getCause() instanceof DOMRpcImplementationNotAvailableException);
+ assertTrue(e.getCause().getMessage().contains(EXCEPTION_TEXT));
}
}
-}
\ No newline at end of file
+}
import static org.mockito.Mockito.mock;
import java.util.HashMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
import org.junit.Test;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException;
import org.opendaylight.mdsal.dom.broker.util.TestModel;
@SuppressWarnings("checkstyle:IllegalCatch")
@Test
- public void basicTest() throws Exception {
+ public void basicTest() throws InterruptedException, TimeoutException {
final RpcDefinition rpcDefinition = mock(RpcDefinition.class);
doReturn(SchemaPath.ROOT).when(rpcDefinition).getPath();
assertNotNull(routedDOMRpcRoutingTableEntry.newInstance(new HashMap<>()));
try {
- routedDOMRpcRoutingTableEntry.invokeRpc(TEST_CHILD).checkedGet();
+ routedDOMRpcRoutingTableEntry.invokeRpc(TEST_CHILD).get();
fail("Expected DOMRpcImplementationNotAvailableException");
- } catch (final Exception e) {
- assertTrue(e instanceof DOMRpcImplementationNotAvailableException);
+ } catch (ExecutionException e) {
+ assertTrue(e.getCause() instanceof DOMRpcImplementationNotAvailableException);
}
}
-}
\ No newline at end of file
+}
import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.leafNode;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.FluentFuture;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import org.opendaylight.mdsal.dom.api.DOMRpcException;
import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException;
import org.opendaylight.mdsal.dom.api.DOMRpcResult;
import org.opendaylight.mdsal.dom.broker.util.TestModel;
+import org.opendaylight.yangtools.util.concurrent.FluentFutures;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
}
private static final class TestRpcImplementation implements DOMRpcImplementation {
- private final CheckedFuture<DOMRpcResult, DOMRpcException> unknownRpc;
+ private final FluentFuture<DOMRpcResult> unknownRpc;
private TestRpcImplementation() {
- unknownRpc = Futures.immediateFailedCheckedFuture(
+ unknownRpc = FluentFutures.immediateFailedFluentFuture(
new DOMRpcImplementationNotAvailableException(EXCEPTION_TEXT));
}
+ @Override
@Nonnull
- public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(
- @Nonnull final DOMRpcIdentifier rpc, @Nullable final NormalizedNode<?, ?> input) {
+ public FluentFuture<DOMRpcResult> invokeRpc(@Nonnull final DOMRpcIdentifier rpc,
+ @Nullable final NormalizedNode<?, ?> input) {
return unknownRpc;
}
}
package org.opendaylight.mdsal.dom.spi;
import com.google.common.collect.ForwardingObject;
-import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import javax.annotation.Nonnull;
-import org.opendaylight.mdsal.dom.api.DOMRpcException;
import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
import org.opendaylight.mdsal.dom.api.DOMRpcResult;
protected abstract DOMRpcImplementation delegate();
@Override
- public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(
- final DOMRpcIdentifier type, final NormalizedNode<?, ?> input) {
+ public FluentFuture<DOMRpcResult> invokeRpc(final DOMRpcIdentifier type, final NormalizedNode<?, ?> input) {
return delegate().invokeRpc(type, input);
}
}
package org.opendaylight.mdsal.dom.spi;
import com.google.common.collect.ForwardingObject;
-import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import javax.annotation.Nonnull;
import org.opendaylight.mdsal.dom.api.DOMRpcAvailabilityListener;
-import org.opendaylight.mdsal.dom.api.DOMRpcException;
import org.opendaylight.mdsal.dom.api.DOMRpcResult;
import org.opendaylight.mdsal.dom.api.DOMRpcService;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
protected abstract DOMRpcService delegate();
@Override
- public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(
- final SchemaPath type, final NormalizedNode<?, ?> input) {
+ public FluentFuture<DOMRpcResult> invokeRpc(final SchemaPath type, final NormalizedNode<?, ?> input) {
return delegate().invokeRpc(type, input);
}