DOM RPC invocation takes ContainerNode 62/102662/1
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 13 Oct 2022 11:21:58 +0000 (13:21 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 13 Oct 2022 11:35:19 +0000 (13:35 +0200)
RPC input statements are equivalent to a ContainerNode, make sure to
update RPC services.

JIRA: MDSAL-541
Change-Id: Iaa26e7051cfb45e043acf4ca6f39125678684ea8
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMRpcImplementationAdapter.java
binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/Mdsal739Test.java
dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/DOMRpcImplementation.java
dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/DOMRpcService.java
dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/DOMRpcRouter.java
dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/RoutedDOMRpcRoutingTableEntryTest.java
dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/TestUtils.java
dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/ForwardingDOMRpcImplementation.java
dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/ForwardingDOMRpcService.java

index 51583e96fea65ccbb15cf2a9e38fa09178399301..cca58c0e43f2c770cefff308bf173f7ee16f6011 100644 (file)
@@ -29,7 +29,6 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.common.YangConstants;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
 
 final class BindingDOMRpcImplementationAdapter implements DOMRpcImplementation {
@@ -47,7 +46,7 @@ final class BindingDOMRpcImplementationAdapter implements DOMRpcImplementation {
     <T extends RpcService> BindingDOMRpcImplementationAdapter(final AdapterContext adapterContext,
             final Class<T> type, final Map<QName, Method> localNameToMethod, final T delegate) {
         try {
-            this.invoker = SERVICE_INVOKERS.get(type, () -> RpcServiceInvoker.from(localNameToMethod));
+            invoker = SERVICE_INVOKERS.get(type, () -> RpcServiceInvoker.from(localNameToMethod));
         } catch (ExecutionException e) {
             throw new IllegalArgumentException("Failed to create invokers for type " + type, e);
         }
@@ -58,7 +57,7 @@ final class BindingDOMRpcImplementationAdapter implements DOMRpcImplementation {
     }
 
     @Override
-    public ListenableFuture<DOMRpcResult> invokeRpc(final DOMRpcIdentifier rpc, final NormalizedNode input) {
+    public ListenableFuture<DOMRpcResult> invokeRpc(final DOMRpcIdentifier rpc, final ContainerNode input) {
         final QName rpcType = rpc.getType();
         final CurrentAdapterSerializer serializer = adapterContext.currentSerializer();
         final DataObject bindingInput = input != null ? deserialize(serializer, rpcType, input) : null;
@@ -72,15 +71,14 @@ final class BindingDOMRpcImplementationAdapter implements DOMRpcImplementation {
     }
 
     private DataObject deserialize(final CurrentAdapterSerializer serializer, final QName rpcType,
-            final NormalizedNode input) {
+            final ContainerNode input) {
         if (ENABLE_CODEC_SHORTCUT && input instanceof BindingLazyContainerNode) {
             return ((BindingLazyContainerNode<?>) input).getDataObject();
         }
 
-        final ContainerNode container = (ContainerNode) input;
-        checkArgument(inputQname.equals(container.getIdentifier().getNodeType()), "Unexpected RPC %s input %s", rpcType,
-            input);
-        return serializer.fromNormalizedNodeRpcData(Absolute.of(rpcType, inputQname), container);
+        checkArgument(inputQname.equals(input.getIdentifier().getNodeType()),
+            "Unexpected RPC %s input %s", rpcType, input);
+        return serializer.fromNormalizedNodeRpcData(Absolute.of(rpcType, inputQname), input);
     }
 
     private ListenableFuture<RpcResult<?>> invoke(final QName rpcType, final DataObject input) {
index f48d19b2a7d11fdee1ea9f9bbb4c40fb8e9d7634..e16ff619cf33e61a7f146a10b9dc2549648ee2c4 100644 (file)
@@ -35,7 +35,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controll
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 
 @ExtendWith(MockitoExtension.class)
@@ -64,7 +63,7 @@ public class Mdsal739Test {
     public void testRpcInputName() {
         final var rpcService = mock(DOMRpcService.class);
 
-        final var captor = ArgumentCaptor.forClass(NormalizedNode.class);
+        final var captor = ArgumentCaptor.forClass(ContainerNode.class);
         doReturn(Futures.immediateFailedFuture(new Throwable())).when(rpcService).invokeRpc(any(), captor.capture());
         final var adapter = (OpendaylightTestRpcServiceService) new RpcServiceAdapter(
             OpendaylightTestRpcServiceService.class, adapterContext, rpcService).getProxy();
@@ -74,7 +73,7 @@ public class Mdsal739Test {
         final var input = captor.getValue();
         assertThat(input, instanceOf(ContainerNode.class));
         assertSame(NodeIdentifier.create(RockTheHouseInput.QNAME), input.getIdentifier());
-        final var body = ((ContainerNode) input).body();
+        final var body = input.body();
         assertEquals(1, body.size());
         assertEquals(ImmutableNodes.leafNode(QName.create(RockTheHouseInput.QNAME, "zip-code"), "12345"),
             body.iterator().next());
index 73e8bb57c80bb4ced2b200b5df044e2e17662d14..7074eef968ecae2329c154a6652ddb1a573a2287 100644 (file)
@@ -9,7 +9,7 @@ package org.opendaylight.mdsal.dom.api;
 
 import com.google.common.util.concurrent.ListenableFuture;
 import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 
 /**
  * Interface implemented by an individual RPC implementation. This API allows for dispatch
@@ -28,7 +28,7 @@ public interface DOMRpcImplementation {
      * @throws NullPointerException if any argument is null
      */
     @NonNull ListenableFuture<? extends DOMRpcResult> invokeRpc(@NonNull DOMRpcIdentifier rpc,
-            @NonNull NormalizedNode input);
+            @NonNull ContainerNode input);
 
     /**
      * Return the relative invocation cost of this implementation. Default implementation return 0.
index f3f710909a048235c44c850e435c959b823849b2..b16ba74c895c8ba38d02cc1bb15d5af1d5647465 100644 (file)
@@ -11,7 +11,7 @@ import com.google.common.util.concurrent.ListenableFuture;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 
 /**
  * A {@link DOMService} which allows clients to invoke RPCs. The conceptual model of this service is that of a dynamic
@@ -29,14 +29,14 @@ public interface DOMRpcService extends DOMService {
      * @return A {@link ListenableFuture} which will return either a result structure, or report a subclass
      *         of {@link DOMRpcException} reporting a transport error.
      */
-    @NonNull ListenableFuture<? extends DOMRpcResult> invokeRpc(@NonNull QName type, @NonNull NormalizedNode input);
+    @NonNull ListenableFuture<? extends DOMRpcResult> invokeRpc(@NonNull QName type, @NonNull ContainerNode input);
 
     /**
      * Register a {@link DOMRpcAvailabilityListener} with this service to receive notifications
      * about RPC implementations becoming (un)available. The listener will be invoked with the
      * current implementations reported and will be kept uptodate as implementations come and go.
      * Users should note that using a listener does not necessarily mean that
-     * {@link #invokeRpc(QName, NormalizedNode)} will not report a failure due to
+     * {@link #invokeRpc(QName, ContainerNode)} will not report a failure due to
      * {@link DOMRpcImplementationNotAvailableException} and need to be ready to handle it.
      * Implementations are encouraged to take reasonable precautions to prevent this scenario from
      * occurring.
index ef656b8634277e7749db92e32a32abff0255c954..46406f83abad70adf2aeaeacd9ed46c2d900c3bd 100644 (file)
@@ -271,7 +271,7 @@ public final class DOMRpcRouter extends AbstractRegistration
         RegImpl(final DOMRpcRouter router, final T listener, final Map<QName, Set<YangInstanceIdentifier>> rpcs) {
             super(listener);
             this.router = requireNonNull(router);
-            this.prevRpcs = requireNonNull(rpcs);
+            prevRpcs = requireNonNull(rpcs);
         }
 
         @Override
@@ -351,7 +351,7 @@ public final class DOMRpcRouter extends AbstractRegistration
                 final Map<Absolute, Set<DOMDataTreeIdentifier>> actions) {
             super(listener);
             this.router = requireNonNull(router);
-            this.prevActions = requireNonNull(actions);
+            prevActions = requireNonNull(actions);
         }
 
         @Override
@@ -474,7 +474,7 @@ public final class DOMRpcRouter extends AbstractRegistration
 
     private final class RpcServiceFacade implements DOMRpcService {
         @Override
-        public ListenableFuture<? extends DOMRpcResult> invokeRpc(final QName type, final NormalizedNode input) {
+        public ListenableFuture<? extends DOMRpcResult> invokeRpc(final QName type, final ContainerNode input) {
             final AbstractDOMRpcRoutingTableEntry entry = (AbstractDOMRpcRoutingTableEntry) routingTable.getEntry(type);
             if (entry == null) {
                 return Futures.immediateFailedFuture(
@@ -565,7 +565,7 @@ public final class DOMRpcRouter extends AbstractRegistration
         }
 
         static ListenableFuture<? extends DOMRpcResult> invoke(final AbstractDOMRpcRoutingTableEntry entry,
-                final NormalizedNode input) {
+                final ContainerNode input) {
             if (entry instanceof UnknownDOMRpcRoutingTableEntry) {
                 return Futures.immediateFailedFuture(
                     new DOMRpcImplementationNotAvailableException("%s is not resolved to an RPC", entry.getType()));
@@ -580,7 +580,7 @@ public final class DOMRpcRouter extends AbstractRegistration
         }
 
         private static ListenableFuture<? extends DOMRpcResult> invokeRoutedRpc(
-                final RoutedDOMRpcRoutingTableEntry entry, final NormalizedNode input) {
+                final RoutedDOMRpcRoutingTableEntry entry, final ContainerNode input) {
             final Optional<NormalizedNode> maybeKey = NormalizedNodes.findNode(input,
                 entry.getRpcId().getContextReference());
 
@@ -624,7 +624,7 @@ public final class DOMRpcRouter extends AbstractRegistration
         }
 
         private static ListenableFuture<? extends DOMRpcResult> invokeGlobalRpc(
-                final GlobalDOMRpcRoutingTableEntry entry, final NormalizedNode input) {
+                final GlobalDOMRpcRoutingTableEntry entry, final ContainerNode input) {
             return entry.getImplementations(YangInstanceIdentifier.empty()).get(0).invokeRpc(entry.getRpcId(), input);
         }
     }
index e57809ad4ca7306dd0b81c2e8968b9f46708a931..5c82e1bc0a915aa00b6d87dca951d771821d93ba 100644 (file)
@@ -35,7 +35,6 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
@@ -146,7 +145,7 @@ public class RoutedDOMRpcRoutingTableEntryTest {
         entry = entry.newInstance(map);
     }
 
-    private void assertRpcAvailable(final NormalizedNode input) {
+    private void assertRpcAvailable(final ContainerNode input) {
         doReturn(Futures.immediateFuture(result)).when(impl).invokeRpc(any(), any());
 
         final var future = OperationInvocation.invoke(entry, input);
@@ -159,7 +158,7 @@ public class RoutedDOMRpcRoutingTableEntryTest {
         verify(impl).invokeRpc(any(), any());
     }
 
-    private void assertRpcUnavailable(final NormalizedNode input) {
+    private void assertRpcUnavailable(final ContainerNode input) {
         final var future = OperationInvocation.invoke(entry, input);
         final var cause = assertThrows(ExecutionException.class, () -> Futures.getDone(future)).getCause();
         assertThat(cause, instanceOf(DOMRpcImplementationNotAvailableException.class));
index edfecfe354c52c0ad8de54aed9e7a415fee27f24..1ebddce610c954e4dadb3d5fb138e04f1b32b833 100644 (file)
@@ -19,17 +19,17 @@ import org.opendaylight.yangtools.util.concurrent.FluentFutures;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
 
 final class TestUtils {
-
     private static final MapNode OUTER_LIST = ImmutableNodes.mapNodeBuilder(TestModel.OUTER_LIST_QNAME)
-            .withChild(ImmutableNodes.mapEntry(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1)).build();
+        .withChild(ImmutableNodes.mapEntry(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1))
+        .build();
 
     private static final String TOP_LEVEL_LIST_FOO_KEY_VALUE = "foo";
     private static final QName TOP_QNAME = TestModel.ID_QNAME;
@@ -37,26 +37,25 @@ final class TestUtils {
     private static final QName TOP_LEVEL_LIST_KEY_QNAME = QName.create(TOP_QNAME, "name");
 
     private static final MapEntryNode TOP_LEVEL_LIST_NODE = ImmutableMapEntryNodeBuilder.create()
-            .withNodeIdentifier(
-                    NodeIdentifierWithPredicates.of(
-                            TOP_LEVEL_LIST_QNAME, TOP_LEVEL_LIST_KEY_QNAME, TOP_LEVEL_LIST_FOO_KEY_VALUE))
-            .withChild(leafNode(TOP_LEVEL_LIST_KEY_QNAME, TOP_LEVEL_LIST_FOO_KEY_VALUE))
-            .build();
+        .withNodeIdentifier(NodeIdentifierWithPredicates.of(
+            TOP_LEVEL_LIST_QNAME, TOP_LEVEL_LIST_KEY_QNAME, TOP_LEVEL_LIST_FOO_KEY_VALUE))
+        .withChild(leafNode(TOP_LEVEL_LIST_KEY_QNAME, TOP_LEVEL_LIST_FOO_KEY_VALUE))
+        .build();
 
     private static final MapNode CHILD_LIST = ImmutableNodes.mapNodeBuilder(TestModel.TEST_QNAME)
-            .withNodeIdentifier(NodeIdentifier.create(TestModel.TEST_QNAME))
-            .withChild(TOP_LEVEL_LIST_NODE)
-            .build();
+        .withNodeIdentifier(NodeIdentifier.create(TestModel.TEST_QNAME))
+        .withChild(TOP_LEVEL_LIST_NODE)
+        .build();
 
-    static final NormalizedNode TEST_CONTAINER = Builders.containerBuilder()
-            .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
-            .withChild(OUTER_LIST)
-            .build();
+    static final ContainerNode TEST_CONTAINER = Builders.containerBuilder()
+        .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
+        .withChild(OUTER_LIST)
+        .build();
 
-    static final NormalizedNode TEST_CHILD = Builders.containerBuilder()
-            .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
-            .withChild(CHILD_LIST)
-            .build();
+    static final ContainerNode TEST_CHILD = Builders.containerBuilder()
+        .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
+        .withChild(CHILD_LIST)
+        .build();
 
     static final String EXCEPTION_TEXT = "TestRpcImplementationException";
 
@@ -77,7 +76,7 @@ final class TestUtils {
         }
 
         @Override
-        public FluentFuture<DOMRpcResult> invokeRpc(final DOMRpcIdentifier rpc, final NormalizedNode input) {
+        public FluentFuture<DOMRpcResult> invokeRpc(final DOMRpcIdentifier rpc, final ContainerNode input) {
             requireNonNull(input);
             return unknownRpc;
         }
index 92903cd79163b734d51fea485dc62f1a5c9c76c9..aff6bfcc4e2e8d5f6b85150bdbf36bc1b5fac8db 100644 (file)
@@ -13,7 +13,7 @@ import org.eclipse.jdt.annotation.NonNull;
 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.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 
 /**
  * Utility implementation which implements {@link DOMRpcImplementation} by forwarding it to
@@ -24,7 +24,7 @@ public abstract class ForwardingDOMRpcImplementation extends ForwardingObject im
     protected abstract @NonNull DOMRpcImplementation delegate();
 
     @Override
-    public ListenableFuture<? extends DOMRpcResult> invokeRpc(final DOMRpcIdentifier type, final NormalizedNode input) {
+    public ListenableFuture<? extends DOMRpcResult> invokeRpc(final DOMRpcIdentifier type, final ContainerNode input) {
         return delegate().invokeRpc(type, input);
     }
 }
index c2b85367db0fe4d29bb8f06882971ec214e7f73c..38ca71d1a7049095619f14927fc88ec458ce0064 100644 (file)
@@ -15,7 +15,7 @@ import org.opendaylight.mdsal.dom.api.DOMRpcResult;
 import org.opendaylight.mdsal.dom.api.DOMRpcService;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 
 /**
  * Utility {@link DOMRpcService} which forwards all requests to a backing delegate instance.
@@ -25,7 +25,7 @@ public abstract class ForwardingDOMRpcService extends ForwardingObject implement
     protected abstract @NonNull DOMRpcService delegate();
 
     @Override
-    public ListenableFuture<? extends DOMRpcResult> invokeRpc(final QName type, final NormalizedNode input) {
+    public ListenableFuture<? extends DOMRpcResult> invokeRpc(final QName type, final ContainerNode input) {
         return delegate().invokeRpc(type, input);
     }