From 15c98a268eb948e03aa9d95777f4e4d71c1b447f Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Mon, 21 Nov 2022 14:10:39 +0100 Subject: [PATCH] Derive RpcRoutingStrategy from RpcEffectiveStatement 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 --- .../dom/adapter/RpcServiceAdapter.java | 2 +- .../mdsal/dom/broker/DOMRpcRoutingTable.java | 31 +++++++------------ .../broker/GlobalDOMRpcRoutingTableEntry.java | 7 +++-- .../broker/RoutedDOMRpcRoutingTableEntry.java | 7 +++-- .../GlobalDOMRpcRoutingTableEntryTest.java | 12 ++----- .../RoutedDOMRpcRoutingTableEntryTest.java | 6 +--- .../mdsal/dom/spi/RpcRoutingStrategy.java | 17 ++++++---- .../mdsal/dom/spi/RpcRoutingStrategyTest.java | 14 ++++----- 8 files changed, 43 insertions(+), 53 deletions(-) diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/RpcServiceAdapter.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/RpcServiceAdapter.java index 5c2ab06080..f0023fa185 100644 --- a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/RpcServiceAdapter.java +++ b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/RpcServiceAdapter.java @@ -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); } diff --git a/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/DOMRpcRoutingTable.java b/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/DOMRpcRoutingTable.java index 62903f20ed..af9bb33b1b 100644 --- a/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/DOMRpcRoutingTable.java +++ b/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/DOMRpcRoutingTable.java @@ -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 { @@ -56,32 +55,26 @@ final class DOMRpcRoutingTable extends AbstractDOMRoutingTable> 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); } } diff --git a/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/GlobalDOMRpcRoutingTableEntry.java b/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/GlobalDOMRpcRoutingTableEntry.java index cf7e6215db..86269b2fe2 100644 --- a/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/GlobalDOMRpcRoutingTableEntry.java +++ b/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/GlobalDOMRpcRoutingTableEntry.java @@ -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> impls) { - super(DOMRpcIdentifier.create(def.getQName()), impls); + super(DOMRpcIdentifier.create(rpcName), impls); } @Override diff --git a/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/RoutedDOMRpcRoutingTableEntry.java b/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/RoutedDOMRpcRoutingTableEntry.java index bfea5534ac..a8f7a6e1c5 100644 --- a/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/RoutedDOMRpcRoutingTableEntry.java +++ b/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/RoutedDOMRpcRoutingTableEntry.java @@ -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> impls) { - super(DOMRpcIdentifier.create(def.getQName(), keyId), impls); + super(DOMRpcIdentifier.create(rpcName, keyId), impls); } @Override diff --git a/dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/GlobalDOMRpcRoutingTableEntryTest.java b/dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/GlobalDOMRpcRoutingTableEntryTest.java index 22c76ab2d7..250cdb9d2f 100644 --- a/dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/GlobalDOMRpcRoutingTableEntryTest.java +++ b/dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/GlobalDOMRpcRoutingTableEntryTest.java @@ -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> rpcImplementations = new HashMap<>(); final List 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)); } diff --git a/dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/RoutedDOMRpcRoutingTableEntryTest.java b/dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/RoutedDOMRpcRoutingTableEntryTest.java index 5c82e1bc0a..b7ddbe4a41 100644 --- a/dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/RoutedDOMRpcRoutingTableEntryTest.java +++ b/dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/RoutedDOMRpcRoutingTableEntryTest.java @@ -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 diff --git a/dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/RpcRoutingStrategy.java b/dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/RpcRoutingStrategy.java index d724e87f71..f352893a57 100644 --- a/dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/RpcRoutingStrategy.java +++ b/dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/RpcRoutingStrategy.java @@ -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 { @@ -52,18 +52,23 @@ public abstract sealed class RpcRoutingStrategy implements Identifiable { */ 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 { diff --git a/dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/RpcRoutingStrategyTest.java b/dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/RpcRoutingStrategyTest.java index 1a2f89560e..07bebbd34a 100644 --- a/dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/RpcRoutingStrategyTest.java +++ b/dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/RpcRoutingStrategyTest.java @@ -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 RPCS; + private static List 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 -- 2.36.6