Derive RpcRoutingStrategy from RpcEffectiveStatement 06/103306/2
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 21 Nov 2022 13:10:39 +0000 (14:10 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 21 Nov 2022 18:04:12 +0000 (19:04 +0100)
Use RpcEffectiveStatement instead of RpcDefinition to derive the
strategy. A knock-on effect is a clean up of entries and their tests,
as they can operate solely on QNames now.

Change-Id: Id2988458bb923d09b07a5a1819554b043b3840d8
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/RpcServiceAdapter.java
dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/DOMRpcRoutingTable.java
dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/GlobalDOMRpcRoutingTableEntry.java
dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/RoutedDOMRpcRoutingTableEntry.java
dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/GlobalDOMRpcRoutingTableEntryTest.java
dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/RoutedDOMRpcRoutingTableEntryTest.java
dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/RpcRoutingStrategy.java
dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/RpcRoutingStrategyTest.java

index 5c2ab06080262c85404f1ff2039363bafa456f63..f0023fa1856419e467d5e0fef08d857cabe2a157 100644 (file)
@@ -69,7 +69,7 @@ class RpcServiceAdapter implements InvocationHandler {
 
     private RpcInvocationStrategy createStrategy(final Method method, final RpcDefinition schema) {
         final QName rpcType = schema.getQName();
-        final RpcRoutingStrategy strategy = RpcRoutingStrategy.from(schema);
+        final RpcRoutingStrategy strategy = RpcRoutingStrategy.from(schema.asEffectiveStatement());
         return strategy.isContextBasedRouted() ? new RoutedStrategy(rpcType, method, strategy.getLeaf())
                 : new NonRoutedStrategy(rpcType);
     }
index 62903f20edcfedce5b033f71b15a265b27f68d7c..af9bb33b1b85df96bf3fd7e45c5dd235ba25b308 100644 (file)
@@ -13,6 +13,7 @@ import com.google.common.collect.ListMultimap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.mdsal.dom.api.DOMRpcAvailabilityListener;
 import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
 import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
@@ -20,9 +21,7 @@ import org.opendaylight.mdsal.dom.spi.RpcRoutingStrategy;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.stmt.RpcEffectiveStatement;
 
 final class DOMRpcRoutingTable extends AbstractDOMRoutingTable<DOMRpcIdentifier, YangInstanceIdentifier,
         DOMRpcImplementation, DOMRpcAvailabilityListener, QName, AbstractDOMRpcRoutingTableEntry> {
@@ -56,32 +55,26 @@ final class DOMRpcRoutingTable extends AbstractDOMRoutingTable<DOMRpcIdentifier,
     @Override
     AbstractDOMRpcRoutingTableEntry createOperationEntry(final EffectiveModelContext context, final QName key,
             final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> implementations) {
-        final RpcDefinition rpcDef = findRpcDefinition(context, key);
+        final var rpcDef = findRpcDefinition(context, key);
         if (rpcDef == null) {
             return new UnknownDOMRpcRoutingTableEntry(key, implementations);
         }
 
         final RpcRoutingStrategy strategy = RpcRoutingStrategy.from(rpcDef);
         if (strategy.isContextBasedRouted()) {
-            return new RoutedDOMRpcRoutingTableEntry(rpcDef, YangInstanceIdentifier.of(strategy.getLeaf()),
+            return new RoutedDOMRpcRoutingTableEntry(rpcDef.argument(), YangInstanceIdentifier.of(strategy.getLeaf()),
                 implementations);
         }
 
-        return new GlobalDOMRpcRoutingTableEntry(rpcDef, implementations);
+        return new GlobalDOMRpcRoutingTableEntry(rpcDef.argument(), implementations);
     }
 
-    private static RpcDefinition findRpcDefinition(final SchemaContext context, final QName qname) {
-        if (context != null) {
-            final Module module = context.findModule(qname.getModule()).orElse(null);
-            if (module != null && module.getRpcs() != null) {
-                for (RpcDefinition rpc : module.getRpcs()) {
-                    if (qname.equals(rpc.getQName())) {
-                        return rpc;
-                    }
-                }
-            }
-        }
-
-        return null;
+    private static @Nullable RpcEffectiveStatement findRpcDefinition(final EffectiveModelContext context,
+            final QName qname) {
+        return context == null ? null : context.findModuleStatement(qname.getModule())
+            .flatMap(module -> module.findSchemaTreeNode(qname))
+            .filter(RpcEffectiveStatement.class::isInstance)
+            .map(RpcEffectiveStatement.class::cast)
+            .orElse(null);
     }
 }
index cf7e6215db9f3c2d3425058b0573f71b79e2d30d..86269b2fe2202e481145857317122c8a064ffdb2 100644 (file)
@@ -9,10 +9,11 @@ package org.opendaylight.mdsal.dom.broker;
 
 import java.util.List;
 import java.util.Map;
+import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
 import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
 
 final class GlobalDOMRpcRoutingTableEntry extends AbstractDOMRpcRoutingTableEntry {
     private GlobalDOMRpcRoutingTableEntry(final DOMRpcIdentifier rpcId,
@@ -22,9 +23,9 @@ final class GlobalDOMRpcRoutingTableEntry extends AbstractDOMRpcRoutingTableEntr
 
     // We do not need the RpcDefinition, but this makes sure we do not
     // forward something we don't know to be an RPC.
-    GlobalDOMRpcRoutingTableEntry(final RpcDefinition def,
+    GlobalDOMRpcRoutingTableEntry(final @NonNull QName rpcName,
             final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> impls) {
-        super(DOMRpcIdentifier.create(def.getQName()), impls);
+        super(DOMRpcIdentifier.create(rpcName), impls);
     }
 
     @Override
index bfea5534ac592bb254ba8786d010384531e93fc6..a8f7a6e1c52dbc3f5c8122ab8d734d27e4593673 100644 (file)
@@ -9,10 +9,11 @@ package org.opendaylight.mdsal.dom.broker;
 
 import java.util.List;
 import java.util.Map;
+import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
 import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
 
 final class RoutedDOMRpcRoutingTableEntry extends AbstractDOMRpcRoutingTableEntry {
     private RoutedDOMRpcRoutingTableEntry(final DOMRpcIdentifier routedRpcId,
@@ -20,9 +21,9 @@ final class RoutedDOMRpcRoutingTableEntry extends AbstractDOMRpcRoutingTableEntr
         super(routedRpcId, impls);
     }
 
-    RoutedDOMRpcRoutingTableEntry(final RpcDefinition def, final YangInstanceIdentifier keyId,
+    RoutedDOMRpcRoutingTableEntry(final @NonNull QName rpcName, final YangInstanceIdentifier keyId,
             final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> impls) {
-        super(DOMRpcIdentifier.create(def.getQName(), keyId), impls);
+        super(DOMRpcIdentifier.create(rpcName, keyId), impls);
     }
 
     @Override
index 22c76ab2d7255333a34b516602c8fe69ec18509c..250cdb9d2fdcfdaacac111a0734ddd0c749c4ee9 100644 (file)
@@ -14,37 +14,32 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.opendaylight.mdsal.dom.broker.TestUtils.EXCEPTION_TEXT;
 import static org.opendaylight.mdsal.dom.broker.TestUtils.TEST_CONTAINER;
 import static org.opendaylight.mdsal.dom.broker.TestUtils.getTestRpcImplementation;
 
+import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
 import org.junit.Test;
 import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
 import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException;
 import org.opendaylight.mdsal.dom.broker.DOMRpcRouter.OperationInvocation;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
 
 public class GlobalDOMRpcRoutingTableEntryTest {
     @Test
     public void basicTest() {
         final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> rpcImplementations = new HashMap<>();
         final List<DOMRpcImplementation> rpcImplementation = new ArrayList<>();
-        final RpcDefinition rpcDefinition = mock(RpcDefinition.class);
         final YangInstanceIdentifier yangInstanceIdentifier = YangInstanceIdentifier.builder().build();
 
-        doReturn(TestModel.TEST2_QNAME).when(rpcDefinition).getQName();
         final GlobalDOMRpcRoutingTableEntry globalDOMRpcRoutingTableEntry = new GlobalDOMRpcRoutingTableEntry(
-                rpcDefinition, new HashMap<>());
+            TestModel.TEST2_QNAME, new HashMap<>());
         rpcImplementation.add(getTestRpcImplementation());
         rpcImplementations.put(yangInstanceIdentifier, rpcImplementation);
 
@@ -57,8 +52,7 @@ public class GlobalDOMRpcRoutingTableEntryTest {
         final ListenableFuture<?> future = OperationInvocation.invoke(
             globalDOMRpcRoutingTableEntry.newInstance(rpcImplementations), TEST_CONTAINER);
 
-        final ExecutionException ex = assertThrows(ExecutionException.class, () -> future.get(5, TimeUnit.SECONDS));
-        final Throwable cause = ex.getCause();
+        final var cause = assertThrows(ExecutionException.class, () -> Futures.getDone(future)).getCause();
         assertThat(cause, instanceOf(DOMRpcImplementationNotAvailableException.class));
         assertThat(cause.getMessage(), containsString(EXCEPTION_TEXT));
     }
index 5c82e1bc0a915aa00b6d87dca951d771821d93ba..b7ddbe4a41dda3601794d4850c2d3c0c198ffca1 100644 (file)
@@ -37,7 +37,6 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdent
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 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;
 
 @RunWith(MockitoJUnitRunner.StrictStubs.class)
 public class RoutedDOMRpcRoutingTableEntryTest {
@@ -62,8 +61,6 @@ public class RoutedDOMRpcRoutingTableEntryTest {
         .withChild(ImmutableNodes.leafNode(Rpcs.NAME, "name"))
         .build();
 
-    @Mock
-    public RpcDefinition definition;
     @Mock
     public DOMRpcImplementation impl;
     @Mock
@@ -72,9 +69,8 @@ public class RoutedDOMRpcRoutingTableEntryTest {
 
     @Before
     public void before() {
-        doReturn(Rpcs.BAR).when(definition).getQName();
         // Note: ImmutableMap.of() allows get(null), Map.of() does not
-        entry = new RoutedDOMRpcRoutingTableEntry(definition, CTX_IN_INPUT, ImmutableMap.of());
+        entry = new RoutedDOMRpcRoutingTableEntry(Rpcs.BAR, CTX_IN_INPUT, ImmutableMap.of());
     }
 
     @Test
index d724e87f71b35662cda0bb0554ff66c7c78136d2..f352893a57454e7a2b93e3d3ceac77b8e42fd705 100644 (file)
@@ -13,8 +13,8 @@ import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.odlext.model.api.ContextReferenceEffectiveStatement;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.InputEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.RpcEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
 
 public abstract sealed class RpcRoutingStrategy implements Identifiable<QName> {
@@ -52,18 +52,23 @@ public abstract sealed class RpcRoutingStrategy implements Identifiable<QName> {
      */
     public abstract boolean isContextBasedRouted();
 
-    public static RpcRoutingStrategy from(final RpcDefinition rpc) {
+    public static @NonNull RpcRoutingStrategy from(final RpcEffectiveStatement rpc) {
         // FIXME: deprecate context-reference
-        for (EffectiveStatement<?, ?> stmt : rpc.getInput().asEffectiveStatement().effectiveSubstatements()) {
+        return of(rpc.argument(), rpc.findFirstEffectiveSubstatement(InputEffectiveStatement.class)
+            .orElseThrow(() -> new IllegalArgumentException("Cannot find input in " + rpc)));
+    }
+
+    private static @NonNull RpcRoutingStrategy of(final QName rpcName, final InputEffectiveStatement input) {
+        for (var stmt : input.effectiveSubstatements()) {
             if (stmt instanceof SchemaTreeEffectiveStatement<?> schemaStmt) {
                 final var context =
                     stmt.findFirstEffectiveSubstatementArgument(ContextReferenceEffectiveStatement.class);
                 if (context.isPresent()) {
-                    return new RoutedRpcStrategy(rpc.getQName(), context.orElseThrow(), schemaStmt.argument());
+                    return new RoutedRpcStrategy(rpcName, context.orElseThrow(), schemaStmt.argument());
                 }
             }
         }
-        return new GlobalRpcStrategy(rpc.getQName());
+        return new GlobalRpcStrategy(rpcName);
     }
 
     private static final class RoutedRpcStrategy extends RpcRoutingStrategy {
index 1a2f89560e30966ba21a41f952b8cf8a8ed384b5..07bebbd34a6d04a3ccefd96d617866b6c3911a86 100644 (file)
@@ -14,20 +14,21 @@ import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 
 import com.google.common.collect.Iterables;
-import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.extension.yang.ext.rev130709.$YangModuleInfoImpl;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.stmt.RpcEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration;
 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
 
 public class RpcRoutingStrategyTest {
-    private static Collection<? extends RpcDefinition> RPCS;
+    private static List<RpcEffectiveStatement> RPCS;
 
     @BeforeClass
     public static void beforeClass() {
@@ -36,10 +37,9 @@ public class RpcRoutingStrategyTest {
                 $YangModuleInfoImpl.getInstance().getYangTextByteSource()),
             YangTextSchemaSource.forResource(RpcRoutingStrategy.class, "/rpc-routing-strategy.yang"));
 
-        RPCS = ctx.getModules().stream()
-            .filter(module -> module.getName().equals("foo"))
-            .findFirst().orElseThrow()
-            .getRpcs();
+        RPCS = Iterables.getOnlyElement(ctx.findModuleStatements("foo"))
+            .streamEffectiveSubstatements(RpcEffectiveStatement.class)
+            .collect(Collectors.toUnmodifiableList());
     }
 
     @AfterClass