Unify RPC input serialization 65/103365/2
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 24 Nov 2022 19:28:36 +0000 (20:28 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 24 Nov 2022 19:31:28 +0000 (20:31 +0100)
We know the expected RPC QName, hence we can share code between the
two implementations.

Change-Id: I9e071d329b441509a6747495ab6d9d3573796ff5
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/AbstractDOMRpcImplementationAdapter.java
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMRpcImplementationAdapter.java
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/LegacyDOMRpcImplementationAdapter.java

index 09e48806de0d8ac135c3640c275d2cdd70fb18e2..7ba4a03eeefe5ed849eb1beeb02a67a557512a0d 100644 (file)
@@ -7,22 +7,31 @@
  */
 package org.opendaylight.mdsal.binding.dom.adapter;
 
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Verify.verifyNotNull;
 import static java.util.Objects.requireNonNull;
+import static org.opendaylight.mdsal.binding.dom.adapter.StaticConfiguration.ENABLE_CODEC_SHORTCUT;
 
 import com.google.common.util.concurrent.ListenableFuture;
 import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingLazyContainerNode;
 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.binding.DataObject;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
 
 abstract sealed class AbstractDOMRpcImplementationAdapter implements DOMRpcImplementation
         permits BindingDOMRpcImplementationAdapter, LegacyDOMRpcImplementationAdapter {
     private final AdapterContext adapterContext;
+    private final @NonNull QName inputName;
 
-    AbstractDOMRpcImplementationAdapter(final AdapterContext adapterContext) {
+    AbstractDOMRpcImplementationAdapter(final AdapterContext adapterContext, @NonNull QName inputName) {
         this.adapterContext = requireNonNull(adapterContext);
+        this.inputName = requireNonNull(inputName);
     }
 
     @Override
@@ -37,6 +46,24 @@ abstract sealed class AbstractDOMRpcImplementationAdapter implements DOMRpcImple
         return LazyDOMRpcResultFuture.create(serializer, invokeRpc(serializer, rpc, input));
     }
 
-    abstract @NonNull ListenableFuture<RpcResult<?>> invokeRpc(CurrentAdapterSerializer serializer,
-        DOMRpcIdentifier rpc, ContainerNode input);
+    abstract @NonNull ListenableFuture<RpcResult<?>> invokeRpc(@NonNull CurrentAdapterSerializer serializer,
+        @NonNull DOMRpcIdentifier rpc, @NonNull ContainerNode input);
+
+    final @NonNull DataObject deserialize(final @NonNull CurrentAdapterSerializer serializer,
+            final @NonNull QName rpcName, final @NonNull ContainerNode input) {
+        if (ENABLE_CODEC_SHORTCUT && input instanceof BindingLazyContainerNode<?> lazy) {
+            return lazy.getDataObject();
+        }
+
+        // TODO: this is a bit inefficient: typically we get the same CurrentAdapterSerializer and the path is also
+        //       constant, hence we should be able to cache this lookup and just have the appropriate
+        //       BindingDataObjectCodecTreeNode and reuse it directly
+        checkArgument(inputName.equals(input.getIdentifier().getNodeType()),
+            "Unexpected RPC %s input %s", rpcName, input);
+        // TODO: this is a bit inefficient: typically we get the same CurrentAdapterSerializer and the path is also
+        //       constant, hence we should be able to cache this lookup and just have the appropriate
+        //       BindingDataObjectCodecTreeNode and reuse it directly
+        // FIXME: should be a guaranteed return, as innput is @NonNull
+        return verifyNotNull(serializer.fromNormalizedNodeRpcData(Absolute.of(rpcName, inputName), input));
+    }
 }
index 2f44a2d28fd2f40b2dcb66163fce413b8dffbfd9..a24ebdfdf06958383018d6d2694c46a3d0af146a 100644 (file)
@@ -7,53 +7,33 @@
  */
 package org.opendaylight.mdsal.binding.dom.adapter;
 
-import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Objects.requireNonNull;
-import static org.opendaylight.mdsal.binding.dom.adapter.StaticConfiguration.ENABLE_CODEC_SHORTCUT;
 
 import com.google.common.util.concurrent.ListenableFuture;
 import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.binding.dom.codec.api.BindingLazyContainerNode;
 import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.Rpc;
 import org.opendaylight.yangtools.yang.binding.RpcInput;
 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.model.api.stmt.SchemaNodeIdentifier.Absolute;
 
 final class BindingDOMRpcImplementationAdapter extends AbstractDOMRpcImplementationAdapter {
     private final @NonNull Rpc<?, ?> delegate;
     private final @NonNull QName rpcName;
-    private final @NonNull QName inputName;
 
     BindingDOMRpcImplementationAdapter(final AdapterContext adapterContext, final Rpc<?, ?> delegate,
             final QName rpcName) {
-        super(adapterContext);
+        super(adapterContext, YangConstants.operationInputQName(rpcName.getModule()).intern());
         this.delegate = requireNonNull(delegate);
         this.rpcName = requireNonNull(rpcName);
-        inputName = YangConstants.operationInputQName(rpcName.getModule()).intern();
     }
 
     @Override
     ListenableFuture<RpcResult<?>> invokeRpc(final CurrentAdapterSerializer serializer, final DOMRpcIdentifier rpc,
             final ContainerNode input) {
-        final var bindingInput = input != null ? deserialize(serializer, input) : null;
+        final var bindingInput = input != null ? deserialize(serializer, rpcName, input) : null;
         return ((Rpc) delegate).invoke((RpcInput) bindingInput);
     }
-
-    private DataObject deserialize(final CurrentAdapterSerializer serializer, final ContainerNode input) {
-        if (ENABLE_CODEC_SHORTCUT && input instanceof BindingLazyContainerNode<?> lazy) {
-            return lazy.getDataObject();
-        }
-
-        // TODO: this is a bit inefficient: typically we get the same CurrentAdapterSerializer and the path is also
-        //       constant, hence we should be able to cache this lookup and just have the appropriate
-        //       BindingDataObjectCodecTreeNode and reuse it directly
-        checkArgument(inputName.equals(input.getIdentifier().getNodeType()),
-            "Unexpected RPC %s input %s", rpcName, input);
-        return serializer.fromNormalizedNodeRpcData(Absolute.of(rpcName, inputName), input);
-    }
 }
index 77ae2529ab75e75f0dc4167834947ab161680d10..0ecedfdc8f8f23ac08e2e34463f0e8c827af95b1 100644 (file)
@@ -7,9 +7,7 @@
  */
 package org.opendaylight.mdsal.binding.dom.adapter;
 
-import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Objects.requireNonNull;
-import static org.opendaylight.mdsal.binding.dom.adapter.StaticConfiguration.ENABLE_CODEC_SHORTCUT;
 
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
@@ -18,16 +16,13 @@ import java.lang.reflect.Method;
 import java.util.Map;
 import java.util.concurrent.ExecutionException;
 import org.opendaylight.mdsal.binding.dom.adapter.invoke.RpcServiceInvoker;
-import org.opendaylight.mdsal.binding.dom.codec.api.BindingLazyContainerNode;
 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
 import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 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.model.api.stmt.SchemaNodeIdentifier.Absolute;
 
 @Deprecated(since = "11.0.0", forRemoval = true)
 final class LegacyDOMRpcImplementationAdapter<T extends RpcService> extends AbstractDOMRpcImplementationAdapter {
@@ -36,11 +31,11 @@ final class LegacyDOMRpcImplementationAdapter<T extends RpcService> extends Abst
 
     private final RpcServiceInvoker invoker;
     private final T delegate;
-    private final QName inputQname;
 
     LegacyDOMRpcImplementationAdapter(final AdapterContext adapterContext, final Class<T> type,
             final Map<QName, Method> localNameToMethod, final T delegate) {
-        super(adapterContext);
+        // FIXME: do not use BindingReflections here
+        super(adapterContext, YangConstants.operationInputQName(BindingReflections.getQNameModule(type)).intern());
 
         try {
             invoker = SERVICE_INVOKERS.get(type, () -> RpcServiceInvoker.from(localNameToMethod));
@@ -49,25 +44,13 @@ final class LegacyDOMRpcImplementationAdapter<T extends RpcService> extends Abst
         }
 
         this.delegate = requireNonNull(delegate);
-        inputQname = YangConstants.operationInputQName(BindingReflections.getQNameModule(type)).intern();
     }
 
     @Override
     ListenableFuture<RpcResult<?>> invokeRpc(final CurrentAdapterSerializer serializer, final DOMRpcIdentifier rpc,
             final ContainerNode input) {
         final QName rpcType = rpc.getType();
-        final DataObject bindingInput = input != null ? deserialize(serializer, rpcType, input) : null;
+        final var bindingInput = input != null ? deserialize(serializer, rpcType, input) : null;
         return invoker.invokeRpc(delegate, rpcType, bindingInput);
     }
-
-    private DataObject deserialize(final CurrentAdapterSerializer serializer, final QName rpcType,
-            final ContainerNode input) {
-        if (ENABLE_CODEC_SHORTCUT && input instanceof BindingLazyContainerNode) {
-            return ((BindingLazyContainerNode<?>) input).getDataObject();
-        }
-
-        checkArgument(inputQname.equals(input.getIdentifier().getNodeType()),
-            "Unexpected RPC %s input %s", rpcType, input);
-        return serializer.fromNormalizedNodeRpcData(Absolute.of(rpcType, inputQname), input);
-    }
 }