Fix KeyedListAction serialization 81/76081/8
authorJakub Tóth <jakub.toth@pantheon.tech>
Fri, 14 Sep 2018 08:44:14 +0000 (10:44 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 1 Oct 2018 05:41:31 +0000 (07:41 +0200)
SchemaRootCodecContext needs to understand both Action and
KeyedListAction, as their parameterizations differ.

JIRA: MDSAL-371
Change-Id: I405a73b1a8ca8801ae1786be704cefe674c5fb72
Signed-off-by: Jakub Tóth <jakub.toth@pantheon.tech>
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-dom-codec/src/main/java/org/opendaylight/mdsal/binding/dom/codec/impl/SchemaRootCodecContext.java
binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/test/ActionSerializeDeserializeTest.java
binding/mdsal-binding-test-model/src/main/yang/actions.yang

index f29a111066884f704ee26a00956ccf976d3a49be..d7945db02192dab87fdfa27899e5103a777d5b76 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.mdsal.binding.dom.codec.impl;
 
 import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Verify.verify;
 
 import com.google.common.base.Optional;
@@ -17,6 +18,7 @@ import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
 import com.google.common.util.concurrent.UncheckedExecutionException;
+import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.util.List;
 import org.opendaylight.mdsal.binding.spec.naming.BindingMapping;
@@ -27,6 +29,7 @@ import org.opendaylight.yangtools.yang.binding.ChoiceIn;
 import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedListAction;
 import org.opendaylight.yangtools.yang.binding.Notification;
 import org.opendaylight.yangtools.yang.binding.RpcInput;
 import org.opendaylight.yangtools.yang.binding.RpcOutput;
@@ -206,13 +209,26 @@ final class SchemaRootCodecContext<D extends DataObject> extends DataContainerCo
     }
 
     ActionCodecContext createActionContext(final Class<? extends Action<?, ?, ?>> action) {
-        final Type[] args = ClassLoaderUtils.findParameterizedType(action, Action.class).getActualTypeArguments();
-        checkArgument(args.length == 3, "Unexpected (%s) Action generatic arguments", args.length);
+        if (KeyedListAction.class.isAssignableFrom(action)) {
+            return prepareActionContext(2, 3, 4, action, KeyedListAction.class);
+        } else if (Action.class.isAssignableFrom(action)) {
+            return prepareActionContext(1, 2, 3, action, Action.class);
+        }
+        throw new IllegalArgumentException("The specific action type does not exist for action " + action.getName());
+    }
 
