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