2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
10 import static org.junit.Assert.assertFalse;
11 import static org.junit.Assert.assertTrue;
12 import static org.junit.Assert.fail;
14 import com.google.common.collect.ImmutableMap;
16 import java.util.Optional;
17 import org.junit.Before;
18 import org.junit.Test;
19 import org.opendaylight.yangtools.yang.common.QName;
20 import org.opendaylight.yangtools.yang.common.QNameModule;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
23 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
24 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
25 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
26 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
27 import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
28 import org.opendaylight.yangtools.yang.data.api.schema.tree.ConflictingModificationAppliedException;
29 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
30 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
31 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
32 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
33 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
34 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
35 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
36 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
40 public class OrderedListTest {
41 private static final Logger LOG = LoggerFactory.getLogger(OrderedListTest.class);
43 private DataTree inMemoryDataTree;
44 private SchemaContext context;
46 private QNameModule testModule;
47 private QName parentContainer;
48 private QName childContainer;
49 private QName parentOrderedList;
50 private QName childOrderedList;
51 private QName parentKeyLeaf;
52 private QName parentOrdinaryLeaf;
53 private QName childKeyLeaf;
54 private QName childOrdinaryLeaf;
58 context = YangParserTestUtils.parseYangResource("/ordered-list-modification-test.yang");
59 testModule = QNameModule.create(URI.create("ordered-list-modification-test"));
60 parentContainer = QName.create(testModule, "parent-container");
61 childContainer = QName.create(testModule, "child-container");
62 parentOrderedList = QName.create(testModule, "parent-ordered-list");
63 childOrderedList = QName.create(testModule, "child-ordered-list");
64 parentKeyLeaf = QName.create(testModule, "parent-key-leaf");
65 childKeyLeaf = QName.create(testModule, "child-key-leaf");
66 parentOrdinaryLeaf = QName.create(testModule, "parent-ordinary-leaf");
67 childOrdinaryLeaf = QName.create(testModule, "child-ordinary-leaf");
68 inMemoryDataTree = new InMemoryDataTreeFactory().create(DataTreeConfiguration.DEFAULT_OPERATIONAL, context);
72 public void testsequentialModifications() throws DataValidationFailedException {
81 public void modification1() throws DataValidationFailedException {
82 OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
83 new NodeIdentifier(parentOrderedList))
84 .withChild(createParentOrderedListEntry("pkval1", "plfval1"))
85 .withChild(createParentOrderedListEntry("pkval2", "plfval2"))
86 .withChild(createParentOrderedListEntry("pkval3", "plfval3")).build();
88 ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
89 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
90 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
93 YangInstanceIdentifier path1 = YangInstanceIdentifier.of(parentContainer);
95 DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
96 treeModification.write(path1, parentContainerNode);
98 OrderedMapNode childOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
99 new NodeIdentifier(childOrderedList))
100 .withChild(createChildOrderedListEntry("chkval1", "chlfval1"))
101 .withChild(createChildOrderedListEntry("chkval2", "chlfval2")).build();
103 YangInstanceIdentifier path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer)
104 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList);
106 treeModification.write(path2, childOrderedListNode);
107 treeModification.ready();
108 inMemoryDataTree.validate(treeModification);
109 inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
111 DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
112 Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path1);
113 assertTrue(readNode.isPresent());
115 readNode = snapshotAfterCommits.readNode(path2);
116 assertTrue(readNode.isPresent());
119 public void modification2() throws DataValidationFailedException {
120 OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
121 new NodeIdentifier(parentOrderedList))
122 .withChild(createParentOrderedListEntry("pkval3", "plfval3updated"))
123 .withChild(createParentOrderedListEntry("pkval4", "plfval4"))
124 .withChild(createParentOrderedListEntry("pkval5", "plfval5")).build();
126 ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
127 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
128 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
131 DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
133 YangInstanceIdentifier path1 = YangInstanceIdentifier.of(parentContainer);
134 treeModification.merge(path1, parentContainerNode);
136 OrderedMapNode childOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
137 new NodeIdentifier(childOrderedList))
138 .withChild(createChildOrderedListEntry("chkval1", "chlfval1updated"))
139 .withChild(createChildOrderedListEntry("chkval2", "chlfval2updated"))
140 .withChild(createChildOrderedListEntry("chkval3", "chlfval3")).build();
142 YangInstanceIdentifier path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer)
143 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList);
144 treeModification.merge(path2, childOrderedListNode);
146 treeModification.ready();
147 inMemoryDataTree.validate(treeModification);
148 inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
150 DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
151 Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path1);
152 assertTrue(readNode.isPresent());
154 readNode = snapshotAfterCommits.readNode(path2);
155 assertTrue(readNode.isPresent());
158 public void modification3() throws DataValidationFailedException {
159 OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
160 new NodeIdentifier(parentOrderedList))
161 .withChild(createParentOrderedListEntry("pkval1", "plfval1")).build();
163 ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
164 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
165 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
168 YangInstanceIdentifier path1 = YangInstanceIdentifier.of(parentContainer);
170 DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
171 treeModification.write(path1, parentContainerNode);
173 OrderedMapNode childOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
174 new NodeIdentifier(childOrderedList))
175 .withChild(createChildOrderedListEntry("chkval1", "chlfval1new")).build();
177 YangInstanceIdentifier path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer)
178 .node(parentOrderedList)
179 .node(createParentOrderedListEntryPath("pkval4")).node(childOrderedList);
181 treeModification.merge(path2, childOrderedListNode);
184 treeModification.ready();
185 fail("Exception should have been thrown.");
186 inMemoryDataTree.validate(treeModification);
187 inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
188 } catch (final IllegalArgumentException ex) {
189 LOG.debug("IllegalArgumentException was thrown as expected", ex);
190 assertTrue(ex.getMessage().contains("Metadata not available for modification NodeModification"));
193 DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
194 Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path1);
195 assertTrue(readNode.isPresent());
197 readNode = snapshotAfterCommits.readNode(path2);
198 assertFalse(readNode.isPresent());
201 public void modification4() throws DataValidationFailedException {
202 DataTreeModification treeModification1 = inMemoryDataTree.takeSnapshot().newModification();
203 DataTreeModification treeModification2 = inMemoryDataTree.takeSnapshot().newModification();
205 OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
206 new NodeIdentifier(parentOrderedList)).withChild(createParentOrderedListEntry("pkval1", "plfval1"))
209 OrderedMapNode parentOrderedListNode2 = Builders.orderedMapBuilder().withNodeIdentifier(
210 new NodeIdentifier(parentOrderedList)).withChild(createParentOrderedListEntry("pkval2", "plfval2"))
213 ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
214 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
215 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
218 ContainerNode parentContainerNode2 = Builders.containerBuilder().withNodeIdentifier(
219 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
220 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode2).build())
223 YangInstanceIdentifier path = YangInstanceIdentifier.of(parentContainer);
225 treeModification1.write(path, parentContainerNode);
226 treeModification2.write(path, parentContainerNode2);
227 treeModification1.ready();
228 treeModification2.ready();
230 inMemoryDataTree.validate(treeModification1);
231 inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification1));
234 inMemoryDataTree.validate(treeModification2);
235 fail("Exception should have been thrown.");
236 inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification2));
237 } catch (ConflictingModificationAppliedException ex) {
238 LOG.debug("ConflictingModificationAppliedException was thrown as expected", ex);
239 assertTrue(ex.getMessage().contains("Node was replaced by other transaction"));
242 DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
243 Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path);
244 assertTrue(readNode.isPresent());
247 public void delete1() throws DataValidationFailedException {
248 YangInstanceIdentifier path = YangInstanceIdentifier.of(parentContainer).node(childContainer)
249 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList)
250 .node(createChildOrderedListEntryPath("chkval1"));
252 DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
253 treeModification.delete(path);
254 treeModification.ready();
255 inMemoryDataTree.validate(treeModification);
256 inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
258 DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
259 Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path);
260 assertFalse(readNode.isPresent());
263 public void delete2() throws DataValidationFailedException {
264 YangInstanceIdentifier path = YangInstanceIdentifier.of(parentContainer).node(childContainer)
265 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2"));
267 DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
268 treeModification.delete(path);
269 treeModification.ready();
270 inMemoryDataTree.validate(treeModification);
271 inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
273 DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
274 Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path);
275 assertFalse(readNode.isPresent());
278 private MapEntryNode createParentOrderedListEntry(final String keyValue, final String leafValue) {
279 return Builders.mapEntryBuilder().withNodeIdentifier(new NodeIdentifierWithPredicates(parentOrderedList,
280 parentKeyLeaf, keyValue))
281 .withChild(Builders.leafBuilder().withNodeIdentifier(NodeIdentifier.create(parentOrdinaryLeaf))
282 .withValue(leafValue).build()).build();
285 private MapEntryNode createChildOrderedListEntry(final String keyValue, final String leafValue) {
286 return Builders.mapEntryBuilder().withNodeIdentifier(new NodeIdentifierWithPredicates(childOrderedList,
287 childKeyLeaf, keyValue))
288 .withChild(Builders.leafBuilder().withNodeIdentifier(NodeIdentifier.create(childOrdinaryLeaf))
289 .withValue(leafValue).build()).build();
292 private NodeIdentifierWithPredicates createParentOrderedListEntryPath(final String keyValue) {
293 ImmutableMap.Builder<QName, Object> builder = ImmutableMap.builder();
294 ImmutableMap<QName, Object> keys = builder.put(parentKeyLeaf, keyValue).build();
295 return new NodeIdentifierWithPredicates(parentOrderedList, keys);
298 private NodeIdentifierWithPredicates createChildOrderedListEntryPath(final String keyValue) {
299 ImmutableMap.Builder<QName, Object> builder = ImmutableMap.builder();
300 ImmutableMap<QName, Object> keys = builder.put(childKeyLeaf, keyValue).build();
301 return new NodeIdentifierWithPredicates(childOrderedList, keys);