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