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