Cleanup DataTree interfaces and InMemmoryDataTreeFactory
[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.model.api.SchemaContext;
36 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 public class OrderedListTest {
41     private static final Logger LOG = LoggerFactory.getLogger(OrderedListTest.class);
42
43     private DataTree inMemoryDataTree;
44     private SchemaContext context;
45
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;
55
56     @Before
57     public void setup() {
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);
69     }
70
71     @Test
72     public void testsequentialModifications() throws DataValidationFailedException {
73         modification1();
74         modification2();
75         delete1();
76         delete2();
77         modification3();
78         modification4();
79     }
80
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();
87
88         ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
89                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
90                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
91                 .build();
92
93         YangInstanceIdentifier path1 = YangInstanceIdentifier.of(parentContainer);
94
95         DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
96         treeModification.write(path1, parentContainerNode);
97
98         OrderedMapNode childOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
99                 new NodeIdentifier(childOrderedList))
100                 .withChild(createChildOrderedListEntry("chkval1", "chlfval1"))
101                 .withChild(createChildOrderedListEntry("chkval2", "chlfval2")).build();
102
103         YangInstanceIdentifier path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer)
104                 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList);
105
106         treeModification.write(path2, childOrderedListNode);
107         treeModification.ready();
108         inMemoryDataTree.validate(treeModification);
109         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
110
111         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
112         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path1);
113         assertTrue(readNode.isPresent());
114
115         readNode = snapshotAfterCommits.readNode(path2);
116         assertTrue(readNode.isPresent());
117     }
118
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();
125
126         ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
127                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
128                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
129                 .build();
130
131         DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
132
133         YangInstanceIdentifier path1 = YangInstanceIdentifier.of(parentContainer);
134         treeModification.merge(path1, parentContainerNode);
135
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();
141
142         YangInstanceIdentifier path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer)
143                 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2")).node(childOrderedList);
144         treeModification.merge(path2, childOrderedListNode);
145
146         treeModification.ready();
147         inMemoryDataTree.validate(treeModification);
148         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
149
150         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
151         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path1);
152         assertTrue(readNode.isPresent());
153
154         readNode = snapshotAfterCommits.readNode(path2);
155         assertTrue(readNode.isPresent());
156     }
157
158     public void modification3() throws DataValidationFailedException {
159         OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
160                 new NodeIdentifier(parentOrderedList))
161                 .withChild(createParentOrderedListEntry("pkval1", "plfval1")).build();
162
163         ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
164                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
165                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
166                 .build();
167
168         YangInstanceIdentifier path1 = YangInstanceIdentifier.of(parentContainer);
169
170         DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
171         treeModification.write(path1, parentContainerNode);
172
173         OrderedMapNode childOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
174                 new NodeIdentifier(childOrderedList))
175                 .withChild(createChildOrderedListEntry("chkval1", "chlfval1new")).build();
176
177         YangInstanceIdentifier path2 = YangInstanceIdentifier.of(parentContainer).node(childContainer)
178                 .node(parentOrderedList)
179                 .node(createParentOrderedListEntryPath("pkval4")).node(childOrderedList);
180
181         treeModification.merge(path2, childOrderedListNode);
182
183         try {
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"));
191         }
192
193         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
194         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path1);
195         assertTrue(readNode.isPresent());
196
197         readNode = snapshotAfterCommits.readNode(path2);
198         assertFalse(readNode.isPresent());
199     }
200
201     public void modification4() throws DataValidationFailedException {
202         DataTreeModification treeModification1 = inMemoryDataTree.takeSnapshot().newModification();
203         DataTreeModification treeModification2 = inMemoryDataTree.takeSnapshot().newModification();
204
205         OrderedMapNode parentOrderedListNode = Builders.orderedMapBuilder().withNodeIdentifier(
206             new NodeIdentifier(parentOrderedList)).withChild(createParentOrderedListEntry("pkval1", "plfval1"))
207                 .build();
208
209         OrderedMapNode parentOrderedListNode2 = Builders.orderedMapBuilder().withNodeIdentifier(
210             new NodeIdentifier(parentOrderedList)).withChild(createParentOrderedListEntry("pkval2", "plfval2"))
211                 .build();
212
213         ContainerNode parentContainerNode = Builders.containerBuilder().withNodeIdentifier(
214                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
215                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode).build())
216                 .build();
217
218         ContainerNode parentContainerNode2 = Builders.containerBuilder().withNodeIdentifier(
219                 new NodeIdentifier(parentContainer)).withChild(Builders.containerBuilder()
220                 .withNodeIdentifier(new NodeIdentifier(childContainer)).withChild(parentOrderedListNode2).build())
221                 .build();
222
223         YangInstanceIdentifier path = YangInstanceIdentifier.of(parentContainer);
224
225         treeModification1.write(path, parentContainerNode);
226         treeModification2.write(path, parentContainerNode2);
227         treeModification1.ready();
228         treeModification2.ready();
229
230         inMemoryDataTree.validate(treeModification1);
231         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification1));
232
233         try {
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"));
240         }
241
242         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
243         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path);
244         assertTrue(readNode.isPresent());
245     }
246
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"));
251
252         DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
253         treeModification.delete(path);
254         treeModification.ready();
255         inMemoryDataTree.validate(treeModification);
256         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
257
258         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
259         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path);
260         assertFalse(readNode.isPresent());
261     }
262
263     public void delete2() throws DataValidationFailedException {
264         YangInstanceIdentifier path = YangInstanceIdentifier.of(parentContainer).node(childContainer)
265                 .node(parentOrderedList).node(createParentOrderedListEntryPath("pkval2"));
266
267         DataTreeModification treeModification = inMemoryDataTree.takeSnapshot().newModification();
268         treeModification.delete(path);
269         treeModification.ready();
270         inMemoryDataTree.validate(treeModification);
271         inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
272
273         DataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
274         Optional<NormalizedNode<?, ?>> readNode = snapshotAfterCommits.readNode(path);
275         assertFalse(readNode.isPresent());
276     }
277
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();
283     }
284
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();
290     }
291
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);
296     }
297
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);
302     }
303 }