048f8268bb102cc0270b0a58bf0dc2e8cd70910e
[yangtools.git] / yang / yang-data-impl / src / test / java / org / opendaylight / yangtools / yang / data / impl / schema / tree / OrderedListTest.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
9
10 import static org.junit.Assert.assertFalse;
11 import static org.junit.Assert.assertTrue;
12 import static org.junit.Assert.fail;
13
14 import com.google.common.collect.ImmutableMap;
15 import java.net.URI;
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.test.util.YangParserTestUtils;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 public class OrderedListTest {
40     private static final Logger LOG = LoggerFactory.getLogger(OrderedListTest.class);
41
42     private DataTree inMemoryDataTree;
43
44     private QNameModule testModule;
45     private QName parentContainer;
46     private QName childContainer;
47     private QName parentOrderedList;
48     private QName childOrderedList;
49     private QName parentKeyLeaf;
50     private QName parentOrdinaryLeaf;
51     private QName childKeyLeaf;
52     private QName childOrdinaryLeaf;
53
54     @Before
55     public void setup() {
56         testModule = QNameModule.create(URI.create("ordered-list-modification-test"));
57         parentContainer = QName.create(testModule, "parent-container");
58         childContainer = QName.create(testModule, "child-container");
59         parentOrderedList = QName.create(testModule, "parent-ordered-list");
60         childOrderedList = QName.create(testModule, "child-ordered-list");
61         parentKeyLeaf = QName.create(testModule, "parent-key-leaf");
62         childKeyLeaf = QName.create(testModule, "child-key-leaf");
63         parentOrdinaryLeaf = QName.create(testModule, "parent-ordinary-leaf");
64         childOrdinaryLeaf = QName.create(testModule, "child-ordinary-leaf");
65         inMemoryDataTree = new InMemoryDataTreeFactory().create(DataTreeConfiguration.DEFAULT_OPERATIONAL,
66             YangParserTestUtils.parseYangResource("/ordered-list-modification-test.yang"));
67     }
68
69     @Test
70     public void testsequentialModifications() throws DataValidationFailedException {
71         modification1();
72         modification2();
73         delete1();
74         delete2();
75         modification3();
76         modification4();
77     }
78
79     public void modification1() throws DataValidationFailedException {
80         OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
81                 new NodeIdentifier(parentOrderedList))
82                 .withChild(createParentOrderedListEntry("pkval1", "plfval1"))
83                 .withChild(createParentOrderedListEntry("pkval2", "plfval2"))
84                 .withChild(createParentOrderedListEntry("pkval3", "plfval3")).build();
85
86         ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
87                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
88                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
89                 .build();
90
91         YangInstanceIdentifier path1 = YangInstanceIdentifier.of(parentContainer);
92
93         DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
94         treeModification.write(path1, parentContainerNode);
95
96         OrderedMapNode childOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
97                 new NodeIdentifier(childOrderedList))
98                 .withChild(createChildOrderedListEntry("chkval1", "chlfval1"))
99                 .withChild(createChildOrderedListEntry("chkval2", "chlfval2")).build();
100
101         YangInstanceIdentifier path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer)
102                 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList);
103
104         treeModification.write(path2, childOrderedListNode);
105         treeModification.ready();
106         inMemoryDataTree.validate(treeModification);
107         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
108
109         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
110         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path1);
111         assertTrue(readNode.isPresent());
112
113         readNode = snapshotAfterCommits.readNode(path2);
114         assertTrue(readNode.isPresent());
115     }
116
117     public void modification2() throws DataValidationFailedException {
118         OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
119                 new NodeIdentifier(parentOrderedList))
120                 .withChild(createParentOrderedListEntry("pkval3", "plfval3updated"))
121                 .withChild(createParentOrderedListEntry("pkval4", "plfval4"))
122                 .withChild(createParentOrderedListEntry("pkval5", "plfval5")).build();
123
124         ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
125                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
126                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
127                 .build();
128
129         DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
130
131         YangInstanceIdentifier path1 = YangInstanceIdentifier.of(parentContainer);
132         treeModification.merge(path1, parentContainerNode);
133
134         OrderedMapNode childOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
135                 new NodeIdentifier(childOrderedList))
136                 .withChild(createChildOrderedListEntry("chkval1", "chlfval1updated"))
137                 .withChild(createChildOrderedListEntry("chkval2", "chlfval2updated"))
138                 .withChild(createChildOrderedListEntry("chkval3", "chlfval3")).build();
139
140         YangInstanceIdentifier path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer)
141                 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList);
142         treeModification.merge(path2, childOrderedListNode);
143
144         treeModification.ready();
145         inMemoryDataTree.validate(treeModification);
146         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
147
148         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
149         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path1);
150         assertTrue(readNode.isPresent());
151
152         readNode = snapshotAfterCommits.readNode(path2);
153         assertTrue(readNode.isPresent());
154     }
155
156     public void modification3() throws DataValidationFailedException {
157         OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
158                 new NodeIdentifier(parentOrderedList))
159                 .withChild(createParentOrderedListEntry("pkval1", "plfval1")).build();
160
161         ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
162                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
163                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
164                 .build();
165
166         YangInstanceIdentifier path1 = YangInstanceIdentifier.of(parentContainer);
167
168         DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
169         treeModification.write(path1, parentContainerNode);
170
171         OrderedMapNode childOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
172                 new NodeIdentifier(childOrderedList))
173                 .withChild(createChildOrderedListEntry("chkval1", "chlfval1new")).build();
174
175         YangInstanceIdentifier path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer)
176                 .node(parentOrderedList)
177                 .node(createParentOrderedListEntryPath("pkval4")).node(childOrderedList);
178
179         treeModification.merge(path2, childOrderedListNode);
180
181         try {
182             treeModification.ready();
183             fail("Exception should have been thrown.");
184             inMemoryDataTree.validate(treeModification);
185             inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
186         } catch (final IllegalArgumentException ex) {
187             LOG.debug("IllegalArgumentException was thrown as expected", ex);
188             assertTrue(ex.getMessage().contains("Metadata not available for modification ModifiedNode"));
189         }
190
191         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
192         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path1);
193         assertTrue(readNode.isPresent());
194
195         readNode = snapshotAfterCommits.readNode(path2);
196         assertFalse(readNode.isPresent());
197     }
198
199     public void modification4() throws DataValidationFailedException {
200         DataTreeModification treeModification1 = inMemoryDataTree.takeSnapshot().newModification();
201         DataTreeModification treeModification2 = inMemoryDataTree.takeSnapshot().newModification();
202
203         OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
204             new NodeIdentifier(parentOrderedList)).withChild(createParentOrderedListEntry("pkval1", "plfval1"))
205                 .build();
206
207         OrderedMapNode parentOrderedListNode2 = Builders.orderedMapBuilder().withNodeIdentifier(
208             new NodeIdentifier(parentOrderedList)).withChild(createParentOrderedListEntry("pkval2", "plfval2"))
209                 .build();
210
211         ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
212                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
213                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
214                 .build();
215
216         ContainerNode parentContainerNode2 = Builders.containerBuilder().withNodeIdentifier(
217                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
218                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode2).build())
219                 .build();
220
221         YangInstanceIdentifier path = YangInstanceIdentifier.of(parentContainer);
222
223         treeModification1.write(path, parentContainerNode);
224         treeModification2.write(path, parentContainerNode2);
225         treeModification1.ready();
226         treeModification2.ready();
227
228         inMemoryDataTree.validate(treeModification1);
229         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification1));
230
231         try {
232             inMemoryDataTree.validate(treeModification2);
233             fail("Exception should have been thrown.");
234             inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification2));
235         } catch (ConflictingModificationAppliedException ex) {
236             LOG.debug("ConflictingModificationAppliedException was thrown as expected", ex);
237             assertTrue(ex.getMessage().contains("Node was replaced by other transaction"));
238         }
239
240         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
241         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path);
242         assertTrue(readNode.isPresent());
243     }
244
245     public void delete1() throws DataValidationFailedException {
246         YangInstanceIdentifier path = YangInstanceIdentifier.of(parentContainer).node(childContainer)
247                 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList)
248                 .node(createChildOrderedListEntryPath("chkval1"));
249
250         DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
251         treeModification.delete(path);
252         treeModification.ready();
253         inMemoryDataTree.validate(treeModification);
254         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
255
256         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
257         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path);
258         assertFalse(readNode.isPresent());
259     }
260
261     public void delete2() throws DataValidationFailedException {
262         YangInstanceIdentifier path = YangInstanceIdentifier.of(parentContainer).node(childContainer)
263                 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2"));
264
265         DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
266         treeModification.delete(path);
267         treeModification.ready();
268         inMemoryDataTree.validate(treeModification);
269         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
270
271         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
272         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path);
273         assertFalse(readNode.isPresent());
274     }
275
276     private MapEntryNode createParentOrderedListEntry(final String keyValue, final String leafValue) {
277         return Builders.mapEntryBuilder().withNodeIdentifier(NodeIdentifierWithPredicates.of(parentOrderedList,
278                 parentKeyLeaf, keyValue))
279                 .withChild(Builders.leafBuilder().withNodeIdentifier(NodeIdentifier.create(parentOrdinaryLeaf))
280                     .withValue(leafValue).build()).build();
281     }
282
283     private MapEntryNode createChildOrderedListEntry(final String keyValue, final String leafValue) {
284         return Builders.mapEntryBuilder().withNodeIdentifier(NodeIdentifierWithPredicates.of(childOrderedList,
285                 childKeyLeaf, keyValue))
286                 .withChild(Builders.leafBuilder().withNodeIdentifier(NodeIdentifier.create(childOrdinaryLeaf))
287                     .withValue(leafValue).build()).build();
288     }
289
290     private NodeIdentifierWithPredicates createParentOrderedListEntryPath(final String keyValue) {
291         ImmutableMap.Builder<QName, Object> builder = ImmutableMap.builder();
292         ImmutableMap<QName, Object> keys = builder.put(parentKeyLeaf, keyValue).build();
293         return NodeIdentifierWithPredicates.of(parentOrderedList, keys);
294     }
295
296     private NodeIdentifierWithPredicates createChildOrderedListEntryPath(final String keyValue) {
297         ImmutableMap.Builder<QName, Object> builder = ImmutableMap.builder();
298         ImmutableMap<QName, Object> keys = builder.put(childKeyLeaf, keyValue).build();
299         return NodeIdentifierWithPredicates.of(childOrderedList, keys);
300     }
301 }