Clean up TreeNode API
[yangtools.git] / data / yang-data-tree-ri / src / test / java / org / opendaylight / yangtools / yang / data / tree / impl / Bug4295Test.java
1 /*
2  * Copyright (c) 2015 Pantheon Technologies s.r.o. 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.tree.impl;
9
10 import org.junit.jupiter.api.Test;
11 import org.opendaylight.yangtools.yang.common.QName;
12 import org.opendaylight.yangtools.yang.common.QNameModule;
13 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
14 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
15 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
16 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
17 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
18 import org.opendaylight.yangtools.yang.data.api.schema.SystemMapNode;
19 import org.opendaylight.yangtools.yang.data.api.schema.builder.CollectionNodeBuilder;
20 import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
21 import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
22 import org.opendaylight.yangtools.yang.data.tree.api.DataTree;
23 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeConfiguration;
24 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeModification;
25 import org.opendaylight.yangtools.yang.data.tree.api.DataValidationFailedException;
26 import org.opendaylight.yangtools.yang.data.tree.impl.di.InMemoryDataTreeFactory;
27 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
28
29 class Bug4295Test {
30
31     private DataTree inMemoryDataTree;
32     private QName root;
33     private QName subRoot;
34     private QName outerList;
35     private QName innerList;
36     private QName oid;
37     private QName iid;
38     private QName oleaf;
39     private QName ileaf;
40     private QNameModule foo;
41
42     @Test
43     void test() throws DataValidationFailedException {
44         foo = QNameModule.of("foo");
45         root = QName.create(foo, "root");
46         subRoot = QName.create(foo, "sub-root");
47         outerList = QName.create(foo, "outer-list");
48         innerList = QName.create(foo, "inner-list");
49         oid = QName.create(foo, "o-id");
50         iid = QName.create(foo, "i-id");
51         oleaf = QName.create(foo, "o");
52         ileaf = QName.create(foo, "i");
53         inMemoryDataTree = new InMemoryDataTreeFactory().create(DataTreeConfiguration.DEFAULT_OPERATIONAL,
54                 YangParserTestUtils.parseYang("""
55                 module foo {
56                   namespace "foo";
57                   prefix foo;
58
59                   container root {
60                     container sub-root {
61                       list outer-list {
62                         key "o-id";
63                         leaf o-id {
64                           type string;
65                         }
66                         list inner-list {
67                           key "i-id";
68                           leaf i-id {
69                             type string;
70                           }
71                           leaf i {
72                             type string;
73                           }
74                         }
75                         leaf o {
76                           type string;
77                         }
78                       }
79                     }
80                   }
81                 }"""));
82
83         firstModification();
84         secondModification(1);
85         secondModification(2);
86         secondModification(3);
87     }
88
89     private void firstModification() throws DataValidationFailedException {
90         /*  MERGE */
91         YangInstanceIdentifier path = YangInstanceIdentifier.of(root);
92         DataTreeModification modification = inMemoryDataTree.takeSnapshot().newModification();
93         modification.merge(path, createRootContainerBuilder()
94             .withChild(createSubRootContainerBuilder()
95                 .withChild(ImmutableNodes.newSystemMapBuilder()
96                     .withNodeIdentifier(NodeIdentifier.create(outerList))
97                     .withChild(createOuterListEntry("1", "o-1"))
98                     .withChild(createOuterListEntry("2", "o-2"))
99                     .withChild(createOuterListEntry("3", "o-3"))
100                     .build())
101                 .build())
102             .build());
103
104         /*  WRITE INNER LIST WITH ENTRIES*/
105         path = YangInstanceIdentifier.of(root).node(subRoot).node(outerList).node(createOuterListEntryPath("2"))
106                 .node(innerList);
107         modification.write(path, createInnerListBuilder()
108             .withChild(createInnerListEntry("a", "i-a"))
109             .withChild(createInnerListEntry("b", "i-b"))
110             .build());
111
112         /*  COMMIT */
113         modification.ready();
114         inMemoryDataTree.validate(modification);
115         inMemoryDataTree.commit(inMemoryDataTree.prepare(modification));
116     }
117
118     private void secondModification(final int testScenarioNumber) throws DataValidationFailedException {
119         /*  MERGE */
120         ContainerNode rootContainerNode = createRootContainerBuilder()
121             .withChild(createSubRootContainerBuilder()
122                 .withChild(ImmutableNodes.newSystemMapBuilder()
123                     .withNodeIdentifier(NodeIdentifier.create(outerList))
124                     .withChild(createOuterListEntry("3", "o-3"))
125                     .withChild(createOuterListEntry("4", "o-4"))
126                     .withChild(createOuterListEntry("5", "o-5"))
127                     .build())
128                 .build())
129             .build();
130
131         YangInstanceIdentifier path = YangInstanceIdentifier.of(root);
132         DataTreeModification modification = inMemoryDataTree.takeSnapshot().newModification();
133         modification.merge(path, rootContainerNode);
134
135         switch (testScenarioNumber) {
136             case 1:
137                 /* WRITE EMPTY INNER LIST */
138                 writeEmptyInnerList(modification, "2");
139                 break;
140             case 2: {
141                 /* WRITE INNER LIST ENTRY */
142                 MapEntryNode innerListEntryA = createInnerListEntry("a", "i-a-2");
143                 path = YangInstanceIdentifier.of(root, subRoot, outerList).node(createOuterListEntryPath("2"))
144                     .node(innerList).node(createInnerListEntryPath("a"));
145                 modification.write(path, innerListEntryA);
146                 break;
147             }
148             case 3: {
149                 /* WRITE INNER LIST WITH ENTRIES */
150                 path = YangInstanceIdentifier.of(root, subRoot, outerList).node(createOuterListEntryPath("2"))
151                     .node(innerList);
152                 modification.write(path, createInnerListBuilder()
153                     .withChild(createInnerListEntry("a", "i-a-3"))
154                     .withChild(createInnerListEntry("c", "i-c"))
155                     .build());
156                 break;
157             }
158             default:
159                 break;
160         }
161
162         /*  COMMIT */
163         modification.ready();
164         inMemoryDataTree.validate(modification);
165         inMemoryDataTree.commit(inMemoryDataTree.prepare(modification));
166     }
167
168     private void writeEmptyInnerList(final DataTreeModification modification, final String outerListEntryKey) {
169         YangInstanceIdentifier path = YangInstanceIdentifier.of(root, subRoot, outerList)
170                 .node(createOuterListEntryPath(outerListEntryKey)).node(innerList);
171         modification.write(path, createInnerListBuilder().build());
172     }
173
174     private DataContainerNodeBuilder<NodeIdentifier, ContainerNode> createRootContainerBuilder() {
175         return ImmutableNodes.newContainerBuilder().withNodeIdentifier(new NodeIdentifier(root));
176     }
177
178     private DataContainerNodeBuilder<NodeIdentifier, ContainerNode> createSubRootContainerBuilder() {
179         return  ImmutableNodes.newContainerBuilder().withNodeIdentifier(new NodeIdentifier(subRoot));
180     }
181
182     private CollectionNodeBuilder<MapEntryNode, SystemMapNode> createInnerListBuilder() {
183         return ImmutableNodes.newSystemMapBuilder().withNodeIdentifier(NodeIdentifier.create(innerList));
184     }
185
186     private NodeIdentifierWithPredicates createInnerListEntryPath(final String keyValue) {
187         return NodeIdentifierWithPredicates.of(innerList, iid, keyValue);
188     }
189
190     private NodeIdentifierWithPredicates createOuterListEntryPath(final String keyValue) {
191         return NodeIdentifierWithPredicates.of(outerList, oid, keyValue);
192     }
193
194     private MapEntryNode createOuterListEntry(final String keyValue, final String leafValue) {
195         return ImmutableNodes.newMapEntryBuilder()
196             .withNodeIdentifier(NodeIdentifierWithPredicates.of(outerList, oid, keyValue))
197             .withChild(ImmutableNodes.leafNode(oid, keyValue))
198             .withChild(ImmutableNodes.leafNode(oleaf, leafValue))
199             .build();
200     }
201
202     private MapEntryNode createInnerListEntry(final String keyValue, final String leafValue) {
203         return ImmutableNodes.newMapEntryBuilder()
204             .withNodeIdentifier(NodeIdentifierWithPredicates.of(innerList, iid, keyValue))
205             .withChild(ImmutableNodes.leafNode(iid, keyValue))
206             .withChild(ImmutableNodes.leafNode(ileaf, leafValue))
207             .build();
208     }
209 }