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
9 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertTrue;
13 import static org.junit.Assert.fail;
15 import com.google.common.collect.ImmutableMap;
17 import java.util.Optional;
18 import org.junit.Before;
19 import org.junit.Test;
20 import org.opendaylight.yangtools.yang.common.QName;
21 import org.opendaylight.yangtools.yang.common.QNameModule;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
23 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
24 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
25 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
26 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
27 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
28 import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
29 import org.opendaylight.yangtools.yang.data.api.schema.tree.ConflictingModificationAppliedException;
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.api.schema.tree.TipProducingDataTree;
35 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
36 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
37 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
41 public class OrderedListTest {
42 private static final Logger LOG = LoggerFactory.getLogger(OrderedListTest.class);
44 private TipProducingDataTree inMemoryDataTree;
45 private SchemaContext context;
47 private QNameModule testModule;
48 private QName parentContainer;
49 private QName childContainer;
50 private QName parentOrderedList;
51 private QName childOrderedList;
52 private QName parentKeyLeaf;
53 private QName parentOrdinaryLeaf;
54 private QName childKeyLeaf;
55 private QName childOrdinaryLeaf;
59 context = YangParserTestUtils.parseYangResource("/ordered-list-modification-test.yang");
60 testModule = QNameModule.create(URI.create("ordered-list-modification-test"), null);
61 parentContainer = QName.create(testModule, "parent-container");
62 childContainer = QName.create(testModule, "child-container");
63 parentOrderedList = QName.create(testModule, "parent-ordered-list");
64 childOrderedList = QName.create(testModule, "child-ordered-list");
65 parentKeyLeaf = QName.create(testModule, "parent-key-leaf");
66 childKeyLeaf = QName.create(testModule, "child-key-leaf");
67 parentOrdinaryLeaf = QName.create(testModule, "parent-ordinary-leaf");
68 childOrdinaryLeaf = QName.create(testModule, "child-ordinary-leaf");
69 inMemoryDataTree = InMemoryDataTreeFactory.getInstance().create(DataTreeConfiguration.DEFAULT_OPERATIONAL);
70 inMemoryDataTree.setSchemaContext(context);
74 public void testsequentialModifications() throws DataValidationFailedException {
83 public void modification1() throws DataValidationFailedException {
84 OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
85 new NodeIdentifier(parentOrderedList))
86 .withChild(createParentOrderedListEntry("pkval1", "plfval1"))
87 .withChild(createParentOrderedListEntry("pkval2", "plfval2"))
88 .withChild(createParentOrderedListEntry("pkval3", "plfval3")).build();
90 ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
91 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
92 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
95 YangInstanceIdentifier path1 = YangInstanceIdentifier.of(parentContainer);
97 DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
98 treeModification.write(path1, parentContainerNode);
100 OrderedMapNode childOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
101 new NodeIdentifier(childOrderedList))
102 .withChild(createChildOrderedListEntry("chkval1", "chlfval1"))
103 .withChild(createChildOrderedListEntry("chkval2", "chlfval2")).build();
105 YangInstanceIdentifier path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer)
106 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList);
108 treeModification.write(path2, childOrderedListNode);
109 treeModification.ready();
110 inMemoryDataTree.validate(treeModification);
111 inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
113 DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
114 Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path1);
115 assertTrue(readNode.isPresent());
117 readNode = snapshotAfterCommits.readNode(path2);
118 assertTrue(readNode.isPresent());
121 public void modification2() throws DataValidationFailedException {
122 OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
123 new NodeIdentifier(parentOrderedList))
124 .withChild(createParentOrderedListEntry("pkval3", "plfval3updated"))
125 .withChild(createParentOrderedListEntry("pkval4", "plfval4"))
126 .withChild(createParentOrderedListEntry("pkval5", "plfval5")).build();
128 ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
129 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
130 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
133 DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
135 YangInstanceIdentifier path1 = YangInstanceIdentifier.of(parentContainer);
136 treeModification.merge(path1, parentContainerNode);
138 OrderedMapNode childOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
139 new NodeIdentifier(childOrderedList))
140 .withChild(createChildOrderedListEntry("chkval1", "chlfval1updated"))
141 .withChild(createChildOrderedListEntry("chkval2", "chlfval2updated"))
142 .withChild(createChildOrderedListEntry("chkval3", "chlfval3")).build();
144 YangInstanceIdentifier path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer)
145 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList);
146 treeModification.merge(path2, childOrderedListNode);
148 treeModification.ready();
149 inMemoryDataTree.validate(treeModification);
150 inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
152 DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
153 Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path1);
154 assertTrue(readNode.isPresent());
156 readNode = snapshotAfterCommits.readNode(path2);
157 assertTrue(readNode.isPresent());
160 public void modification3() throws DataValidationFailedException {
161 OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
162 new NodeIdentifier(parentOrderedList))
163 .withChild(createParentOrderedListEntry("pkval1", "plfval1")).build();
165 ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
166 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
167 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
170 YangInstanceIdentifier path1 = YangInstanceIdentifier.of(parentContainer);
172 DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
173 treeModification.write(path1, parentContainerNode);
175 OrderedMapNode childOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
176 new NodeIdentifier(childOrderedList))
177 .withChild(createChildOrderedListEntry("chkval1", "chlfval1new")).build();
179 YangInstanceIdentifier path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer)
180 .node(parentOrderedList)
181 .node(createParentOrderedListEntryPath("pkval4")).node(childOrderedList);
183 treeModification.merge(path2, childOrderedListNode);
186 treeModification.ready();
187 fail("Exception should have been thrown.");
188 inMemoryDataTree.validate(treeModification);
189 inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
190 } catch (final IllegalArgumentException ex) {
191 LOG.debug("IllegalArgumentException was thrown as expected: {}", ex);
192 assertTrue(ex.getMessage().contains("Metadata not available for modification NodeModification"));
195 DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
196 Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path1);
197 assertTrue(readNode.isPresent());
199 readNode = snapshotAfterCommits.readNode(path2);
200 assertFalse(readNode.isPresent());
203 public void modification4() throws DataValidationFailedException {
204 DataTreeModification treeModification1 = inMemoryDataTree.takeSnapshot().newModification();
205 DataTreeModification treeModification2 = inMemoryDataTree.takeSnapshot().newModification();
207 OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
208 new NodeIdentifier(parentOrderedList)).withChild(createParentOrderedListEntry("pkval1", "plfval1"))
211 OrderedMapNode parentOrderedListNode2 = Builders.orderedMapBuilder().withNodeIdentifier(
212 new NodeIdentifier(parentOrderedList)).withChild(createParentOrderedListEntry("pkval2", "plfval2"))
215 ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
216 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
217 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
220 ContainerNode parentContainerNode2 = Builders.containerBuilder().withNodeIdentifier(
221 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
222 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode2).build())
225 YangInstanceIdentifier path = YangInstanceIdentifier.of(parentContainer);
227 treeModification1.write(path, parentContainerNode);
228 treeModification2.write(path, parentContainerNode2);
229 treeModification1.ready();
230 treeModification2.ready();
232 inMemoryDataTree.validate(treeModification1);
233 inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification1));
236 inMemoryDataTree.validate(treeModification2);
237 fail("Exception should have been thrown.");
238 inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification2));
239 } catch (ConflictingModificationAppliedException ex) {
240 LOG.debug("ConflictingModificationAppliedException was thrown as expected: {}", ex);
241 assertTrue(ex.getMessage().contains("Node was replaced by other transaction"));
244 DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
245 Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path);
246 assertTrue(readNode.isPresent());
249 public void delete1() throws DataValidationFailedException {
250 YangInstanceIdentifier path = YangInstanceIdentifier.of(parentContainer).node(childContainer)
251 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList)
252 .node(createChildOrderedListEntryPath("chkval1"));
254 DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
255 treeModification.delete(path);
256 treeModification.ready();
257 inMemoryDataTree.validate(treeModification);
258 inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
260 DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
261 Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path);
262 assertFalse(readNode.isPresent());
265 public void delete2() throws DataValidationFailedException {
266 YangInstanceIdentifier path = YangInstanceIdentifier.of(parentContainer).node(childContainer)
267 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2"));
269 DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
270 treeModification.delete(path);
271 treeModification.ready();
272 inMemoryDataTree.validate(treeModification);
273 inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
275 DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
276 Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path);
277 assertFalse(readNode.isPresent());
280 private MapEntryNode createParentOrderedListEntry(final String keyValue, final String leafValue) {
281 return Builders.mapEntryBuilder().withNodeIdentifier(new NodeIdentifierWithPredicates(parentOrderedList,
282 parentKeyLeaf, keyValue))
283 .withChild(Builders.leafBuilder().withNodeIdentifier(NodeIdentifier.create(parentOrdinaryLeaf))
284 .withValue(leafValue).build()).build();
287 private MapEntryNode createChildOrderedListEntry(final String keyValue, final String leafValue) {
288 return Builders.mapEntryBuilder().withNodeIdentifier(new NodeIdentifierWithPredicates(childOrderedList,
289 childKeyLeaf, keyValue))
290 .withChild(Builders.leafBuilder().withNodeIdentifier(NodeIdentifier.create(childOrdinaryLeaf))
291 .withValue(leafValue).build()).build();
294 private NodeIdentifierWithPredicates createParentOrderedListEntryPath(final String keyValue) {
295 ImmutableMap.Builder<QName, Object> builder = ImmutableMap.builder();
296 ImmutableMap<QName, Object> keys = builder.put(parentKeyLeaf, keyValue).build();
297 return new NodeIdentifierWithPredicates(parentOrderedList, keys);
300 private NodeIdentifierWithPredicates createChildOrderedListEntryPath(final String keyValue) {
301 ImmutableMap.Builder<QName, Object> builder = ImmutableMap.builder();
302 ImmutableMap<QName, Object> keys = builder.put(childKeyLeaf, keyValue).build();
303 return new NodeIdentifierWithPredicates(childOrderedList, keys);