From 1193e5695216c2c81e365d53f55b06bb9baf400f Mon Sep 17 00:00:00 2001 From: Jie Han Date: Fri, 9 Feb 2018 16:59:18 +0800 Subject: [PATCH] MDSAL-310 Binding v2 codec - Instance identifier should not reference choice/case. - Since choice and case are not data tree nodes, InstanceIdentifier should not reference choice/case as well as YangInstanceIdentifier. JIRA:MDSAL-310 Change-Id: I881a88bfce337ab3a5d9f2a648cf16ead8214e98 Signed-off-by: Jie Han --- .../impl/context/ChoiceNodeCodecContext.java | 33 ++++++++++- .../context/base/TreeNodeCodecContext.java | 34 +++++++++-- ...nceIdentifierSerializeDeserializeTest.java | 56 +++++++++++++++++++ ...ormalizedNodeSerializeDeserializeTest.java | 36 ++++++++++++ 4 files changed, 153 insertions(+), 6 deletions(-) mode change 100644 => 100755 binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/context/base/TreeNodeCodecContext.java create mode 100644 binding2/mdsal-binding2-dom-codec/src/test/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/InstanceIdentifierSerializeDeserializeTest.java diff --git a/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/context/ChoiceNodeCodecContext.java b/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/context/ChoiceNodeCodecContext.java index ba0c658845..e2c87b5c50 100644 --- a/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/context/ChoiceNodeCodecContext.java +++ b/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/context/ChoiceNodeCodecContext.java @@ -66,6 +66,8 @@ public class ChoiceNodeCodecContext extends DataContainerCod final Map, DataContainerCodecPrototype> byClassBuilder = new HashMap<>(); final Map, DataContainerCodecPrototype> byCaseChildClassBuilder = new HashMap<>(); final Set> potentialSubstitutions = new HashSet<>(); + + //TODO: Collect all choice/cases' descendant data children including augmented data nodes. // Walks all cases for supplied choice in current runtime context for (final Class caze : factory().getRuntimeContext().getCases(getBindingClass())) { // We try to load case using exact match thus name @@ -143,8 +145,35 @@ public class ChoiceNodeCodecContext extends DataContainerCod return Optional.empty(); } - Iterable> getCaseChildrenClasses() { - return byCaseChildClass.keySet(); + + /** + * Gets the map of case class and prototype for {@link + * org.opendaylight.mdsal.binding.javav2.dom.codec.impl.context.base.TreeNodeCodecContext} + * to catch choice/cases' data child by class. + * + * @return the map of case class and prototype + */ + public Map, DataContainerCodecPrototype> getClassCaseChildren() { + return byCaseChildClass; + } + + + /** + * Gets the map of case path argument and prototype for {@link + * org.opendaylight.mdsal.binding.javav2.dom.codec.impl.context.base.TreeNodeCodecContext} + * to catch choice/cases' data child by class. + * + * @return the the map of case path and prototype + */ + public Map> getYangCaseChildren() { + return byYangCaseChild; + } + + public DataContainerCodecContext getCaseByChildClass(final @Nonnull Class type) { + final DataContainerCodecPrototype protoCtx = + childNonNull(byCaseChildClass.get(type), type, "Class %s is not child of any cases for %s", type, + bindingArg()); + return protoCtx.get(); } private DataContainerCodecPrototype loadCase(final Class childClass) { diff --git a/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/context/base/TreeNodeCodecContext.java b/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/context/base/TreeNodeCodecContext.java old mode 100644 new mode 100755 index f14cb3b2fb..c5941d5cd5 --- a/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/context/base/TreeNodeCodecContext.java +++ b/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/context/base/TreeNodeCodecContext.java @@ -32,6 +32,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.context.ChoiceNodeCodecContext; import org.opendaylight.mdsal.binding.javav2.generator.api.ClassLoadingStrategy; import org.opendaylight.mdsal.binding.javav2.model.api.Type; import org.opendaylight.mdsal.binding.javav2.runtime.reflection.BindingReflections; @@ -108,9 +109,17 @@ public abstract class TreeNodeCodecContext choice = (ChoiceNodeCodecContext) childProto.get(); + choice.getClassCaseChildren().entrySet().forEach(entry -> + byBindingArgClassBuilder.put(entry.getKey(), childProto)); + + choice.getYangCaseChildren().entrySet().forEach(entry -> + byYangBuilder.put(entry.getKey(), childProto)); + } } + this.byMethod = ImmutableSortedMap.copyOfSorted(byMethodBuilder); this.byYang = ImmutableMap.copyOf(byYangBuilder); this.byStreamClass = ImmutableMap.copyOf(byStreamClassBuilder); @@ -188,8 +197,15 @@ public abstract class TreeNodeCodecContext context = childNonNull(ctxProto, argType, "Class %s is not valid child of %s", argType, getBindingClass()).get(); - //TODO: get cases in consideration - finish in patches to come -// if (context instanceof ChoiceNodeCodecContext) { + + if (context instanceof ChoiceNodeCodecContext) { + final ChoiceNodeCodecContext choice = (ChoiceNodeCodecContext) context; + final DataContainerCodecContext caze = choice.getCaseByChildClass(argType); + // FIXME: Instance identifier should not reference choice or case as they're + // not data tree nodes. + return caze.bindingPathArgumentChild(arg, builder); + } + context.addYangPathArgument(arg, builder); return context; } @@ -207,6 +223,16 @@ public abstract class TreeNodeCodecContext context = ((DataContainerCodecPrototype) childSupplier).get(); + if (context instanceof ChoiceNodeCodecContext) { + return (NodeCodecContext) childNonNull(((ChoiceNodeCodecContext) context).yangPathArgumentChild(arg), + arg, "Argument %s is not valid child of %s", arg, getSchema()); + } + } + return (NodeCodecContext) childNonNull(childSupplier, arg, "Argument %s is not valid child of %s", arg, getSchema()).get(); } diff --git a/binding2/mdsal-binding2-dom-codec/src/test/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/InstanceIdentifierSerializeDeserializeTest.java b/binding2/mdsal-binding2-dom-codec/src/test/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/InstanceIdentifierSerializeDeserializeTest.java new file mode 100644 index 0000000000..bc09a072f7 --- /dev/null +++ b/binding2/mdsal-binding2-dom-codec/src/test/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/InstanceIdentifierSerializeDeserializeTest.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018 Cisco Systems, Inc. and others. 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.javav2.dom.codec.impl; + +import static org.junit.Assert.assertEquals; + +import javassist.ClassPool; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.mdsal.binding.javav2.dom.codec.generator.impl.StreamWriterGenerator; +import org.opendaylight.mdsal.binding.javav2.runtime.javassist.JavassistUtils; +import org.opendaylight.mdsal.binding.javav2.spec.base.InstanceIdentifier; +import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.data.ChoiceContainer; +import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.data.choice_container.identifier.simple.SimpleId; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; + +public class InstanceIdentifierSerializeDeserializeTest extends AbstractBindingRuntimeTest { + private static final InstanceIdentifier BA_SIMPLE_ID = InstanceIdentifier + .builder(ChoiceContainer.class).child(SimpleId.class).build(); + + private static final QName CHOICE_CONTAINER_QNAME = ChoiceContainer.QNAME; + private static final QName SIMPLE_ID_QNAME = SimpleId.QNAME; + + + private static final YangInstanceIdentifier BI_SIMPLE_ID_PATH = YangInstanceIdentifier + .of(CHOICE_CONTAINER_QNAME).node(SIMPLE_ID_QNAME); + + private BindingNormalizedNodeCodecRegistry registry; + + @Override + @Before + public void setup() { + super.setup(); + final JavassistUtils utils = JavassistUtils.forClassPool(ClassPool.getDefault()); + registry = new BindingNormalizedNodeCodecRegistry(StreamWriterGenerator.create(utils)); + registry.onBindingRuntimeContextUpdated(getRuntimeContext()); + } + + @Test + public void testYangIIToBindingAwareII() { + final InstanceIdentifier instanceIdentifier = registry.fromYangInstanceIdentifier(BI_SIMPLE_ID_PATH); + assertEquals(BA_SIMPLE_ID, instanceIdentifier); + } + + @Test + public void testBindingAwareIIToYangIContainer() { + final YangInstanceIdentifier yangInstanceIdentifier = registry.toYangInstanceIdentifier(BA_SIMPLE_ID); + assertEquals(BI_SIMPLE_ID_PATH, yangInstanceIdentifier); + } +} diff --git a/binding2/mdsal-binding2-dom-codec/src/test/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/NormalizedNodeSerializeDeserializeTest.java b/binding2/mdsal-binding2-dom-codec/src/test/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/NormalizedNodeSerializeDeserializeTest.java index 363ba73cb3..531ff349d6 100644 --- a/binding2/mdsal-binding2-dom-codec/src/test/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/NormalizedNodeSerializeDeserializeTest.java +++ b/binding2/mdsal-binding2-dom-codec/src/test/java/org/opendaylight/mdsal/binding/javav2/dom/codec/impl/NormalizedNodeSerializeDeserializeTest.java @@ -25,9 +25,12 @@ import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode; import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.data.TreeLeafOnlyUsesAugment; import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.dto.TreeLeafOnlyUsesAugmentBuilder; import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.grp.LeafFromGrouping; +import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.data.ChoiceContainer; import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.data.Top; +import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.data.choice_container.identifier.simple.SimpleId; import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.data.top.TopLevelList; import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.dto.TopBuilder; +import org.opendaylight.mdsal.gen.javav2.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.dto.choice_container.identifier.simple.SimpleIdBuilder; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier; @@ -46,6 +49,14 @@ public class NormalizedNodeSerializeDeserializeTest extends AbstractBindingRunti private static final QName AUGMENTED_INT_QNAME = QName.create(TopLevelList.QNAME, "augmented-int"); private static final QName SIMPLE_VALUE_QNAME = QName.create(LeafFromGrouping.QNAME, "simple-value"); private static final QName SIMPLE_TYPE_QNAME = QName.create(LeafFromGrouping.QNAME, "simple-type"); + private static final QName CHOICE_CONTAINER_QNAME = ChoiceContainer.QNAME; + private static final QName SIMPLE_ID_QNAME = SimpleId.QNAME; + private static final QName SIMPLE_LEAF_ID_QNAME = QName.create(SimpleId.QNAME, "id"); + + private static final InstanceIdentifier BA_SIMPLE_ID = InstanceIdentifier + .builder(ChoiceContainer.class).child(SimpleId.class).build(); + private static final YangInstanceIdentifier BI_SIMPLE_ID_PATH = YangInstanceIdentifier + .of(CHOICE_CONTAINER_QNAME).node(SIMPLE_ID_QNAME); @Before public void setup() { @@ -122,4 +133,29 @@ public class NormalizedNodeSerializeDeserializeTest extends AbstractBindingRunti assertEquals(topBindingData(), entry.getValue()); } + private static SimpleId simpleIdBindingData() { + return new SimpleIdBuilder().setId(10).build(); + } + + private static ContainerNode simpleIdNormailziedData() { + return ImmutableContainerNodeBuilder.create() + .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(SIMPLE_ID_QNAME)) + .withChild(leafNode(SIMPLE_LEAF_ID_QNAME, 10)) + .build(); + } + + @Test + public void testChoiceDataToNormalizedNode() { + final Map.Entry> entry = + registry.toNormalizedNode(BA_SIMPLE_ID, simpleIdBindingData()); + assertEquals(simpleIdNormailziedData(), entry.getValue()); + } + + @Test + public void testChoiceDataFromNormalizedNode() { + final Entry, TreeNode> entry = + registry.fromNormalizedNode(BI_SIMPLE_ID_PATH, simpleIdNormailziedData()); + assertEquals(simpleIdBindingData(), entry.getValue()); + } + } \ No newline at end of file -- 2.36.6