From 60b826353c654c51febfbfdac5fbb65544ee0d24 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Mon, 21 Nov 2022 19:47:31 +0100 Subject: [PATCH] Refactor RpcRoutingStrategy RpcRoutingStrategy is not really a nice construct -- it essentially extracts context information, not much more. As such, dealing with two subclasses is a drag. Intruduce ContentRoutedRpcContext to capture the interesting information in a record and adjust users to deal with the fact that normal RPCs do not have this construct. Change-Id: I2c8d24a61e6905063c9eb93fb0513dffe4831b66 Signed-off-by: Robert Varga --- .../dom/adapter/RpcServiceAdapter.java | 10 +- .../mdsal/dom/broker/DOMRpcRoutingTable.java | 11 +- .../dom/spi/ContentRoutedRpcContext.java | 58 +++++++++ .../mdsal/dom/spi/RpcRoutingStrategy.java | 120 ------------------ ....java => ContentRoutedRpcContextTest.java} | 32 ++--- 5 files changed, 77 insertions(+), 154 deletions(-) create mode 100644 dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/ContentRoutedRpcContext.java delete mode 100644 dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/RpcRoutingStrategy.java rename dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/{RpcRoutingStrategyTest.java => ContentRoutedRpcContextTest.java} (53%) 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 f0023fa185..9e7bbc367d 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 @@ -27,7 +27,7 @@ import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSeriali import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections; import org.opendaylight.mdsal.dom.api.DOMRpcResult; import org.opendaylight.mdsal.dom.api.DOMRpcService; -import org.opendaylight.mdsal.dom.spi.RpcRoutingStrategy; +import org.opendaylight.mdsal.dom.spi.ContentRoutedRpcContext; import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -68,10 +68,10 @@ class RpcServiceAdapter implements InvocationHandler { } private RpcInvocationStrategy createStrategy(final Method method, final RpcDefinition schema) { - final QName rpcType = schema.getQName(); - final RpcRoutingStrategy strategy = RpcRoutingStrategy.from(schema.asEffectiveStatement()); - return strategy.isContextBasedRouted() ? new RoutedStrategy(rpcType, method, strategy.getLeaf()) - : new NonRoutedStrategy(rpcType); + final var rpcName = schema.getQName(); + final var contentContext = ContentRoutedRpcContext.forRpc(schema.asEffectiveStatement()); + return contentContext == null ? new NonRoutedStrategy(rpcName) + : new RoutedStrategy(rpcName, method, contentContext.leaf()); } RpcService getProxy() { 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 af9bb33b1b..495b040eff 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 @@ -17,7 +17,7 @@ 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; -import org.opendaylight.mdsal.dom.spi.RpcRoutingStrategy; +import org.opendaylight.mdsal.dom.spi.ContentRoutedRpcContext; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; @@ -60,13 +60,10 @@ final class DOMRpcRoutingTable extends AbstractDOMRoutingTable new IllegalArgumentException("Cannot find input in " + rpc)); + + for (var stmt : input.effectiveSubstatements()) { + // TODO: LeafEffectiveStatement instead? Because that is what we are promising for #leaf()'s QName + if (stmt instanceof SchemaTreeEffectiveStatement schemaStmt) { + final var context = + stmt.findFirstEffectiveSubstatementArgument(ContextReferenceEffectiveStatement.class); + if (context.isPresent()) { + return new ContentRoutedRpcContext(context.orElseThrow(), schemaStmt.argument()); + } + } + } + + return null; + } +} 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 deleted file mode 100644 index f352893a57..0000000000 --- a/dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/RpcRoutingStrategy.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2014 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.dom.spi; - -import static java.util.Objects.requireNonNull; - -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.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 { - private final @NonNull QName identifier; - - private RpcRoutingStrategy(final QName identifier) { - this.identifier = requireNonNull(identifier); - } - - /** - * Returns leaf QName in which RPC Route is stored. - * @return leaf QName in which RPC Route is stored - * @throws UnsupportedOperationException If RPC is not content routed. - * ({@link #isContextBasedRouted()} returned false) - */ - public abstract QName getLeaf(); - - /** - * Returns identity QName which represents RPC Routing context. - * @return identity QName which represents RPC Routing context - * @throws UnsupportedOperationException If RPC is not content routed. - * ({@link #isContextBasedRouted()} returned false) - */ - public abstract QName getContext(); - - @Override - public final QName getIdentifier() { - return identifier; - } - - /** - * Returns true if RPC is routed by context. - * - * @return true if RPC is routed by content. - */ - public abstract boolean isContextBasedRouted(); - - public static @NonNull RpcRoutingStrategy from(final RpcEffectiveStatement rpc) { - // FIXME: deprecate context-reference - 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(rpcName, context.orElseThrow(), schemaStmt.argument()); - } - } - } - return new GlobalRpcStrategy(rpcName); - } - - private static final class RoutedRpcStrategy extends RpcRoutingStrategy { - private final QName context; - private final QName leaf; - - private RoutedRpcStrategy(final QName identifier, final QName ctx, final QName leaf) { - super(identifier); - context = requireNonNull(ctx); - this.leaf = requireNonNull(leaf); - } - - @Override - public QName getContext() { - return context; - } - - @Override - public QName getLeaf() { - return leaf; - } - - @Override - public boolean isContextBasedRouted() { - return true; - } - } - - private static final class GlobalRpcStrategy extends RpcRoutingStrategy { - GlobalRpcStrategy(final QName identifier) { - super(identifier); - } - - @Override - public boolean isContextBasedRouted() { - return false; - } - - @Override - public QName getContext() { - throw new UnsupportedOperationException("Non-routed strategy does not have a context"); - } - - @Override - public QName getLeaf() { - throw new UnsupportedOperationException("Non-routed strategy does not have a context"); - } - } -} 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/ContentRoutedRpcContextTest.java similarity index 53% rename from dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/RpcRoutingStrategyTest.java rename to dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/ContentRoutedRpcContextTest.java index 07bebbd34a..be1b6b3682 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/ContentRoutedRpcContextTest.java @@ -8,12 +8,9 @@ package org.opendaylight.mdsal.dom.spi; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThrows; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertNull; -import com.google.common.collect.Iterables; import java.util.List; import java.util.stream.Collectors; import org.junit.AfterClass; @@ -21,23 +18,22 @@ 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.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 { +public class ContentRoutedRpcContextTest { private static List RPCS; @BeforeClass public static void beforeClass() { - final EffectiveModelContext ctx = YangParserTestUtils.parseYangSources(YangParserConfiguration.DEFAULT, null, + final var ctx = YangParserTestUtils.parseYangSources(YangParserConfiguration.DEFAULT, null, YangTextSchemaSource.delegateForByteSource("yang-ext.yang", $YangModuleInfoImpl.getInstance().getYangTextByteSource()), - YangTextSchemaSource.forResource(RpcRoutingStrategy.class, "/rpc-routing-strategy.yang")); + YangTextSchemaSource.forResource(ContentRoutedRpcContext.class, "/rpc-routing-strategy.yang")); - RPCS = Iterables.getOnlyElement(ctx.findModuleStatements("foo")) + RPCS = ctx.findModuleStatements("foo").iterator().next() .streamEffectiveSubstatements(RpcEffectiveStatement.class) .collect(Collectors.toUnmodifiableList()); } @@ -49,23 +45,15 @@ public class RpcRoutingStrategyTest { @Test public void unroutedRpcStrategyTest() { - final RpcRoutingStrategy strategy = RpcRoutingStrategy.from(Iterables.get(RPCS, 1)); - assertNotNull(strategy); - - assertEquals(QName.create("foo", "unrouted"), strategy.getIdentifier()); - assertFalse(strategy.isContextBasedRouted()); - assertThrows(UnsupportedOperationException.class, () -> strategy.getLeaf()); - assertThrows(UnsupportedOperationException.class, () -> strategy.getContext()); + assertNull(ContentRoutedRpcContext.forRpc(RPCS.get(1))); } @Test public void routedRpcStrategyTest() { - final RpcRoutingStrategy strategy = RpcRoutingStrategy.from(Iterables.get(RPCS, 0)); - assertNotNull(strategy); + final var context = ContentRoutedRpcContext.forRpc(RPCS.get(0)); + assertNotNull(context); - assertEquals(QName.create("foo", "routed"), strategy.getIdentifier()); - assertTrue(strategy.isContextBasedRouted()); - assertEquals(QName.create("foo", "identity"), strategy.getContext()); - assertEquals(QName.create("foo", "ctx"), strategy.getLeaf()); + assertEquals(QName.create("foo", "identity"), context.identity()); + assertEquals(QName.create("foo", "ctx"), context.leaf()); } } \ No newline at end of file -- 2.36.6