From: Tom Pantelis Date: Sat, 14 Jul 2018 01:42:46 +0000 (-0400) Subject: Restore binding RPC shortcut X-Git-Tag: release/fluorine~41 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=b8293b9eb7eb0601d3dfa1fbe0816c0a461d91b9 Restore binding RPC shortcut The binding -> binding RPC serialization shortcut was broken by recent changes so restore it. The LazyDOMRpcResultFuture from the binding adapter is preserved by DOMRpcRouter via intermediate DOMRpcResult adapters. Change-Id: I98942471f4e8430d0043f5c09cb8a38ce2a5d7b9 Signed-off-by: Tom Pantelis --- diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/RpcServiceAdapter.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/RpcServiceAdapter.java index d61c9a4b6e..074341cc0c 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/RpcServiceAdapter.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/RpcServiceAdapter.java @@ -22,6 +22,7 @@ import org.opendaylight.controller.md.sal.dom.api.DOMRpcException; import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult; import org.opendaylight.controller.md.sal.dom.api.DOMRpcService; import org.opendaylight.controller.md.sal.dom.broker.spi.rpc.RpcRoutingStrategy; +import org.opendaylight.controller.sal.core.compat.LegacyDOMRpcResultFutureAdapter; import org.opendaylight.mdsal.binding.dom.adapter.BindingRpcFutureAware; import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer; import org.opendaylight.yangtools.yang.binding.DataContainer; @@ -68,6 +69,12 @@ class RpcServiceAdapter implements InvocationHandler { final CheckedFuture result = delegate.invokeRpc(schemaPath, input); if (result instanceof BindingRpcFutureAware) { return ((BindingRpcFutureAware) result).getBindingFuture(); + } else if (result instanceof LegacyDOMRpcResultFutureAdapter) { + CheckedFuture + delegateFuture = ((LegacyDOMRpcResultFutureAdapter)result).delegate(); + if (delegateFuture instanceof BindingRpcFutureAware) { + return ((BindingRpcFutureAware) delegateFuture).getBindingFuture(); + } } return transformFuture(schemaPath, result, codec.getCodecFactory()); diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java index 99385b0325..a337b5312a 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java @@ -11,9 +11,9 @@ import static com.google.common.base.Preconditions.checkState; import com.google.common.annotations.Beta; import com.google.common.collect.ImmutableMap; -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.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.MountPointService; @@ -82,6 +82,7 @@ public class BindingTestContext implements AutoCloseable { private BindingDOMRpcProviderServiceAdapter baProviderRpc; private DOMRpcRouter domRouter; + private org.opendaylight.mdsal.dom.broker.DOMRpcRouter delegateDomRouter; private NotificationPublishService publishService; @@ -91,7 +92,7 @@ public class BindingTestContext implements AutoCloseable { private DOMNotificationService domListenService; - + private Set schemaModuleInfos; public DOMDataBroker getDomAsyncDataBroker() { return this.newDOMDataBroker; @@ -169,11 +170,11 @@ public class BindingTestContext implements AutoCloseable { this.mockSchemaService.registerSchemaContextListener(this.codec); } - private void updateYangSchema(final ImmutableSet moduleInfos) { + private void updateYangSchema(final Set moduleInfos) { this.mockSchemaService.changeSchema(getContext(moduleInfos)); } - private SchemaContext getContext(final ImmutableSet moduleInfos) { + private SchemaContext getContext(final Set moduleInfos) { final ModuleInfoBackedContext ctx = ModuleInfoBackedContext.create(); ctx.addModuleInfos(moduleInfos); return ctx.tryToCreateSchemaContext().get(); @@ -190,7 +191,10 @@ public class BindingTestContext implements AutoCloseable { startBindingBroker(); startForwarding(); - if (this.startWithSchema) { + + if (schemaModuleInfos != null) { + updateYangSchema(schemaModuleInfos); + } else if (this.startWithSchema) { loadYangSchemaFromClasspath(); } } @@ -202,9 +206,8 @@ public class BindingTestContext implements AutoCloseable { private void startDomBroker() { checkState(this.executor != null); - org.opendaylight.mdsal.dom.broker.DOMRpcRouter delegate = - org.opendaylight.mdsal.dom.broker.DOMRpcRouter.newInstance(mockSchemaService); - this.domRouter = new DOMRpcRouter(delegate, delegate); + delegateDomRouter = org.opendaylight.mdsal.dom.broker.DOMRpcRouter.newInstance(mockSchemaService); + this.domRouter = new DOMRpcRouter(delegateDomRouter, delegateDomRouter); } public void startBindingNotificationBroker() { @@ -219,8 +222,7 @@ public class BindingTestContext implements AutoCloseable { } public void loadYangSchemaFromClasspath() { - final ImmutableSet moduleInfos = BindingReflections.loadModuleInfos(); - updateYangSchema(moduleInfos); + updateYangSchema(BindingReflections.loadModuleInfos()); } public RpcProviderRegistry getBindingRpcRegistry() { @@ -235,6 +237,10 @@ public class BindingTestContext implements AutoCloseable { return this.domRouter; } + public org.opendaylight.mdsal.dom.broker.DOMRpcRouter getDelegateDomRouter() { + return delegateDomRouter; + } + @Override public void close() throws Exception { @@ -251,4 +257,8 @@ public class BindingTestContext implements AutoCloseable { public DataBroker getDataBroker() { return this.dataBroker; } + + public void setSchemaModuleInfos(Set moduleInfos) { + this.schemaModuleInfos = moduleInfos; + } } diff --git a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerRpcTest.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerRpcTest.java index dbb839e3ff..dcdb5a1b0e 100644 --- a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerRpcTest.java +++ b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerRpcTest.java @@ -10,12 +10,19 @@ package org.opendaylight.controller.sal.binding.test.connect.dom; 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.After; import org.junit.Before; import org.junit.Test; @@ -27,6 +34,7 @@ import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult; import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; import org.opendaylight.controller.sal.binding.test.util.BindingBrokerTestFactory; import org.opendaylight.controller.sal.binding.test.util.BindingTestContext; +import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMRpcProviderServiceAdapter; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.of.migration.test.model.rev150210.KnockKnockInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.of.migration.test.model.rev150210.KnockKnockInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.of.migration.test.model.rev150210.KnockKnockOutput; @@ -38,6 +46,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controll import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.rpc.routing.rev140701.TestContext; import org.opendaylight.yangtools.yang.binding.DataObject; 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; @@ -70,12 +79,13 @@ public class CrossBrokerRpcTest { @Before - public void setup() { + public void setup() throws Exception { BindingBrokerTestFactory testFactory = new BindingBrokerTestFactory(); testFactory.setExecutor(MoreExecutors.newDirectExecutorService()); - testFactory.setStartWithParsedSchema(true); testContext = testFactory.getTestContext(); + testContext.setSchemaModuleInfos(ImmutableSet.of( + BindingReflections.getModuleInfo(OpendaylightOfMigrationTestModelService.class))); testContext.start(); providerRegistry = testContext.getBindingRpcRegistry(); provisionRegistry = testContext.getDomRpcRegistry(); @@ -87,6 +97,58 @@ public class CrossBrokerRpcTest { } + @After + public void teardown() throws Exception { + testContext.close(); + } + + @Test + public void testBindingRpcShortcutRegisteredViaLegacyAPI() + throws InterruptedException, ExecutionException, TimeoutException { + final ListenableFuture> knockResult = knockResult(true, "open"); + knockService.registerPath(TestContext.class, BA_NODE_A_ID).setKnockKnockResult(knockResult); + + OpendaylightOfMigrationTestModelService baKnockInvoker = + providerRegistry.getRpcService(OpendaylightOfMigrationTestModelService.class); + + final KnockKnockInput knockInput = knockKnock(BA_NODE_A_ID).setQuestion("Who's there?").build(); + ListenableFuture> future = baKnockInvoker.knockKnock(knockInput); + + final RpcResult rpcResult = future.get(5, TimeUnit.SECONDS); + + assertEquals(knockResult.get().getResult().getClass(), rpcResult.getResult().getClass()); + assertSame(knockResult.get().getResult(), rpcResult.getResult()); + assertSame(knockInput, knockService.getReceivedKnocks().get(BA_NODE_A_ID).iterator().next()); + } + + @Test + public void testBindingRpcShortcutRegisteredViaMdsalAPI() + throws InterruptedException, ExecutionException, TimeoutException { + final ListenableFuture> knockResult = knockResult(true, "open"); + + BindingDOMRpcProviderServiceAdapter mdsalServiceRegistry = new BindingDOMRpcProviderServiceAdapter( + testContext.getDelegateDomRouter(), testContext.getCodec()); + + final Multimap, KnockKnockInput> receivedKnocks = HashMultimap.create(); + mdsalServiceRegistry.registerRpcImplementation(OpendaylightOfMigrationTestModelService.class, + (OpendaylightOfMigrationTestModelService) input -> { + receivedKnocks.put(input.getKnockerId(), input); + return knockResult; + }, ImmutableSet.of(BA_NODE_A_ID)); + + OpendaylightOfMigrationTestModelService baKnockInvoker = + providerRegistry.getRpcService(OpendaylightOfMigrationTestModelService.class); + + final KnockKnockInput knockInput = knockKnock(BA_NODE_A_ID).setQuestion("Who's there?").build(); + Future> future = baKnockInvoker.knockKnock(knockInput); + + final RpcResult rpcResult = future.get(5, TimeUnit.SECONDS); + + assertEquals(knockResult.get().getResult().getClass(), rpcResult.getResult().getClass()); + assertSame(knockResult.get().getResult(), rpcResult.getResult()); + assertSame(knockInput, receivedKnocks.get(BA_NODE_A_ID).iterator().next()); + } + @Test public void bindingRoutedRpcProvider_DomInvokerTest() throws Exception { @@ -134,11 +196,6 @@ public class CrossBrokerRpcTest { return testContext.getCodec().getCodecFactory().toNormalizedNodeRpcData(addFlowA); } - @After - public void teardown() throws Exception { - testContext.close(); - } - private static org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier createBINodeIdentifier( final TopLevelListKey listKey) { return org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.builder().node(Top.QNAME) diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMRpcRouter.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMRpcRouter.java index 3d57aac601..54845cf097 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMRpcRouter.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMRpcRouter.java @@ -10,9 +10,6 @@ package org.opendaylight.controller.md.sal.dom.broker.impl; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.CheckedFuture; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.MoreExecutors; import java.util.Collection; import java.util.Collections; import java.util.Map; @@ -23,46 +20,21 @@ import org.opendaylight.controller.md.sal.dom.api.DOMRpcAvailabilityListener; import org.opendaylight.controller.md.sal.dom.api.DOMRpcException; import org.opendaylight.controller.md.sal.dom.api.DOMRpcIdentifier; import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementation; -import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationNotAvailableException; import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationRegistration; import org.opendaylight.controller.md.sal.dom.api.DOMRpcProviderService; import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult; import org.opendaylight.controller.md.sal.dom.api.DOMRpcService; -import org.opendaylight.controller.md.sal.dom.api.DefaultDOMRpcException; import org.opendaylight.controller.md.sal.dom.spi.AbstractDOMRpcImplementationRegistration; -import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult; -import org.opendaylight.mdsal.common.api.MappingCheckedFuture; +import org.opendaylight.controller.sal.core.compat.LegacyDOMRpcResultFutureAdapter; +import org.opendaylight.controller.sal.core.compat.MdsalDOMRpcResultFutureAdapter; import org.opendaylight.yangtools.concepts.AbstractListenerRegistration; import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.util.concurrent.ExceptionMapper; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaContextListener; import org.opendaylight.yangtools.yang.model.api.SchemaPath; public final class DOMRpcRouter implements AutoCloseable, DOMRpcService, DOMRpcProviderService, SchemaContextListener { - private static final ExceptionMapper MDSAL_DOM_RPC_EX_MAPPER = - new ExceptionMapper( - "rpc", org.opendaylight.mdsal.dom.api.DOMRpcException.class) { - @Override - protected org.opendaylight.mdsal.dom.api.DOMRpcException newWithCause(String message, Throwable cause) { - return cause instanceof org.opendaylight.mdsal.dom.api.DOMRpcException - ? (org.opendaylight.mdsal.dom.api.DOMRpcException)cause - : new org.opendaylight.mdsal.dom.api.DefaultDOMRpcException("RPC failed", cause); - } - }; - - private static final ExceptionMapper LEGACY_DOM_RPC_EX_MAPPER = - new ExceptionMapper("rpc", DOMRpcException.class) { - @Override - protected DOMRpcException newWithCause(String message, Throwable cause) { - return cause instanceof DOMRpcException ? (DOMRpcException)cause - : cause instanceof org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException - ? new DOMRpcImplementationNotAvailableException(cause.getMessage(), cause.getCause()) - : new DefaultDOMRpcException("RPC failed", cause); - } - }; - // This mapping is used to translate mdsal DOMRpcImplementations to their corresponding legacy // DOMRpcImplementations registered thru this interface when invoking a DOMRpcAvailabilityListener. private final Map implMapping = @@ -90,7 +62,6 @@ public final class DOMRpcRouter implements AutoCloseable, DOMRpcService, DOMRpcP return registerRpcImplementation(implementation, ImmutableSet.copyOf(rpcs)); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public synchronized DOMRpcImplementationRegistration registerRpcImplementation( final T implementation, final Set rpcs) { @@ -100,8 +71,7 @@ public final class DOMRpcRouter implements AutoCloseable, DOMRpcService, DOMRpcP public CheckedFuture invokeRpc( org.opendaylight.mdsal.dom.api.DOMRpcIdentifier rpc, NormalizedNode input) { - final ListenableFuture future = implementation.invokeRpc(convert(rpc), input); - return MappingCheckedFuture.create(future, MDSAL_DOM_RPC_EX_MAPPER); + return new MdsalDOMRpcResultFutureAdapter(implementation.invokeRpc(convert(rpc), input)); } @Override @@ -134,12 +104,6 @@ public final class DOMRpcRouter implements AutoCloseable, DOMRpcService, DOMRpcP return DOMRpcIdentifier.create(from.getType(), from.getContextReference()); } - private static ListenableFuture convert(org.opendaylight.mdsal.dom.api.DOMRpcResult from) { - return from == null ? Futures.immediateFuture(null) - : from instanceof DOMRpcResult ? Futures.immediateFuture((DOMRpcResult)from) - : Futures.immediateFuture(new DefaultDOMRpcResult(from.getResult(), from.getErrors())); - } - private static Collection convert( Collection from) { return from.stream().map(DOMRpcRouter::convert).collect(Collectors.toList()); @@ -148,9 +112,10 @@ public final class DOMRpcRouter implements AutoCloseable, DOMRpcService, DOMRpcP @Override public CheckedFuture invokeRpc(final SchemaPath type, final NormalizedNode input) { - final ListenableFuture future = Futures.transformAsync(delegateRpcService.invokeRpc(type, input), - DOMRpcRouter::convert, MoreExecutors.directExecutor()); - return MappingCheckedFuture.create(future, LEGACY_DOM_RPC_EX_MAPPER); + final CheckedFuture + future = delegateRpcService.invokeRpc(type, input); + return future instanceof MdsalDOMRpcResultFutureAdapter ? ((MdsalDOMRpcResultFutureAdapter)future).delegate() + : new LegacyDOMRpcResultFutureAdapter(future); } @Override diff --git a/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/AbstractDOMRpcResultFutureAdapter.java b/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/AbstractDOMRpcResultFutureAdapter.java new file mode 100644 index 0000000000..376682a26d --- /dev/null +++ b/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/AbstractDOMRpcResultFutureAdapter.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2018 Inocybe Technologies 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.controller.sal.core.compat; + +import com.google.common.util.concurrent.CheckedFuture; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import java.util.Optional; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import org.opendaylight.mdsal.dom.api.DOMRpcException; +import org.opendaylight.mdsal.dom.api.DOMRpcResult; +import org.opendaylight.yangtools.util.concurrent.ExceptionMapper; + +/** + * Base for a DOMRpcResult future adapter. + * + * @author Thomas Pantelis + */ +@SuppressWarnings("checkstyle:ClassTypeParameterName") +public abstract class AbstractDOMRpcResultFutureAdapter implements CheckedFuture { + private final CheckedFuture delegate; + private final ExceptionMapper exMapper; + private volatile Optional result; + + AbstractDOMRpcResultFutureAdapter(CheckedFuture delegate, ExceptionMapper exMapper) { + this.delegate = delegate; + this.exMapper = exMapper; + } + + protected abstract T transform(F fromResult); + + public CheckedFuture delegate() { + return delegate; + } + + @Override + public void addListener(Runnable listener, Executor executor) { + delegate.addListener(listener, executor); + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return delegate.cancel(mayInterruptIfRunning); + } + + @Override + public boolean isCancelled() { + return delegate.isCancelled(); + } + + @Override + public boolean isDone() { + return delegate.isDone(); + } + + @Override + public T get() throws InterruptedException, ExecutionException { + if (result != null) { + return result.orElse(null); + } + + try { + return transformIfNecessary(delegate.get()); + } catch (ExecutionException e) { + throw new ExecutionException(e.getMessage(), exMapper.apply(e)); + } + } + + @Override + public T get(final long timeout, final TimeUnit unit) throws InterruptedException, ExecutionException, + TimeoutException { + if (result != null) { + return result.orElse(null); + } + + try { + return transformIfNecessary(delegate.get(timeout, unit)); + } catch (ExecutionException e) { + throw new ExecutionException(e.getMessage(), exMapper.apply(e)); + } + } + + @Override + @SuppressFBWarnings("BC_UNCONFIRMED_CAST_OF_RETURN_VALUE") + public T checkedGet() throws TE { + try { + return get(); + } catch (InterruptedException | ExecutionException e) { + throw exMapper.apply(e); + } + } + + @Override + @SuppressFBWarnings("BC_UNCONFIRMED_CAST_OF_RETURN_VALUE") + public T checkedGet(final long timeout, final TimeUnit unit) throws TimeoutException, TE { + try { + return get(timeout, unit); + } catch (InterruptedException | ExecutionException e) { + throw exMapper.apply(e); + } + } + + private synchronized T transformIfNecessary(F delegateResult) { + if (result == null) { + if (delegateResult == null) { + result = Optional.empty(); + } else { + result = Optional.of(transform(delegateResult)); + } + } + + return result.orElse(null); + } +} diff --git a/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/LegacyDOMRpcResultFutureAdapter.java b/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/LegacyDOMRpcResultFutureAdapter.java new file mode 100644 index 0000000000..3e803449bd --- /dev/null +++ b/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/LegacyDOMRpcResultFutureAdapter.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018 Inocybe Technologies 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.controller.sal.core.compat; + +import com.google.common.util.concurrent.CheckedFuture; +import org.opendaylight.controller.md.sal.dom.api.DOMRpcException; +import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationNotAvailableException; +import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult; +import org.opendaylight.controller.md.sal.dom.api.DefaultDOMRpcException; +import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult; +import org.opendaylight.yangtools.util.concurrent.ExceptionMapper; + +/** + * Adapts a {@link org.opendaylight.mdsal.dom.api.DOMRpcResult} CheckedFuture to a {@link DOMRpcResult} CheckedFuture. + * + * @author Thomas Pantelis + */ +public class LegacyDOMRpcResultFutureAdapter extends AbstractDOMRpcResultFutureAdapter { + + private static final ExceptionMapper LEGACY_DOM_RPC_EX_MAPPER = + new ExceptionMapper("rpc", DOMRpcException.class) { + @Override + protected DOMRpcException newWithCause(String message, Throwable cause) { + return cause instanceof DOMRpcException ? (DOMRpcException)cause + : cause instanceof org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException + ? new DOMRpcImplementationNotAvailableException(cause.getMessage(), cause.getCause()) + : new DefaultDOMRpcException("RPC failed", cause); + } + }; + + public LegacyDOMRpcResultFutureAdapter(CheckedFuture delegate) { + super(delegate, LEGACY_DOM_RPC_EX_MAPPER); + } + + @Override + protected DOMRpcResult transform(org.opendaylight.mdsal.dom.api.DOMRpcResult fromResult) { + return new DefaultDOMRpcResult(fromResult.getResult(), fromResult.getErrors()); + } +} diff --git a/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/MdsalDOMRpcResultFutureAdapter.java b/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/MdsalDOMRpcResultFutureAdapter.java new file mode 100644 index 0000000000..bc06110dce --- /dev/null +++ b/opendaylight/md-sal/sal-dom-compat/src/main/java/org/opendaylight/controller/sal/core/compat/MdsalDOMRpcResultFutureAdapter.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018 Inocybe Technologies 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.controller.sal.core.compat; + +import com.google.common.util.concurrent.CheckedFuture; +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; + +/** + * Adapts a {@link org.opendaylight.controller.md.sal.dom.api.DOMRpcResult} CheckedFuture to a + * {@link DOMRpcResult} CheckedFuture. + * + * @author Thomas Pantelis + */ +public class MdsalDOMRpcResultFutureAdapter extends AbstractDOMRpcResultFutureAdapter< + DOMRpcResult, DOMRpcException, org.opendaylight.controller.md.sal.dom.api.DOMRpcResult, + org.opendaylight.controller.md.sal.dom.api.DOMRpcException> { + private static final ExceptionMapper MDSAL_DOM_RPC_EX_MAPPER = + new ExceptionMapper("rpc", DOMRpcException.class) { + @Override + protected DOMRpcException newWithCause(String message, Throwable cause) { + return cause instanceof DOMRpcException ? (DOMRpcException) cause + : new DefaultDOMRpcException("RPC failed", cause); + } + }; + + public MdsalDOMRpcResultFutureAdapter(CheckedFuture delegate) { + super(delegate, MDSAL_DOM_RPC_EX_MAPPER); + } + + @Override + protected DOMRpcResult transform(org.opendaylight.controller.md.sal.dom.api.DOMRpcResult fromResult) { + return new DefaultDOMRpcResult(fromResult.getResult(), fromResult.getErrors()); + } +}