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