From 8128f33de85b2e839a8ce6d18812374a63b81c66 Mon Sep 17 00:00:00 2001 From: Maros Marsalek Date: Mon, 21 Nov 2016 13:09:23 +0100 Subject: Fix leaf list modification detection Change-Id: Ib7bcde546faf8e9bf73d16adaf87c2f8c43ec4aa Signed-off-by: Maros Marsalek --- .../fd/honeycomb/data/impl/ModificationDiff.java | 9 ++++- .../honeycomb/data/impl/ModificationDiffTest.java | 44 ++++++++++++++++++++++ infra/data-impl/src/test/resources/test-diff.yang | 6 +++ 3 files changed, 58 insertions(+), 1 deletion(-) (limited to 'infra/data-impl') diff --git a/infra/data-impl/src/main/java/io/fd/honeycomb/data/impl/ModificationDiff.java b/infra/data-impl/src/main/java/io/fd/honeycomb/data/impl/ModificationDiff.java index f999ba1ee..86666ba70 100644 --- a/infra/data-impl/src/main/java/io/fd/honeycomb/data/impl/ModificationDiff.java +++ b/infra/data-impl/src/main/java/io/fd/honeycomb/data/impl/ModificationDiff.java @@ -45,6 +45,7 @@ import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; @@ -151,7 +152,9 @@ final class ModificationDiff { // Check if there are any modified leaves and if so, consider current node as modified final Boolean directLeavesModified = emptyPresenceNode || modification.streamChildren() - .filter(child -> child.is(LeafSchemaNode.class)) + // Checking leaf or leaf-lists children for direct modification, which means that leafs of leaf lists + // trigger a modification on parent node + .filter(child -> child.is(LeafSchemaNode.class) || child.is(LeafListSchemaNode.class)) // For some reason, we get modifications on unmodified list keys // and that messes up our modifications collection here, so we need to skip .filter(Modification::isBeforeAndAfterDifferent) @@ -387,6 +390,10 @@ final class ModificationDiff { if (maybeChild.isPresent()) { found = maybeChild.get(); } + // Special handling for leaf-list nodes. Basically the same as is for list mixin nodes + } else if (schema instanceof LeafListSchemaNode && + ((SchemaNode) schema).getQName().equals(identifier.getNodeType())) { + found = schema; } return checkNotNull(found, "Unable to find child node in: %s identifiable by: %s", schema, identifier); diff --git a/infra/data-impl/src/test/java/io/fd/honeycomb/data/impl/ModificationDiffTest.java b/infra/data-impl/src/test/java/io/fd/honeycomb/data/impl/ModificationDiffTest.java index 29390e4c9..664b57378 100644 --- a/infra/data-impl/src/test/java/io/fd/honeycomb/data/impl/ModificationDiffTest.java +++ b/infra/data-impl/src/test/java/io/fd/honeycomb/data/impl/ModificationDiffTest.java @@ -28,6 +28,7 @@ import org.junit.Test; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.MapNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; @@ -41,6 +42,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.tree.TipProducingDataTree import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType; import org.opendaylight.yangtools.yang.data.impl.schema.Builders; import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder; import org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTreeFactory; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; @@ -60,6 +62,10 @@ public class ModificationDiffTest { static final QName EMPTY_QNAME = QName.create(TOP_CONTAINER_QNAME, "empty"); static final QName IN_EMPTY_QNAME = QName.create(TOP_CONTAINER_QNAME, "in-empty"); + static final QName FOR_LEAF_LIST_QNAME = QName.create(TOP_CONTAINER_QNAME, "for-leaf-list"); + static final QName NESTED_LEAF_LIST_QNAME = QName.create(TOP_CONTAINER_QNAME, "nested-leaf-list"); + + static final QName WITH_CHOICE_CONTAINER_QNAME = QName.create("urn:opendaylight:params:xml:ns:yang:test:diff", "2015-01-05", "with-choice"); static final QName CHOICE_QNAME = QName.create(WITH_CHOICE_CONTAINER_QNAME, "choice"); @@ -87,6 +93,24 @@ public class ModificationDiffTest { assertUpdate(modificationDiff.getUpdates().values().iterator().next(), TOP_CONTAINER_ID, null, topContainer); } + @Test + public void testLeafList() throws Exception { + final TipProducingDataTree dataTree = getDataTree(); + final DataTreeModification dataTreeModification = getModification(dataTree); + final ContainerNode topContainer = getTopContainerWithLeafList("string1", "string2"); + final YangInstanceIdentifier TOP_CONTAINER_ID = YangInstanceIdentifier.of(TOP_CONTAINER_QNAME); + dataTreeModification.write(TOP_CONTAINER_ID, topContainer); + final DataTreeCandidateTip prepare = prepareModification(dataTree, dataTreeModification); + + final ModificationDiff modificationDiff = getModificationDiff(prepare); + + assertThat(modificationDiff.getUpdates().size(), is(1)); + assertThat(modificationDiff.getUpdates().values().size(), is(1)); + assertUpdate(modificationDiff.getUpdates().values().iterator().next(), + TOP_CONTAINER_ID.node(FOR_LEAF_LIST_QNAME), null, + topContainer.getChild(new YangInstanceIdentifier.NodeIdentifier(FOR_LEAF_LIST_QNAME)).get()); + } + @Test public void testWritePresenceEmptyContainer() throws Exception { final TipProducingDataTree dataTree = getDataTree(); @@ -456,6 +480,26 @@ public class ModificationDiffTest { .build(); } + static ContainerNode getTopContainerWithLeafList(final String... stringValue) { + final ListNodeBuilder> leafSetBuilder = Builders.leafSetBuilder(); + for (final String value : stringValue) { + leafSetBuilder.withChild(Builders.leafSetEntryBuilder() + .withNodeIdentifier(new YangInstanceIdentifier.NodeWithValue<>(NESTED_LEAF_LIST_QNAME, value)) + .withValue(value) + .build()); + } + + return Builders.containerBuilder() + .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TOP_CONTAINER_QNAME)) + .withChild(Builders.containerBuilder() + .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(FOR_LEAF_LIST_QNAME)) + .withChild(leafSetBuilder + .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(NESTED_LEAF_LIST_QNAME)) + .build()) + .build()) + .build(); + } + static MapNode getNestedList(final String listItemName, final String text) { return Builders.mapBuilder() .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(NESTED_LIST_QNAME)) diff --git a/infra/data-impl/src/test/resources/test-diff.yang b/infra/data-impl/src/test/resources/test-diff.yang index 57708589d..b7a0c7e7f 100644 --- a/infra/data-impl/src/test/resources/test-diff.yang +++ b/infra/data-impl/src/test/resources/test-diff.yang @@ -22,6 +22,12 @@ module test-diff { } } + container for-leaf-list { + leaf-list nested-leaf-list { + type string; + } + } + list nested-list { key "name"; -- cgit 1.2.3-korg