+    private ActionCodecContext prepareActionContext(final int inputOffset, final int outputOffset,
+            final int expectedArgsLength, final Class<? extends Action<?, ?, ?>> action, final Class<?> actionType) {
+        final ParameterizedType paramType = checkNotNull(ClassLoaderUtils.findParameterizedType(action, actionType),
+            "There does not exist any ParameterType in %s", action);
+        final Type[] args = paramType.getActualTypeArguments();
+        checkArgument(args.length == expectedArgsLength, "Unexpected (%s) Action generatic arguments", args.length);
         final ActionDefinition schema = factory().getRuntimeContext().getActionDefinition(action);
         return new ActionCodecContext(
-            DataContainerCodecPrototype.from(asClass(args[1], RpcInput.class), schema.getInput(), factory()).get(),
-            DataContainerCodecPrototype.from(asClass(args[2], RpcOutput.class), schema.getOutput(), factory()).get());
+                DataContainerCodecPrototype.from(asClass(args[inputOffset], RpcInput.class), schema.getInput(),
+                        factory()).get(),
+                DataContainerCodecPrototype.from(asClass(args[outputOffset], RpcOutput.class), schema.getOutput(),
+                        factory()).get());
     }
 
     private static <T extends DataObject> Class<? extends T> asClass(final Type type, final Class<T> target) {
index fb3783d6556afd6d483b2f175986a30d09617a49..05a45d42d1af7b4d311d3f66b89878fc0e69da52 100644 (file)
@@ -18,6 +18,7 @@ import org.opendaylight.yang.gen.v1.urn.odl.actions.norev.cont.Foo;
 import org.opendaylight.yang.gen.v1.urn.odl.actions.norev.cont.foo.InputBuilder;
 import org.opendaylight.yang.gen.v1.urn.odl.actions.norev.cont.foo.OutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.odl.actions.norev.grpcont.Bar;
+import org.opendaylight.yang.gen.v1.urn.odl.actions.norev.lstio.Fooio;
 import org.opendaylight.yangtools.yang.binding.RpcInput;
 import org.opendaylight.yangtools.yang.binding.RpcOutput;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -47,10 +48,25 @@ public class ActionSerializeDeserializeTest extends AbstractBindingCodecTest {
     private static final RpcOutput BINDING_BAR_OUTPUT =
             new org.opendaylight.yang.gen.v1.urn.odl.actions.norev.grp.bar.OutputBuilder().setXyzzy("xyzzy").build();
 
+    private static final NodeIdentifier FOOIO_INPUT = NodeIdentifier.create(operationInputQName(Fooio.QNAME
+            .getModule()));
+    private static final NodeIdentifier FOOIO_OUTPUT = NodeIdentifier.create(operationOutputQName(Fooio.QNAME
+            .getModule()));
+    private static final NodeIdentifier FOOIO_I = NodeIdentifier.create(QName.create(Fooio.QNAME, "fooi"));
+    private static final NodeIdentifier FOOIO_O = NodeIdentifier.create(QName.create(Fooio.QNAME, "fooo"));
+    private static final ContainerNode DOM_FOOIO_INPUT = containerBuilder().withNodeIdentifier(FOOIO_INPUT).withChild(
+            leafBuilder().withNodeIdentifier(FOOIO_I).withValue("ifoo").build()).build();
+    private static final ContainerNode DOM_FOOIO_OUTPUT = containerBuilder().withNodeIdentifier(FOOIO_OUTPUT).withChild(
+            leafBuilder().withNodeIdentifier(FOOIO_O).withValue("ofoo").build()).build();
+    private static final RpcInput BINDING_FOOIO_INPUT =
+            new org.opendaylight.yang.gen.v1.urn.odl.actions.norev.lstio.fooio.InputBuilder().setFooi("ifoo").build();
+    private static final RpcOutput BINDING_FOOIO_OUTPUT =
+            new org.opendaylight.yang.gen.v1.urn.odl.actions.norev.lstio.fooio.OutputBuilder().setFooo("ofoo").build();
+
     @Test
     public void testSerialization() {
         assertEquals(DOM_FOO_INPUT, registry.toLazyNormalizedNodeActionInput(Foo.class, BINDING_FOO_INPUT)
-            .getDelegate());
+                .getDelegate());
         assertEquals(DOM_BAR_INPUT, registry.toLazyNormalizedNodeActionInput(Bar.class, BINDING_BAR_INPUT)
                 .getDelegate());
         assertEquals(DOM_FOO_OUTPUT, registry.toLazyNormalizedNodeActionOutput(Foo.class, BINDING_FOO_OUTPUT)
@@ -59,6 +75,14 @@ public class ActionSerializeDeserializeTest extends AbstractBindingCodecTest {
                 .getDelegate());
     }
 
+    @Test
+    public void testKeyedListActionSerialization() {
+        assertEquals(DOM_FOOIO_INPUT, registry.toLazyNormalizedNodeActionInput(Fooio.class, BINDING_FOOIO_INPUT)
+                .getDelegate());
+        assertEquals(DOM_FOOIO_OUTPUT, registry.toLazyNormalizedNodeActionOutput(Fooio.class, BINDING_FOOIO_OUTPUT)
+                .getDelegate());
+    }
+
     @Test
     public void testDeserialization() {
         assertEquals(BINDING_FOO_INPUT, registry.fromNormalizedNodeActionInput(Foo.class, DOM_FOO_INPUT));
@@ -66,4 +90,10 @@ public class ActionSerializeDeserializeTest extends AbstractBindingCodecTest {
         assertEquals(BINDING_FOO_OUTPUT, registry.fromNormalizedNodeActionOutput(Foo.class, DOM_FOO_OUTPUT));
         assertEquals(BINDING_BAR_OUTPUT, registry.fromNormalizedNodeActionOutput(Bar.class, DOM_FOO_INPUT));
     }
+
+    @Test
+    public void testKeyedListActionDeserialization() {
+        assertEquals(BINDING_FOOIO_INPUT, registry.fromNormalizedNodeActionInput(Fooio.class, DOM_FOOIO_INPUT));
+        assertEquals(BINDING_FOOIO_OUTPUT, registry.fromNormalizedNodeActionOutput(Fooio.class, DOM_FOOIO_OUTPUT));
+    }
 }
index 5f2eff6431c86e6610f0de5ca4ea5560be19b461..299519677e63a25983ed3b6bbbdefa3d2182bcf2 100644 (file)
@@ -23,6 +23,25 @@ module actions {
         }
     }
 
+    list lstio {
+        key keyio;
+        leaf keyio {
+            type string;
+        }
+        action fooio {
+            input {
+                leaf fooi {
+                    type string;
+                }
+            }
+            output {
+                leaf fooo {
+                    type string;
+                }
+            }
+        }
+    }
+
     grouping grp {
         action bar {
             output {