Generate fields for all Identityrefs in an Union binding class 63/100863/15
authorOleksandrZharov <Oleksandr.Zharov@pantheon.tech>
Thu, 28 Apr 2022 11:47:27 +0000 (13:47 +0200)
committerRobert Varga <nite@hq.sk>
Mon, 13 Jun 2022 13:22:41 +0000 (13:22 +0000)
Changed property name in generator for identityrefs so it will
generate variable names based on type of identityref and not
identityref_ like was before. With that it will generate fields
for all identityrefs that we have in union and methods for them.

Updated related test and added another one to cover the change.

JIRA: MDSAL-740
Change-Id: I11735655ab407f37774cb1b5ffa61955abaee37c
Signed-off-by: OleksandrZharov <Oleksandr.Zharov@pantheon.tech>
Signed-off-by: Tibor Král <tibor.kral@pantheon.tech>
binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/impl/UnionTypeWithMultipleIdentityrefsTest.java [new file with mode: 0644]
binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/AbstractTypeObjectGenerator.java
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/UnionWithIdentityrefTest.java
binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/UnionWithMultipleIdentityrefsTest.java [new file with mode: 0644]
binding/mdsal-binding-java-api-generator/src/test/resources/compilation/union-with-multiple-identityrefs/union-with-multi-identityrefs.yang [new file with mode: 0644]
binding/mdsal-binding-test-model/src/main/yang/union-with-multiple-identityrefs.yang [new file with mode: 0644]

diff --git a/binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/impl/UnionTypeWithMultipleIdentityrefsTest.java b/binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/impl/UnionTypeWithMultipleIdentityrefsTest.java
new file mode 100644 (file)
index 0000000..c5a00fa
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2022 PANTHEON.tech s.r.o. 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.binding.dom.codec.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Map;
+import java.util.Optional;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.union.test.rev220428.IdentOne;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.union.test.rev220428.IdentTwo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.union.test.rev220428.Top;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.union.test.rev220428.TopBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.union.test.rev220428.UnionType;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+
+public class UnionTypeWithMultipleIdentityrefsTest extends AbstractBindingCodecTest {
+
+    public static final QName MODULE_QNAME = QName.create("urn:opendaylight:yang:union:test",
+            "2022-04-28", "union-with-multi-identityref");
+    public static final QName TOP_QNAME = QName.create(MODULE_QNAME, "top");
+    public static final QName UNION_LEAF_QNAME = QName.create(TOP_QNAME, "test-union-leaf");
+    public static final QName IDENTITY_ONE_QNAME = QName.create(MODULE_QNAME, "ident-one");
+    public static final QName IDENTITY_TWO_QNAME = QName.create(MODULE_QNAME, "ident-two");
+
+
+    @Test
+    public void fromBindingToNNTest() {
+        verifyIdentityWasTranslatedToNNCorrectly(new UnionType(IdentOne.VALUE), IdentOne.QNAME);
+        verifyIdentityWasTranslatedToNNCorrectly(new UnionType(IdentTwo.VALUE), IdentTwo.QNAME);
+    }
+
+    @Test
+    public void fromNNToBindingTest() throws NoSuchFieldException {
+        verifyIdentityWasTranslatedToBindingCorrectly(IDENTITY_ONE_QNAME, new UnionType(IdentOne.VALUE));
+        verifyIdentityWasTranslatedToBindingCorrectly(IDENTITY_TWO_QNAME, new UnionType(IdentTwo.VALUE));
+    }
+
+    @Test
+    public void bindingToNNAndBackAgain() {
+        final Top topIdentOne = new TopBuilder().setTestUnionLeaf(new UnionType(IdentOne.VALUE)).build();
+        final Top topIdentOneReturned = thereAndBackAgain(InstanceIdentifier.builder(Top.class).build(), topIdentOne);
+        assertNull(topIdentOneReturned.getTestUnionLeaf().getIdentTwo());
+        assertEquals(topIdentOneReturned.getTestUnionLeaf().getIdentOne().implementedInterface(), IdentOne.class);
+        final Top topIdentTwo = new TopBuilder().setTestUnionLeaf(new UnionType(IdentTwo.VALUE)).build();
+        final Top topIdentTwoReturned = thereAndBackAgain(InstanceIdentifier.builder(Top.class).build(), topIdentTwo);
+        assertNull(topIdentTwoReturned.getTestUnionLeaf().getIdentOne());
+        assertEquals(topIdentTwoReturned.getTestUnionLeaf().getIdentTwo().implementedInterface(), IdentTwo.class);
+    }
+
+    private void verifyIdentityWasTranslatedToBindingCorrectly(final QName identityQname, final UnionType union) {
+        final ContainerNode top = Builders.containerBuilder()
+            .withNodeIdentifier(new NodeIdentifier(TOP_QNAME))
+            .withChild(ImmutableNodes.leafNode(NodeIdentifier.create(UNION_LEAF_QNAME), identityQname))
+            .build();
+        final Map.Entry<InstanceIdentifier<?>, DataObject> translated =
+            codecContext.fromNormalizedNode(YangInstanceIdentifier.create(NodeIdentifier.create(TOP_QNAME)), top);
+        assertNotNull(translated);
+        assertNotNull(translated.getValue());
+        assertTrue(translated.getValue() instanceof Top);
+        assertEquals(new TopBuilder().setTestUnionLeaf(union).build(), translated.getValue());
+    }
+
+    private void verifyIdentityWasTranslatedToNNCorrectly(final UnionType chosenIdentity, final QName identityQname) {
+        // create binding instance with identity
+        final Top topContainer = new TopBuilder().setTestUnionLeaf(chosenIdentity).build();
+        // translate via codec into NN
+        final Map.Entry<YangInstanceIdentifier, NormalizedNode> translated =
+            codecContext.toNormalizedNode(InstanceIdentifier.builder(Top.class).build(), topContainer);
+        assertNotNull(translated);
+        // verify translation worked
+        final NormalizedNode translatedNN = translated.getValue();
+        assertNotNull(translatedNN);
+        // verify the union leaf is present
+        Optional<NormalizedNode> leafNodeOpt = NormalizedNodes.findNode(translatedNN,
+            NodeIdentifier.create(UNION_LEAF_QNAME));
+        assertTrue(leafNodeOpt.isPresent());
+        // verify the leaf is the correct identity
+        assertEquals(identityQname, leafNodeOpt.get().body());
+    }
+}
index d99977dbea8d60b441f445e598cdc7d1d610b2c1..2ba6783367bb5c05f00bf19aeaaf4dc827558169 100644 (file)
@@ -11,6 +11,7 @@ import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Verify.verify;
 import static com.google.common.base.Verify.verifyNotNull;
 
