bd852e288b88b80f826ed4ff58e00d311d07417c
[yangtools.git] / yang / yang-data-codec-gson / src / test / java / org / opendaylight / yangtools / yang / data / codec / gson / JsonStreamToNormalizedNodeTest.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.codec.gson;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertTrue;
13 import static org.junit.Assert.fail;
14 import static org.opendaylight.yangtools.yang.data.codec.gson.TestUtils.loadTextFile;
15 import static org.opendaylight.yangtools.yang.data.impl.schema.Builders.augmentationBuilder;
16 import static org.opendaylight.yangtools.yang.data.impl.schema.Builders.choiceBuilder;
17 import static org.opendaylight.yangtools.yang.data.impl.schema.Builders.containerBuilder;
18 import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.leafNode;
19
20 import com.google.common.collect.Sets;
21 import com.google.gson.stream.JsonReader;
22 import java.io.IOException;
23 import java.io.StringReader;
24 import java.net.URISyntaxException;
25 import org.junit.BeforeClass;
26 import org.junit.Test;
27 import org.opendaylight.yangtools.yang.common.QName;
28 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
29 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
30 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
31 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
32 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
33 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
34 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
35 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
36 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
37 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
38
39 /**
40  * Each test tests whether json input is correctly transformed to normalized node structure.
41  */
42 public class JsonStreamToNormalizedNodeTest {
43
44     private static final QName CONT_1 = QName.create("ns:complex:json", "2014-08-11", "cont1");
45     private static final QName EMPTY_LEAF = QName.create(CONT_1,"empty");
46     private static SchemaContext schemaContext;
47
48     @BeforeClass
49     public static void initialization() throws IOException, URISyntaxException, ReactorException {
50         schemaContext = YangParserTestUtils.parseYangSources("/complexjson/yang");
51     }
52
53     @Test
54     public void leafNodeInContainer() throws IOException, URISyntaxException {
55         final String inputJson = loadTextFile("/complexjson/leaf-node-in-container.json");
56         verifyTransformationToNormalizedNode(inputJson, TestingNormalizedNodeStructuresCreator.leafNodeInContainer());
57     }
58
59     @Test
60     public void leafNodeViaAugmentationInContainer() throws IOException, URISyntaxException {
61         final String inputJson = loadTextFile("/complexjson/leaf-node-via-augmentation-in-container.json");
62         verifyTransformationToNormalizedNode(inputJson,
63                 TestingNormalizedNodeStructuresCreator.leafNodeViaAugmentationInContainer());
64     }
65
66     @Test
67     public void leafListNodeInContainer() throws IOException, URISyntaxException {
68         final String inputJson = loadTextFile("/complexjson/leaflist-node-in-container.json");
69         verifyTransformationToNormalizedNode(inputJson,
70                 TestingNormalizedNodeStructuresCreator.leafListNodeInContainer());
71     }
72
73     @Test
74     public void keyedListNodeInContainer() throws IOException, URISyntaxException {
75         final String inputJson = loadTextFile("/complexjson/keyed-list-node-in-container.json");
76         verifyTransformationToNormalizedNode(inputJson,
77                 TestingNormalizedNodeStructuresCreator.keyedListNodeInContainer());
78     }
79
80     @Test
81     public void choiceNodeInContainer() throws IOException, URISyntaxException {
82         final String inputJson = loadTextFile("/complexjson/choice-node-in-container.json");
83         verifyTransformationToNormalizedNode(inputJson, TestingNormalizedNodeStructuresCreator.choiceNodeInContainer());
84     }
85
86     /**
87      * Test of translating internal augmentations to normalized nodes structure.
88      *
89      * <p>
90      * 2 nodes are added via internal augmentation A, 1 node via internal augmentation B and one node is originally
91      * member of case.
92      */
93     @Test
94     public void caseNodeAugmentationInChoiceInContainer() throws IOException, URISyntaxException {
95         final String inputJson = loadTextFile("/complexjson/case-node-augmentation-in-choice-in-container.json");
96         verifyTransformationToNormalizedNode(inputJson,
97                 TestingNormalizedNodeStructuresCreator.caseNodeAugmentationInChoiceInContainer());
98     }
99
100     /**
101      * also test using of namesakes (equal local names with different.
102      */
103     @Test
104     public void caseNodeExternalAugmentationInChoiceInContainer() throws IOException, URISyntaxException {
105         final String inputJson =
106                 loadTextFile("/complexjson/case-node-external-augmentation-in-choice-in-container.json");
107         verifyTransformationToNormalizedNode(inputJson,
108                 TestingNormalizedNodeStructuresCreator.caseNodeExternalAugmentationInChoiceInContainer());
109     }
110
111     /**
112      * augmentation of choice - adding new case.
113      */
114     @Test
115     public void choiceNodeAugmentationInContainer() throws IOException, URISyntaxException {
116         final String inputJson = loadTextFile("/complexjson/choice-node-augmentation-in-container.json");
117         verifyTransformationToNormalizedNode(inputJson,
118                 TestingNormalizedNodeStructuresCreator.choiceNodeAugmentationInContainer());
119     }
120
121     @Test
122     public void unkeyedNodeInContainer() throws IOException, URISyntaxException {
123         final String inputJson = loadTextFile("/complexjson/unkeyed-node-in-container.json");
124         verifyTransformationToNormalizedNode(inputJson,
125             TestingNormalizedNodeStructuresCreator.unkeyedNodeInContainer());
126     }
127
128     /**
129      * Top level JSON element contains no information about module name.
130      *
131      * <p>
132      * It should be possible to find out potential module name from available schema context.
133      */
134     @Test
135     public void missingModuleInfoInTopLevelElement() throws IOException, URISyntaxException {
136         final String inputJson = loadTextFile("/complexjson/missing-module-in-top-level.json");
137         verifyTransformationToNormalizedNode(inputJson, TestingNormalizedNodeStructuresCreator.topLevelContainer());
138     }
139
140     /**
141      * Exception expected.
142      *
143      * <p>
144      * It tests case when several elements with the same name and various namespaces exists and are in JSON specified
145      * without module name prefix.
146      */
147     @Test
148     public void leafNamesakes() throws IOException, URISyntaxException {
149         final String inputJson = loadTextFile("/complexjson/namesakes.json");
150         try {
151             //second parameter isn't necessary because error will be raised before it is used.
152             verifyTransformationToNormalizedNode(inputJson, null);
153             fail("Expected exception not raised");
154         } catch (final IllegalStateException e) {
155             final String errorMessage = e.getMessage();
156             assertTrue(errorMessage.contains("Choose suitable module name for element lf11-namesake:"));
157             assertTrue(errorMessage.contains("complexjson-augmentation"));
158             assertTrue(errorMessage.contains("complexjson-augmentation-namesake"));
159         }
160     }
161
162     @Test
163     public void emptyTypeTest() throws IOException, URISyntaxException {
164         final String inputJson = loadTextFile("/complexjson/type-empty.json");
165         final ContainerNode awaitedStructure = containerBuilder()
166                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(CONT_1))
167                 .addChild(leafNode(EMPTY_LEAF, null))
168                 .build();
169
170         verifyTransformationToNormalizedNode(inputJson, awaitedStructure);
171     }
172
173     /**
174      * Exception expected.
175      *
176      * <p>
177      * Json input contains element which doesn't exist in YANG schema
178      */
179     @Test
180     public void parsingNotExistingElement() throws IOException, URISyntaxException {
181         final String inputJson = loadTextFile("/complexjson/not-existing-element.json");
182         try {
183             //second parameter isn't necessary because error will be raised before it is used.
184             verifyTransformationToNormalizedNode(inputJson, null);
185         } catch (final IllegalStateException e) {
186             assertTrue(e.getMessage().contains("Schema node with name dummy-element was not found"));
187         }
188     }
189
190     @Test
191     public void listItemWithoutArray() throws IOException, URISyntaxException {
192         final String inputJson = loadTextFile("/complexjson/keyed-list-restconf-behaviour.json");
193
194         final NormalizedNodeResult result = new NormalizedNodeResult();
195         final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
196         final SchemaNode parentNode = schemaContext.getDataChildByName(CONT_1);
197         final JsonParserStream jsonParser = JsonParserStream.create(streamWriter, schemaContext, parentNode);
198         jsonParser.parse(new JsonReader(new StringReader(inputJson)));
199         final NormalizedNode<?, ?> transformedInput = result.getResult();
200         assertNotNull(transformedInput);
201     }
202
203     @Test
204     public void listItemWithArray() throws IOException, URISyntaxException {
205         final String inputJson = loadTextFile("/complexjson/keyed-list-yang-json-behaviour.json");
206
207         final NormalizedNodeResult result = new NormalizedNodeResult();
208         final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
209         final SchemaNode parentNode = schemaContext.getDataChildByName(CONT_1);
210         final JsonParserStream jsonParser = JsonParserStream.create(streamWriter, schemaContext, parentNode);
211         jsonParser.parse(new JsonReader(new StringReader(inputJson)));
212         final NormalizedNode<?, ?> transformedInput = result.getResult();
213         assertNotNull(transformedInput);
214     }
215
216     @Test
217     public void multipleChoiceAugmentation() throws IOException, URISyntaxException {
218         final String inputJson = loadTextFile("/complexjson/multiple-choice-augmentation-in-container.json");
219
220         final NormalizedNodeResult result = new NormalizedNodeResult();
221         final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
222         final SchemaNode parentNode = schemaContext.getDataChildByName(CONT_1);
223
224         final QName augmentChoice1QName = QName.create(parentNode.getQName(), "augment-choice1");
225         final QName augmentChoice2QName = QName.create(augmentChoice1QName, "augment-choice2");
226         final QName containerQName = QName.create(augmentChoice1QName, "case11-choice-case-container");
227         final QName leafQName = QName.create(augmentChoice1QName, "case11-choice-case-leaf");
228
229         final YangInstanceIdentifier.AugmentationIdentifier aug1Id =
230                 new YangInstanceIdentifier.AugmentationIdentifier(Sets.newHashSet(augmentChoice1QName));
231         final YangInstanceIdentifier.AugmentationIdentifier aug2Id =
232                 new YangInstanceIdentifier.AugmentationIdentifier(Sets.newHashSet(augmentChoice2QName));
233         final YangInstanceIdentifier.NodeIdentifier augmentChoice1Id =
234                 new YangInstanceIdentifier.NodeIdentifier(augmentChoice1QName);
235         final YangInstanceIdentifier.NodeIdentifier augmentChoice2Id =
236                 new YangInstanceIdentifier.NodeIdentifier(augmentChoice2QName);
237         final YangInstanceIdentifier.NodeIdentifier containerId =
238                 new YangInstanceIdentifier.NodeIdentifier(containerQName);
239
240         final NormalizedNode<?, ?> cont1Normalized =
241                 containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(parentNode.getQName()))
242                         .withChild(augmentationBuilder().withNodeIdentifier(aug1Id)
243                                 .withChild(choiceBuilder().withNodeIdentifier(augmentChoice1Id)
244                                         .withChild(augmentationBuilder().withNodeIdentifier(aug2Id)
245                                                 .withChild(choiceBuilder().withNodeIdentifier(augmentChoice2Id)
246                                                         .withChild(containerBuilder().withNodeIdentifier(containerId)
247                                                                 .withChild(leafNode(leafQName, "leaf-value"))
248                                                                 .build())
249                                                         .build())
250                                                 .build())
251                                         .build())
252                                 .build()).build();
253
254         final JsonParserStream jsonParser = JsonParserStream.create(streamWriter, schemaContext);
255         jsonParser.parse(new JsonReader(new StringReader(inputJson)));
256         final NormalizedNode<?, ?> transformedInput = result.getResult();
257         assertNotNull(transformedInput);
258         assertEquals(cont1Normalized, transformedInput);
259     }
260
261     private static void verifyTransformationToNormalizedNode(final String inputJson,
262             final NormalizedNode<?, ?> awaitedStructure) {
263         final NormalizedNodeResult result = new NormalizedNodeResult();
264         final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
265         final JsonParserStream jsonParser = JsonParserStream.create(streamWriter, schemaContext);
266         jsonParser.parse(new JsonReader(new StringReader(inputJson)));
267         final NormalizedNode<?, ?> transformedInput = result.getResult();
268         assertEquals("Transformation of json input to normalized node wasn't successful.", awaitedStructure,
269                 transformedInput);
270     }
271 }