Break open RpcInvocationStrategy 31/103331/2
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 23 Nov 2022 14:50:00 +0000 (15:50 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 24 Nov 2022 14:35:58 +0000 (15:35 +0100)
Creation of the strategy is inter-twined with ContextReferenceExtractor,
which we want to cache in CurrentAdapterSerializer. Inline creation of
the strategy where we have controlled access to
CurrentAdapterSerializer, with RpcServiceAdapter doing the mediation, so
that we do not pass things around and create a method call tangle.

JIRA: MDSAL-777
Change-Id: I3f092f8ce47d154c84ca821512d1fbfbb65d8673
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/RpcInvocationStrategy.java
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/RpcServiceAdapter.java

index 109f3b56a39c0af1fa2c01f0dd10cdc20405ec57..8a37d5dd0f31c2f70ce21f8d66f228adf1c8a7cb 100644 (file)
@@ -13,13 +13,9 @@ import static org.opendaylight.mdsal.binding.dom.adapter.StaticConfiguration.ENA
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.MoreExecutors;
-import java.lang.reflect.Method;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
-import org.opendaylight.mdsal.binding.runtime.api.RpcRuntimeType;
-import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
 import org.opendaylight.mdsal.dom.api.DOMRpcResult;
-import org.opendaylight.mdsal.dom.spi.ContentRoutedRpcContext;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
@@ -30,7 +26,7 @@ import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
 
 sealed class RpcInvocationStrategy {
-    private static final class ContentRouted extends RpcInvocationStrategy {
+    static final class ContentRouted extends RpcInvocationStrategy {
         private final ContextReferenceExtractor refExtractor;
         private final NodeIdentifier contextName;
 
@@ -59,27 +55,13 @@ sealed class RpcInvocationStrategy {
     private final @NonNull NodeIdentifier inputIdentifier;
     private final @NonNull Absolute outputPath;
 
-    private RpcInvocationStrategy(final RpcServiceAdapter adapter, final QName rpcName) {
+    RpcInvocationStrategy(final RpcServiceAdapter adapter, final QName rpcName) {
         this.adapter = requireNonNull(adapter);
         final var namespace = rpcName.getModule();
         outputPath = Absolute.of(rpcName, YangConstants.operationOutputQName(namespace).intern()).intern();
         inputIdentifier = NodeIdentifier.create(YangConstants.operationInputQName(namespace.intern()));
     }
 
-    static @NonNull RpcInvocationStrategy of(final RpcServiceAdapter adapter, final Method method,
-            final RpcRuntimeType type) {
-        final var schema = type.statement();
-        final var contentContext = ContentRoutedRpcContext.forRpc(schema);
-        if (contentContext == null) {
-            return new RpcInvocationStrategy(adapter, schema.argument());
-        }
-
-        return new ContentRouted(adapter, schema.argument(), contentContext.leaf(), ContextReferenceExtractor.from(
-            // FIXME: do not use BindingReflections here
-            BindingReflections.resolveRpcInputClass(method).orElseThrow(
-                () -> new IllegalArgumentException("RPC method " + method.getName() + " has no input"))));
-    }
-
     final ListenableFuture<RpcResult<?>> invoke(final DataObject input) {
         return invoke(serialize(inputIdentifier, adapter.currentSerializer(), input));
     }
index 4d4b03937ae0fcbf230dc9ffa89bbeafdeb668f4..7fecffadce5e75cd44c35a193f88c9bc303692e8 100644 (file)
@@ -16,10 +16,12 @@ import java.lang.reflect.Proxy;
 import java.util.Map;
 import java.util.Map.Entry;
 import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.mdsal.binding.dom.adapter.RpcInvocationStrategy.ContentRouted;
 import org.opendaylight.mdsal.binding.runtime.api.RpcRuntimeType;
 import org.opendaylight.mdsal.binding.spec.naming.BindingMapping;
 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
 import org.opendaylight.mdsal.dom.api.DOMRpcService;
+import org.opendaylight.mdsal.dom.spi.ContentRoutedRpcContext;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 import org.opendaylight.yangtools.yang.model.api.stmt.RpcEffectiveStatement;
@@ -67,7 +69,18 @@ class RpcServiceAdapter implements InvocationHandler {
                     throw new IllegalStateException("Unexpected run-time type " + runtimeType + " for " + rpcName);
                 }
 
-                return Map.entry(method, RpcInvocationStrategy.of(this, method, rpcType));
+                final var contentContext = ContentRoutedRpcContext.forRpc(rpc);
+                final RpcInvocationStrategy strategy;
+                if (contentContext != null) {
+                    strategy = new ContentRouted(this, rpcName, contentContext.leaf(), ContextReferenceExtractor.from(
+                        // FIXME: do not use BindingReflections here
+                        BindingReflections.resolveRpcInputClass(method).orElseThrow(
+                            () -> new IllegalArgumentException("RPC method " + method.getName() + " has no input"))));
+                } else {
+                    strategy = new RpcInvocationStrategy(this, rpcName);
+                }
+
+                return Map.entry(method, strategy);
             })
             .collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue));
     }