Bump odlparent dependencies to 3.0.0
[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
9 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
10
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertTrue;
13 import static org.junit.Assert.fail;
14
15 import com.google.common.collect.ImmutableMap;
16 import java.net.URI;
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;
40
41 public class OrderedListTest {
42     private static final Logger LOG = LoggerFactory.getLogger(OrderedListTest.class);
43
44     private TipProducingDataTree inMemoryDataTree;
45     private SchemaContext context;
46
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;
56
57     @Before
58     public void setup() {
59         context = YangParserTestUtils.parseYangResource("/ordered-list-modification-test.yang");
60         testModule = QNameModule.create(URI.create("ordered-list-modification-test"));
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);
71     }
72
73     @Test
74     public void testsequentialModifications() throws DataValidationFailedException {
75         modification1();
76         modification2();
77         delete1();
78         delete2();
79         modification3();
80         modification4();
81     }
82
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();
89
90         ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
91                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
92                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
93                 .build();
94
95         YangInstanceIdentifier path1 = YangInstanceIdentifier.of(parentContainer);
96
97         DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
98         treeModification.write(path1, parentContainerNode);
99
100         OrderedMapNode childOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
101                 new NodeIdentifier(childOrderedList))
102                 .withChild(createChildOrderedListEntry("chkval1", "chlfval1"))
103                 .withChild(createChildOrderedListEntry("chkval2", "chlfval2")).build();
104
105         YangInstanceIdentifier path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer)
106                 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList);
107
108         treeModification.write(path2, childOrderedListNode);
109         treeModification.ready();
110         inMemoryDataTree.validate(treeModification);
111         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
112
113         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
114         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path1);
115         assertTrue(readNode.isPresent());
116
117         readNode = snapshotAfterCommits.readNode(path2);
118         assertTrue(readNode.isPresent());
119     }
120
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();
127
128         ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
129                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
130                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
131                 .build();
132
133         DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
134
135         YangInstanceIdentifier path1 = YangInstanceIdentifier.of(parentContainer);
136         treeModification.merge(path1, parentContainerNode);
137
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();
143
144         YangInstanceIdentifier path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer)
145                 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList);
146         treeModification.merge(path2, childOrderedListNode);
147
148         treeModification.ready();
149         inMemoryDataTree.validate(treeModification);
150         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
151
152         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
153         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path1);
154         assertTrue(readNode.isPresent());
155
156         readNode = snapshotAfterCommits.readNode(path2);
157         assertTrue(readNode.isPresent());
158     }
159
160     public void modification3() throws DataValidationFailedException {
161         OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
162                 new NodeIdentifier(parentOrderedList))
163                 .withChild(createParentOrderedListEntry("pkval1", "plfval1")).build();
164
165         ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
166                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
167                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
168                 .build();
169
170         YangInstanceIdentifier path1 = YangInstanceIdentifier.of(parentContainer);
171
172         DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
173         treeModification.write(path1, parentContainerNode);
174
175         OrderedMapNode childOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
176                 new NodeIdentifier(childOrderedList))
177                 .withChild(createChildOrderedListEntry("chkval1", "chlfval1new")).build();
178
179         YangInstanceIdentifier path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer)
180                 .node(parentOrderedList)
181                 .node(createParentOrderedListEntryPath("pkval4")).node(childOrderedList);
182
183         treeModification.merge(path2, childOrderedListNode);
184
185         try {
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"));
193         }
194
195         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
196         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path1);
197         assertTrue(readNode.isPresent());
198
199         readNode = snapshotAfterCommits.readNode(path2);
200         assertFalse(readNode.isPresent());
201     }
202
203     public void modification4() throws DataValidationFailedException {
204         DataTreeModification treeModification1 = inMemoryDataTree.takeSnapshot().newModification();
205         DataTreeModification treeModification2 = inMemoryDataTree.takeSnapshot().newModification();
206
207         OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
208             new NodeIdentifier(parentOrderedList)).withChild(createParentOrderedListEntry("pkval1", "plfval1"))
209                 .build();
210
211         OrderedMapNode parentOrderedListNode2 = Builders.orderedMapBuilder().withNodeIdentifier(
212             new NodeIdentifier(parentOrderedList)).withChild(createParentOrderedListEntry("pkval2", "plfval2"))
213                 .build();
214
215         ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
216                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
217                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
218                 .build();
219
220         ContainerNode parentContainerNode2 = Builders.containerBuilder().withNodeIdentifier(
221                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
222                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode2).build())
223                 .build();
224
225         YangInstanceIdentifier path = YangInstanceIdentifier.of(parentContainer);
226
227         treeModification1.write(path, parentContainerNode);
228         treeModification2.write(path, parentContainerNode2);
229         treeModification1.ready();
230         treeModification2.ready();
231
232         inMemoryDataTree.validate(treeModification1);
233         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification1));
234
235         try {
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"));
242         }
243
244         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
245         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path);
246         assertTrue(readNode.isPresent());
247     }
248
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"));
253
254         DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
255         treeModification.delete(path);
256         treeModification.ready();
257         inMemoryDataTree.validate(treeModification);
258         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
259
260         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
261         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path);
262         assertFalse(readNode.isPresent());
263     }
264
265     public void delete2() throws DataValidationFailedException {
266         YangInstanceIdentifier path = YangInstanceIdentifier.of(parentContainer).node(childContainer)
267                 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2"));
268
269         DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
270         treeModification.delete(path);
271         treeModification.ready();
272         inMemoryDataTree.validate(treeModification);
273         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
274
275         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
276         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path);
277         assertFalse(readNode.isPresent());
278     }
279
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();
285     }
286
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();
292     }
293
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);
298     }
299
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);
304     }
305 }