/* * Copyright (c) 2015 Pantheon Technologies s.r.o. 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.yangtools.yang.data.impl.schema.tree; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap.Builder; import org.junit.Before; import org.junit.Test; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.common.XMLNamespace; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.SystemMapNode; import org.opendaylight.yangtools.yang.data.api.schema.builder.CollectionNodeBuilder; import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder; import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree; import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration; import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification; import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException; import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder; import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils; public class Bug4295Test { private DataTree inMemoryDataTree; private QName root; private QName subRoot; private QName outerList; private QName innerList; private QName oid; private QName iid; private QName oleaf; private QName ileaf; private QNameModule foo; @Before public void init() { foo = QNameModule.create(XMLNamespace.of("foo")); root = QName.create(foo, "root"); subRoot = QName.create(foo, "sub-root"); outerList = QName.create(foo, "outer-list"); innerList = QName.create(foo, "inner-list"); oid = QName.create(foo, "o-id"); iid = QName.create(foo, "i-id"); oleaf = QName.create(foo, "o"); ileaf = QName.create(foo, "i"); inMemoryDataTree = new InMemoryDataTreeFactory().create(DataTreeConfiguration.DEFAULT_OPERATIONAL, YangParserTestUtils.parseYangResource("/bug-4295/foo.yang")); } @Test public void test() throws DataValidationFailedException { firstModification(); secondModification(1); secondModification(2); secondModification(3); } private void firstModification() throws DataValidationFailedException { /* MERGE */ SystemMapNode outerListNode = ImmutableNodes.mapNodeBuilder() .withNodeIdentifier(NodeIdentifier.create(outerList)) .withChild(createOuterListEntry("1", "o-1")) .withChild(createOuterListEntry("2", "o-2")) .withChild(createOuterListEntry("3", "o-3")) .build(); ContainerNode rootContainerNode = createRootContainerBuilder() .withChild(createSubRootContainerBuilder().withChild(outerListNode).build()) .build(); YangInstanceIdentifier path = YangInstanceIdentifier.of(root); DataTreeModification modification = inMemoryDataTree.takeSnapshot().newModification(); modification.merge(path, rootContainerNode); /* WRITE INNER LIST WITH ENTRIES*/ SystemMapNode innerListNode = createInnerListBuilder() .withChild(createInnerListEntry("a", "i-a")) .withChild(createInnerListEntry("b", "i-b")) .build(); path = YangInstanceIdentifier.of(root).node(subRoot).node(outerList).node(createOuterListEntryPath("2")) .node(innerList); modification.write(path, innerListNode); /* COMMIT */ modification.ready(); inMemoryDataTree.validate(modification); inMemoryDataTree.commit(inMemoryDataTree.prepare(modification)); } private void secondModification(final int testScenarioNumber) throws DataValidationFailedException { /* MERGE */ SystemMapNode outerListNode = ImmutableNodes.mapNodeBuilder() .withNodeIdentifier(NodeIdentifier.create(outerList)) .withChild(createOuterListEntry("3", "o-3")) .withChild(createOuterListEntry("4", "o-4")) .withChild(createOuterListEntry("5", "o-5")) .build(); ContainerNode rootContainerNode = createRootContainerBuilder() .withChild(createSubRootContainerBuilder().withChild(outerListNode).build()) .build(); YangInstanceIdentifier path = YangInstanceIdentifier.of(root); DataTreeModification modification = inMemoryDataTree.takeSnapshot().newModification(); modification.merge(path, rootContainerNode); if (testScenarioNumber == 1) { /* WRITE EMPTY INNER LIST */ writeEmptyInnerList(modification, "2"); } else if (testScenarioNumber == 2) { /* WRITE INNER LIST ENTRY */ MapEntryNode innerListEntryA = createInnerListEntry("a", "i-a-2"); path = YangInstanceIdentifier.of(root).node(subRoot).node(outerList).node(createOuterListEntryPath("2")) .node(innerList).node(createInnerListEntryPath("a")); modification.write(path, innerListEntryA); } else if (testScenarioNumber == 3) { /* WRITE INNER LIST WITH ENTRIES */ SystemMapNode innerListNode = createInnerListBuilder().withChild(createInnerListEntry("a", "i-a-3")) .withChild(createInnerListEntry("c", "i-c")).build(); path = YangInstanceIdentifier.of(root).node(subRoot).node(outerList).node(createOuterListEntryPath("2")) .node(innerList); modification.write(path, innerListNode); } /* COMMIT */ modification.ready(); inMemoryDataTree.validate(modification); inMemoryDataTree.commit(inMemoryDataTree.prepare(modification)); } private void writeEmptyInnerList(final DataTreeModification modification, final String outerListEntryKey) { YangInstanceIdentifier path = YangInstanceIdentifier.of(root).node(subRoot).node(outerList) .node(createOuterListEntryPath(outerListEntryKey)).node(innerList); modification.write(path, createInnerListBuilder().build()); } private DataContainerNodeBuilder createRootContainerBuilder() { return ImmutableContainerNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(root)); } private DataContainerNodeBuilder createSubRootContainerBuilder() { return ImmutableContainerNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(subRoot)); } private CollectionNodeBuilder createInnerListBuilder() { return ImmutableNodes.mapNodeBuilder().withNodeIdentifier(NodeIdentifier.create(innerList)); } private NodeIdentifierWithPredicates createInnerListEntryPath(final String keyValue) { Builder builder = ImmutableMap.builder(); ImmutableMap keys = builder.put(iid, keyValue).build(); return NodeIdentifierWithPredicates.of(innerList, keys); } private NodeIdentifierWithPredicates createOuterListEntryPath(final String keyValue) { Builder builder = ImmutableMap.builder(); ImmutableMap keys = builder.put(oid, keyValue).build(); return NodeIdentifierWithPredicates.of(outerList, keys); } private MapEntryNode createOuterListEntry(final String keyValue, final String leafValue) { return ImmutableNodes.mapEntryBuilder(outerList, oid, keyValue) .withChild(ImmutableNodes.leafNode(oleaf, leafValue)).build(); } private MapEntryNode createInnerListEntry(final String keyValue, final String leafValue) { return ImmutableNodes.mapEntryBuilder(innerList, iid, keyValue) .withChild(ImmutableNodes.leafNode(ileaf, leafValue)).build(); } }