Use schemaTreeChild() to lookup input/output 59/109359/3
authorRobert Varga <robert.varga@pantheon.tech>
Sat, 16 Dec 2023 20:55:17 +0000 (21:55 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Sun, 17 Dec 2023 01:05:23 +0000 (02:05 +0100)
We have proper RpcRuntimeType, hence we can follow along the schema tree
axis to obtain the runtime types for RPC input/output.

Change-Id: Iea34601edc340b788fc3ee4e17c5da7e245734b7
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/BindingCodecContext.java
binding/mdsal-binding-runtime-api/src/main/java/org/opendaylight/mdsal/binding/runtime/api/AbstractBindingRuntimeContext.java

index 82ba6fac4d6649090eaa7a3127e9240254d0a5d1..08997deaf3537cc4e48645d2a4422ce129c458eb 100644 (file)
@@ -38,7 +38,7 @@ import java.util.Map.Entry;
 import java.util.Optional;
 import java.util.ServiceLoader;
 import java.util.concurrent.ExecutionException;
-import java.util.function.BiFunction;
+import java.util.function.Function;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.kohsuke.MetaInfServices;
@@ -59,13 +59,13 @@ import org.opendaylight.mdsal.binding.loader.BindingClassLoader;
 import org.opendaylight.mdsal.binding.model.api.JavaTypeName;
 import org.opendaylight.mdsal.binding.runtime.api.ActionRuntimeType;
 import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext;
-import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeTypes;
 import org.opendaylight.mdsal.binding.runtime.api.ChoiceRuntimeType;
 import org.opendaylight.mdsal.binding.runtime.api.ContainerLikeRuntimeType;
 import org.opendaylight.mdsal.binding.runtime.api.ContainerRuntimeType;
 import org.opendaylight.mdsal.binding.runtime.api.DataRuntimeType;
 import org.opendaylight.mdsal.binding.runtime.api.ListRuntimeType;
 import org.opendaylight.mdsal.binding.runtime.api.NotificationRuntimeType;
+import org.opendaylight.mdsal.binding.runtime.api.RpcRuntimeType;
 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.util.ClassLoaderUtils;
@@ -303,11 +303,11 @@ public final class BindingCodecContext extends AbstractBindingNormalizedNodeSeri
         CacheBuilder.newBuilder().build(new CacheLoader<>() {
             @Override
             public ContainerLikeCodecContext<?> load(final Class<?> key) {
-                final BiFunction<BindingRuntimeTypes, QName, Optional<? extends ContainerLikeRuntimeType<?, ?>>> lookup;
+                final Function<RpcRuntimeType, ContainerLikeRuntimeType<?, ?>> lookup;
                 if (RpcInput.class.isAssignableFrom(key)) {
-                    lookup = BindingRuntimeTypes::findRpcInput;
+                    lookup = RpcRuntimeType::input;
                 } else if (RpcOutput.class.isAssignableFrom(key)) {
-                    lookup = BindingRuntimeTypes::findRpcOutput;
+                    lookup = RpcRuntimeType::output;
                 } else {
                     throw new IllegalArgumentException(key + " does not represent an RPC container");
                 }
@@ -331,11 +331,12 @@ public final class BindingCodecContext extends AbstractBindingNormalizedNodeSeri
                         final ContainerLike schema = getRpcDataSchema(potential, qname);
                         checkArgument(schema != null, "Schema for %s does not define input / output.", potentialQName);
 
-                        final var type = lookup.apply(context.getTypes(), potentialQName)
-                            .orElseThrow(() -> new IllegalArgumentException("Cannot find runtime type for " + key));
-
-                        // FIXME: accurate type
-                        return new ContainerLikeCodecContext(key, type, BindingCodecContext.this);
+                        final var runtimeType = context.getTypes().schemaTreeChild(potentialQName);
+                        if (runtimeType instanceof RpcRuntimeType rpcType) {
+                            // FIXME: accurate type
+                            return new ContainerLikeCodecContext(key, lookup.apply(rpcType), BindingCodecContext.this);
+                        }
+                        throw new IllegalArgumentException("Cannot find runtime type for " + key);
                     }
                 }
 
index 6b22a84432c9c59ab7178a21cb26970750cedad9..bf0dc18a1de77c4392c859b2b8e247dbd45fdf64 100644 (file)
@@ -105,16 +105,19 @@ public abstract class AbstractBindingRuntimeContext implements BindingRuntimeCon
 
     @Override
     public final Class<? extends RpcInput> getRpcInput(final QName rpcName) {
-        return loadClass(getTypes().findRpcInput(rpcName)
-            .orElseThrow(() -> new IllegalArgumentException("Failed to find RpcInput for " + rpcName)))
-            .asSubclass(RpcInput.class);
+        return loadClass(getRpc(rpcName).input()).asSubclass(RpcInput.class);
     }
 
     @Override
     public final Class<? extends RpcOutput> getRpcOutput(final QName rpcName) {
-        return loadClass(getTypes().findRpcOutput(rpcName)
-            .orElseThrow(() -> new IllegalArgumentException("Failed to find RpcOutput for " + rpcName)))
-            .asSubclass(RpcOutput.class);
+        return loadClass(getRpc(rpcName).output()).asSubclass(RpcOutput.class);
+    }
+
+    private @NonNull RpcRuntimeType getRpc(final QName rpcName) {
+        if (getTypes().schemaTreeChild(rpcName) instanceof RpcRuntimeType rpc) {
+            return rpc;
+        }
+        throw new IllegalArgumentException("Failed to find RPC for " + rpcName);
     }
 
     @Override