+import com.google.common.base.VerifyException;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
 import java.util.ArrayList;
@@ -729,6 +730,10 @@ abstract class AbstractTypeObjectGenerator<S extends EffectiveStatement<?, ?>, R
                     builder.addEnclosingTransferObject(subBits);
                     generatedType = subBits;
                 } else if (TypeDefinitions.IDENTITYREF.equals(subName)) {
+                    propSource = stmt.findFirstEffectiveSubstatement(BaseEffectiveStatement.class)
+                        .orElseThrow(() -> new VerifyException(String.format("Invalid identityref "
+                            + "definition %s in %s, missing BASE statement", stmt, definingStatement)))
+                        .argument().getLocalName();
                     generatedType = verifyNotNull(dependencies.identityTypes.get(stmt),
                         "Cannot resolve identityref %s in %s", stmt, definingStatement)
                         .methodReturnType(builderFactory);
index 9555718976a49ad2c0ddf29458275fc89d172818..11dc334b5cf281e6ad465ba1ace29f5fa8c9580b 100644 (file)
@@ -52,7 +52,7 @@ public class UnionWithIdentityrefTest extends BaseCompilationTest {
         Object actualUint8 = getUint8.invoke(unionType);
         assertNull(actualUint8);
 
-        Method getIdentityref = unionTypeClass.getDeclaredMethod("getIdentityref");
+        Method getIdentityref = unionTypeClass.getDeclaredMethod("getIdentBase");
         Object actualIdentityref = getIdentityref.invoke(unionType);
         assertEquals(identOneValue, actualIdentityref);
 
diff --git a/binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/UnionWithMultipleIdentityrefsTest.java b/binding/mdsal-binding-java-api-generator/src/test/java/org/opendaylight/mdsal/binding/java/api/generator/UnionWithMultipleIdentityrefsTest.java
new file mode 100644 (file)
index 0000000..09f7ddb
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2022 PANTHEON.tech s.r.o. 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.binding.java.api.generator;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import org.junit.Test;
+import org.opendaylight.mdsal.binding.spec.naming.BindingMapping;
+
+public class UnionWithMultipleIdentityrefsTest extends BaseCompilationTest {
+    @Test
+    public void test() throws Exception {
+        final File sourcesOutputDir = CompilationTestUtils.generatorOutput("union-with-multiple-identityrefs");
+        final File compiledOutputDir = CompilationTestUtils.compilerOutput("union-with-multiple-identityrefs");
+        generateTestSources("/compilation/union-with-multiple-identityrefs", sourcesOutputDir);
+
+        // Test if sources are compilable
+        CompilationTestUtils.testCompilation(sourcesOutputDir, compiledOutputDir);
+
+        ClassLoader loader = new URLClassLoader(new URL[] { compiledOutputDir.toURI().toURL() });
+        Class<?> identOneClass = Class.forName(CompilationTestUtils.BASE_PKG
+                + ".urn.opendaylight.yang.union.test.rev220428.IdentOne", true, loader);
+        Class<?> identTwoClass = Class.forName(CompilationTestUtils.BASE_PKG
+                + ".urn.opendaylight.yang.union.test.rev220428.IdentTwo", true, loader);
+        Class<?> unionTypeClass = Class.forName(CompilationTestUtils.BASE_PKG
+                + ".urn.opendaylight.yang.union.test.rev220428.UnionType", true, loader);
+
+        Object identOneValue = identOneClass.getDeclaredField(BindingMapping.VALUE_STATIC_FIELD_NAME).get(null);
+        Object identTwoValue = identTwoClass.getDeclaredField(BindingMapping.VALUE_STATIC_FIELD_NAME).get(null);
+
+        Constructor<?> unionTypeIdentOneConstructor = CompilationTestUtils.assertContainsConstructor(unionTypeClass,
+                identOneClass);
+        Constructor<?> unionTypeIdentTwoConstructor = CompilationTestUtils.assertContainsConstructor(unionTypeClass,
+                identTwoClass);
+        Object unionTypeOne = unionTypeIdentOneConstructor.newInstance(identOneValue);
+        Object unionTypeTwo = unionTypeIdentTwoConstructor.newInstance(identTwoValue);
+
+        Method getIdentityOne = unionTypeClass.getDeclaredMethod("getIdentOne");
+        Object actualIdentityOne = getIdentityOne.invoke(unionTypeOne);
+        assertEquals(identOneValue, actualIdentityOne);
+
+        Method getIdentityTwo = unionTypeClass.getDeclaredMethod("getIdentTwo");
+        Object actualIdentityTwo = getIdentityTwo.invoke(unionTypeTwo);
+        assertEquals(identTwoValue, actualIdentityTwo);
+
+        CompilationTestUtils.cleanUp(sourcesOutputDir, compiledOutputDir);
+    }
+}
diff --git a/binding/mdsal-binding-java-api-generator/src/test/resources/compilation/union-with-multiple-identityrefs/union-with-multi-identityrefs.yang b/binding/mdsal-binding-java-api-generator/src/test/resources/compilation/union-with-multiple-identityrefs/union-with-multi-identityrefs.yang
new file mode 100644 (file)
index 0000000..9aee962
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2022 PANTHEON.tech s.r.o. 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
+ */
+
+module union-with-multi-identityref {
+  yang-version 1;
+  namespace "urn:opendaylight:yang:union:test";
+  prefix "uniontest";
+
+  description "test union with multiple identityref";
+
+  revision "2022-04-28";
+
+  identity ident-one;
+  identity ident-two;
+
+  typedef union-type {
+    type union {
+      type identityref {
+        base ident-one;
+      }
+      type identityref {
+        base ident-two;
+      }
+    }
+  }
+
+  leaf test-union-leaf{
+    type union-type;
+  }
+}
\ No newline at end of file
diff --git a/binding/mdsal-binding-test-model/src/main/yang/union-with-multiple-identityrefs.yang b/binding/mdsal-binding-test-model/src/main/yang/union-with-multiple-identityrefs.yang
new file mode 100644 (file)
index 0000000..44763c3
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2022 PANTHEON.tech s.r.o. 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
+ */
+
+module union-with-multi-identityref {
+  yang-version 1;
+  namespace "urn:opendaylight:yang:union:test";
+  prefix "uniontest";
+
+  description "test union with multiple identityref";
+
+  revision "2022-04-28";
+
+  identity ident-one;
+  identity ident-two;
+
+  typedef union-type {
+    type union {
+      type identityref {
+        base ident-one;
+      }
+      type identityref {
+        base ident-two;
+      }
+    }
+  }
+
+  container top {
+    leaf test-union-leaf{
+        type union-type;
+      }
+  }
+}
\ No newline at end of file