Bug 2690 - Yang-Data-Impl: write and then merge on same list in
[yangtools.git] / yang / yang-data-impl / src / test / java / org / opendaylight / yangtools / yang / data / impl / leafref / context / test / DataTreeCandidateValidatorTest3.java
1 /**
2  * Copyright (c) 2015 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.leafref.context.test;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertTrue;
12
13 import java.io.File;
14 import java.io.IOException;
15 import java.net.URISyntaxException;
16 import java.util.Set;
17 import org.apache.log4j.BasicConfigurator;
18 import org.junit.BeforeClass;
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.LeafNode;
27 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
28 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
29 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
30 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
31 import org.opendaylight.yangtools.yang.data.api.schema.tree.TipProducingDataTree;
32 import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefContext;
33 import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefDataValidationFailedException;
34 import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefValidatation;
35 import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefYangSyntaxErrorException;
36 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
37 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
38 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
39 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
40 import org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTreeFactory;
41 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
42 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
43 import org.opendaylight.yangtools.yang.model.api.Module;
44 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
45 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
46 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 public class DataTreeCandidateValidatorTest3 {
51
52     private static SchemaContext context;
53     private static Module mainModule;
54     private static QNameModule rootModuleQname;
55     private static LeafRefContext rootLeafRefContext;
56     public static TipProducingDataTree inMemoryDataTree;
57
58     private static QName chips;
59     private static QName chip;
60     private static QName devType;
61     private static QName chipDesc;
62
63     private static QName devices;
64     private static QName device;
65     private static QName typeText1;
66     private static QName typeText2;
67     private static QName typeText3;
68     private static QName devDesc;
69     private static QName sn;
70     private static QName defaultIp;
71
72     private static QName deviceTypeStr;
73     private static QName deviceType;
74     private static QName type1;
75     private static QName type2;
76     private static QName type3;
77     private static QName desc;
78
79     private static final Logger LOG = LoggerFactory.getLogger("");
80     private static final String NEW_LINE = System.getProperty("line.separator");
81
82     static {
83         BasicConfigurator.configure();
84     }
85
86     @BeforeClass
87     public static void init() throws URISyntaxException, IOException,
88             YangSyntaxErrorException, LeafRefYangSyntaxErrorException {
89
90         initSchemaContext();
91         initLeafRefContext();
92         initQnames();
93         initDataTree();
94     }
95
96     @Test
97     public void dataTreeCanditateValidationTest2() {
98
99         writeDevices();
100
101         mergeDevices();
102     }
103
104     private static void writeDevices() {
105
106         final ContainerSchemaNode devicesContSchemaNode = (ContainerSchemaNode) mainModule
107                 .getDataChildByName(devices);
108
109         final ContainerNode devicesContainer = createDevicesContainer(devicesContSchemaNode);
110
111         final YangInstanceIdentifier devicesPath = YangInstanceIdentifier.of(devices);
112         final DataTreeModification writeModification = inMemoryDataTree
113                 .takeSnapshot().newModification();
114         writeModification.write(devicesPath, devicesContainer);
115
116         final DataTreeCandidate writeDevicesCandidate = inMemoryDataTree
117                 .prepare(writeModification);
118
119         LOG.debug("*************************");
120         LOG.debug("Before writeDevices: ");
121         LOG.debug("*************************");
122         LOG.debug(inMemoryDataTree.toString());
123
124         boolean exception = false;
125         try {
126             LeafRefValidatation.validate(writeDevicesCandidate, rootLeafRefContext);
127         } catch (final LeafRefDataValidationFailedException e) {
128             LOG.debug("All validation errors:" + NEW_LINE + e.getMessage());
129             assertEquals(6, e.getValidationsErrorsCount());
130             exception = true;
131         }
132
133         assertTrue(exception);
134
135         inMemoryDataTree.commit(writeDevicesCandidate);
136
137         LOG.debug("*************************");
138         LOG.debug("After writeDevices: ");
139         LOG.debug("*************************");
140         LOG.debug(inMemoryDataTree.toString());
141     }
142
143     private static void mergeDevices() {
144
145         final ContainerSchemaNode devicesContSchemaNode = (ContainerSchemaNode) mainModule
146                 .getDataChildByName(devices);
147
148         final ContainerNode devicesContainer = createDevices2Container(devicesContSchemaNode);
149
150         final YangInstanceIdentifier devicesPath = YangInstanceIdentifier.of(devices);
151         final DataTreeModification mergeModification = inMemoryDataTree
152                 .takeSnapshot().newModification();
153         mergeModification.write(devicesPath, devicesContainer);
154         mergeModification.merge(devicesPath, devicesContainer);
155
156         final DataTreeCandidate mergeDevicesCandidate = inMemoryDataTree
157                 .prepare(mergeModification);
158
159         LOG.debug("*************************");
160         LOG.debug("Before mergeDevices: ");
161         LOG.debug("*************************");
162         LOG.debug(inMemoryDataTree.toString());
163
164         boolean exception = false;
165         try {
166             LeafRefValidatation.validate(mergeDevicesCandidate, rootLeafRefContext);
167         } catch (final LeafRefDataValidationFailedException e) {
168             LOG.debug("All validation errors:" + NEW_LINE + e.getMessage());
169             // :TODO verify errors count gz
170             assertEquals(6, e.getValidationsErrorsCount());
171             exception = true;
172         }
173
174         inMemoryDataTree.commit(mergeDevicesCandidate);
175
176         LOG.debug("*************************");
177         LOG.debug("After mergeDevices: ");
178         LOG.debug("*************************");
179         LOG.debug(inMemoryDataTree.toString());
180
181         assertTrue(exception);
182     }
183
184     private static void initQnames() {
185
186         chips = QName.create(rootModuleQname, "chips");
187         chip = QName.create(rootModuleQname, "chip");
188         devType = QName.create(rootModuleQname, "dev_type");
189         chipDesc = QName.create(rootModuleQname, "chip_desc");
190
191         devices = QName.create(rootModuleQname, "devices");
192         device = QName.create(rootModuleQname, "device");
193         typeText1 = QName.create(rootModuleQname, "type_text1");
194         typeText2 = QName.create(rootModuleQname, "type_text2");
195         typeText3 = QName.create(rootModuleQname, "type_text3");
196         devDesc = QName.create(rootModuleQname, "dev_desc");
197         sn = QName.create(rootModuleQname, "sn");
198         defaultIp = QName.create(rootModuleQname, "default_ip");
199
200         deviceTypeStr = QName.create(rootModuleQname, "device_types");
201         deviceType = QName.create(rootModuleQname, "device_type");
202         type1 = QName.create(rootModuleQname, "type1");
203         type2 = QName.create(rootModuleQname, "type2");
204         type3 = QName.create(rootModuleQname, "type3");
205         desc = QName.create(rootModuleQname, "desc");
206     }
207
208     private static void initSchemaContext() throws URISyntaxException,
209             IOException, YangSyntaxErrorException {
210
211         final File resourceFile = new File(DataTreeCandidateValidatorTest.class
212                 .getResource("/leafref-validation/leafref-validation3.yang")
213                 .toURI());
214         final File resourceDir = resourceFile.getParentFile();
215
216         final YangParserImpl parser = YangParserImpl.getInstance();
217         context = parser.parseFile(resourceFile, resourceDir);
218
219         final Set<Module> modules = context.getModules();
220         for (final Module module : modules) {
221             if (module.getName().equals("leafref-validation3")) {
222                 mainModule = module;
223             }
224         }
225
226         rootModuleQname = mainModule.getQNameModule();
227     }
228
229     private static void initDataTree() {
230
231         inMemoryDataTree = InMemoryDataTreeFactory.getInstance().create();
232         inMemoryDataTree.setSchemaContext(context);
233
234         final DataTreeModification initialDataTreeModification = inMemoryDataTree
235                 .takeSnapshot().newModification();
236
237         final ContainerSchemaNode chipsListContSchemaNode = (ContainerSchemaNode) mainModule
238                 .getDataChildByName(chips);
239         final ContainerNode chipsContainer = createChipsContainer(chipsListContSchemaNode);
240         final YangInstanceIdentifier path1 = YangInstanceIdentifier.of(chips);
241         initialDataTreeModification.write(path1, chipsContainer);
242
243         final ContainerSchemaNode devTypesListContSchemaNode = (ContainerSchemaNode) mainModule
244                 .getDataChildByName(deviceTypeStr);
245         final ContainerNode deviceTypesContainer = createDevTypeStrContainer(devTypesListContSchemaNode);
246         final YangInstanceIdentifier path2 = YangInstanceIdentifier.of(deviceTypeStr);
247         initialDataTreeModification.write(path2, deviceTypesContainer);
248
249         final DataTreeCandidate writeChipsCandidate = inMemoryDataTree
250                 .prepare(initialDataTreeModification);
251
252         inMemoryDataTree.commit(writeChipsCandidate);
253
254         System.out.println(inMemoryDataTree.toString());
255     }
256
257     private static void initLeafRefContext() throws IOException,
258             LeafRefYangSyntaxErrorException {
259         rootLeafRefContext = LeafRefContext.create(context);
260     }
261
262     private static ContainerNode createDevTypeStrContainer(
263             final ContainerSchemaNode container) {
264
265         final ListSchemaNode devTypeListSchemaNode = (ListSchemaNode) container
266                 .getDataChildByName(deviceType);
267
268         final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> devTypeContainerBldr = Builders
269                 .containerBuilder(container);
270
271         final MapNode devTypeMap = createDevTypeList(devTypeListSchemaNode);
272         devTypeContainerBldr.addChild(devTypeMap);
273
274         return devTypeContainerBldr.build();
275     }
276
277     private static MapNode createDevTypeList(
278             final ListSchemaNode devTypeListSchemaNode) {
279
280         final CollectionNodeBuilder<MapEntryNode, MapNode> devTypeMapBldr = Builders
281                 .mapBuilder(devTypeListSchemaNode);
282
283         devTypeMapBldr.addChild(createDevTypeListEntry("dev_type1_1",
284                 "dev_type2_1", "dev_type3_1", "typedesc1",
285                 devTypeListSchemaNode));
286         devTypeMapBldr.addChild(createDevTypeListEntry("dev_type1_2",
287                 "dev_type2_2", "dev_type3_2", "typedesc2",
288                 devTypeListSchemaNode));
289         devTypeMapBldr.addChild(createDevTypeListEntry("dev_type1_3",
290                 "dev_type2_3", "dev_type3_3", "typedesc3",
291                 devTypeListSchemaNode));
292
293         return devTypeMapBldr.build();
294     }
295
296     private static MapEntryNode createDevTypeListEntry(final String type1Val,
297             final String type2Val, final String type3Val, final String descVal,
298             final ListSchemaNode devTypeListSchemaNode) {
299
300         final LeafNode<String> type1Leaf = ImmutableNodes.leafNode(type1, type1Val);
301         final LeafNode<String> type2Leaf = ImmutableNodes.leafNode(type2, type2Val);
302         final LeafNode<String> type3Leaf = ImmutableNodes.leafNode(type3, type3Val);
303         final LeafNode<String> descLeaf = ImmutableNodes.leafNode(desc, descVal);
304
305         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> devTypeMapEntryBldr = Builders
306                 .mapEntryBuilder(devTypeListSchemaNode);
307
308         devTypeMapEntryBldr.addChild(type1Leaf);
309         devTypeMapEntryBldr.addChild(type2Leaf);
310         devTypeMapEntryBldr.addChild(type3Leaf);
311         devTypeMapEntryBldr.addChild(descLeaf);
312
313         return devTypeMapEntryBldr.build();
314     }
315
316     private static ContainerNode createChipsContainer(
317             final ContainerSchemaNode container) {
318
319         final ListSchemaNode chipsListSchemaNode = (ListSchemaNode) container
320                 .getDataChildByName(chip);
321
322         final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> chipsContainerBldr = Builders
323                 .containerBuilder(container);
324
325         final MapNode chipsMap = createChipsList(chipsListSchemaNode);
326         chipsContainerBldr.addChild(chipsMap);
327
328         return chipsContainerBldr.build();
329     }
330
331     private static MapNode createChipsList(final ListSchemaNode chipsListSchemaNode) {
332
333         final CollectionNodeBuilder<MapEntryNode, MapNode> chipsMapBldr = Builders
334                 .mapBuilder(chipsListSchemaNode);
335
336         chipsMapBldr.addChild(createChipsListEntry("dev_type_1", "desc1",
337                 chipsListSchemaNode));
338         chipsMapBldr.addChild(createChipsListEntry("dev_type_2", "desc2",
339                 chipsListSchemaNode));
340
341         return chipsMapBldr.build();
342     }
343
344     private static MapEntryNode createChipsListEntry(final String devTypeVal,
345             final String chipDescVal, final ListSchemaNode chipsListSchemaNode) {
346
347         final LeafNode<String> devTypeLeaf = ImmutableNodes.leafNode(devType,
348                 devTypeVal);
349         final LeafNode<String> chipDescLeaf = ImmutableNodes.leafNode(chipDesc,
350                 chipDescVal);
351
352         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> chipsMapEntryBldr = Builders
353                 .mapEntryBuilder(chipsListSchemaNode);
354
355         chipsMapEntryBldr.addChild(devTypeLeaf);
356         chipsMapEntryBldr.addChild(chipDescLeaf);
357
358         return chipsMapEntryBldr.build();
359     }
360
361     private static ContainerNode createDevicesContainer(
362             final ContainerSchemaNode container) {
363
364         final ListSchemaNode devicesListSchemaNode = (ListSchemaNode) container
365                 .getDataChildByName(device);
366
367         final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> devicesContainerBldr = Builders
368                 .containerBuilder(container);
369
370         final MapNode devicesMap = createDeviceList(devicesListSchemaNode);
371         devicesContainerBldr.addChild(devicesMap);
372
373         return devicesContainerBldr.build();
374     }
375
376     private static MapNode createDeviceList(final ListSchemaNode deviceListSchemaNode) {
377
378         final CollectionNodeBuilder<MapEntryNode, MapNode> devicesMapBldr = Builders
379                 .mapBuilder(deviceListSchemaNode);
380
381         devicesMapBldr.addChild(createDeviceListEntry("dev_type1_1",
382                 "dev_type2_1", "dev_type3_1", "typedesc1", 123456,
383                 "192.168.0.1", deviceListSchemaNode));
384         devicesMapBldr.addChild(createDeviceListEntry("dev_type1_2",
385                 "dev_type2_2", "dev_type3_2", "typedesc1", 123457,
386                 "192.168.0.1", deviceListSchemaNode));
387         devicesMapBldr.addChild(createDeviceListEntry("dev_type1_1",
388                 "dev_type2_2", "dev_type3_3", "typedesc2", 123458,
389                 "192.168.0.1", deviceListSchemaNode));
390         devicesMapBldr.addChild(createDeviceListEntry("unk11", "unk22",
391                 "unk33", "unk_desc2", 123457, "192.168.0.1",
392                 deviceListSchemaNode));
393
394         return devicesMapBldr.build();
395     }
396
397     private static ContainerNode createDevices2Container(
398             final ContainerSchemaNode container) {
399
400         final ListSchemaNode devicesListSchemaNode = (ListSchemaNode) container
401                 .getDataChildByName(device);
402
403         final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> devicesContainerBldr = Builders
404                 .containerBuilder(container);
405
406         final MapNode devicesMap = createDevice2List(devicesListSchemaNode);
407         devicesContainerBldr.addChild(devicesMap);
408
409         return devicesContainerBldr.build();
410     }
411
412     private static MapNode createDevice2List(final ListSchemaNode deviceListSchemaNode) {
413
414         final CollectionNodeBuilder<MapEntryNode, MapNode> devicesMapBldr = Builders
415                 .mapBuilder(deviceListSchemaNode);
416
417         devicesMapBldr.addChild(createDeviceListEntry("dev_type1_3",
418                 "dev_type2_3", "dev_type3_3", "typedesc3", 123459,
419                 "192.168.0.1", deviceListSchemaNode));
420         devicesMapBldr.addChild(createDeviceListEntry("dev_type1_3",
421                 "dev_type2_3", "dev_type3_3", "typedesc2", 123460,
422                 "192.168.0.1", deviceListSchemaNode));
423         devicesMapBldr.addChild(createDeviceListEntry("dev_type1_3",
424                 "dev_type2_2", "dev_type3_1", "typedesc1", 123461,
425                 "192.168.0.1", deviceListSchemaNode));
426         devicesMapBldr.addChild(createDeviceListEntry("unk1", "unk2", "unk3",
427                 "unk_desc", 123462, "192.168.0.1", deviceListSchemaNode));
428
429         return devicesMapBldr.build();
430     }
431
432     private static MapEntryNode createDeviceListEntry(final String type1TextVal,
433             final String type2TextVal, final String type3TextVal, final String descVal,
434             final int snVal, final String defaultIpVal, final ListSchemaNode devicesListSchemaNode) {
435
436         final LeafNode<String> typeText1Leaf = ImmutableNodes.leafNode(typeText1,
437                 type1TextVal);
438         final LeafNode<String> typeText2Leaf = ImmutableNodes.leafNode(typeText2,
439                 type2TextVal);
440         final LeafNode<String> typeText3Leaf = ImmutableNodes.leafNode(typeText3,
441                 type3TextVal);
442         final LeafNode<String> descLeaf = ImmutableNodes.leafNode(devDesc, descVal);
443         final LeafNode<Integer> snValLeaf = ImmutableNodes.leafNode(sn, snVal);
444         final LeafNode<String> defaultIpLeaf = ImmutableNodes.leafNode(defaultIp,
445                 defaultIpVal);
446
447         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> devicesMapEntryBldr = Builders
448                 .mapEntryBuilder(devicesListSchemaNode);
449
450         devicesMapEntryBldr.addChild(typeText1Leaf);
451         devicesMapEntryBldr.addChild(typeText2Leaf);
452         devicesMapEntryBldr.addChild(typeText3Leaf);
453         devicesMapEntryBldr.addChild(descLeaf);
454         devicesMapEntryBldr.addChild(snValLeaf);
455         devicesMapEntryBldr.addChild(defaultIpLeaf);
456
457         return devicesMapEntryBldr.build();
458     }
459 }