2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.data.codec.gson;
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;
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.test.util.YangParserTestUtils;
39 * Each test tests whether json input is correctly transformed to normalized node structure.
41 public class JsonStreamToNormalizedNodeTest {
43 private static final QName CONT_1 = QName.create("ns:complex:json", "2014-08-11", "cont1");
44 private static final QName EMPTY_LEAF = QName.create(CONT_1,"empty");
45 private static SchemaContext schemaContext;
48 public static void initialization() {
49 schemaContext = YangParserTestUtils.parseYangResourceDirectory("/complexjson/yang");
53 public void leafNodeInContainer() throws IOException, URISyntaxException {
54 final String inputJson = loadTextFile("/complexjson/leaf-node-in-container.json");
55 verifyTransformationToNormalizedNode(inputJson, TestingNormalizedNodeStructuresCreator.leafNodeInContainer());
59 public void leafNodeViaAugmentationInContainer() throws IOException, URISyntaxException {
60 final String inputJson = loadTextFile("/complexjson/leaf-node-via-augmentation-in-container.json");
61 verifyTransformationToNormalizedNode(inputJson,
62 TestingNormalizedNodeStructuresCreator.leafNodeViaAugmentationInContainer());
66 public void leafListNodeInContainer() throws IOException, URISyntaxException {
67 final String inputJson = loadTextFile("/complexjson/leaflist-node-in-container.json");
68 verifyTransformationToNormalizedNode(inputJson,
69 TestingNormalizedNodeStructuresCreator.leafListNodeInContainer());
73 public void keyedListNodeInContainer() throws IOException, URISyntaxException {
74 final String inputJson = loadTextFile("/complexjson/keyed-list-node-in-container.json");
75 verifyTransformationToNormalizedNode(inputJson,
76 TestingNormalizedNodeStructuresCreator.keyedListNodeInContainer());
80 public void choiceNodeInContainer() throws IOException, URISyntaxException {
81 final String inputJson = loadTextFile("/complexjson/choice-node-in-container.json");
82 verifyTransformationToNormalizedNode(inputJson, TestingNormalizedNodeStructuresCreator.choiceNodeInContainer());
86 * Test of translating internal augmentations to normalized nodes structure.
89 * 2 nodes are added via internal augmentation A, 1 node via internal augmentation B and one node is originally
93 public void caseNodeAugmentationInChoiceInContainer() throws IOException, URISyntaxException {
94 final String inputJson = loadTextFile("/complexjson/case-node-augmentation-in-choice-in-container.json");
95 verifyTransformationToNormalizedNode(inputJson,
96 TestingNormalizedNodeStructuresCreator.caseNodeAugmentationInChoiceInContainer());
100 * also test using of namesakes (equal local names with different.
103 public void caseNodeExternalAugmentationInChoiceInContainer() throws IOException, URISyntaxException {
104 final String inputJson =
105 loadTextFile("/complexjson/case-node-external-augmentation-in-choice-in-container.json");
106 verifyTransformationToNormalizedNode(inputJson,
107 TestingNormalizedNodeStructuresCreator.caseNodeExternalAugmentationInChoiceInContainer());
111 * augmentation of choice - adding new case.
114 public void choiceNodeAugmentationInContainer() throws IOException, URISyntaxException {
115 final String inputJson = loadTextFile("/complexjson/choice-node-augmentation-in-container.json");
116 verifyTransformationToNormalizedNode(inputJson,
117 TestingNormalizedNodeStructuresCreator.choiceNodeAugmentationInContainer());
121 public void unkeyedNodeInContainer() throws IOException, URISyntaxException {
122 final String inputJson = loadTextFile("/complexjson/unkeyed-node-in-container.json");
123 verifyTransformationToNormalizedNode(inputJson,
124 TestingNormalizedNodeStructuresCreator.unkeyedNodeInContainer());
128 * Top level JSON element contains no information about module name.
131 * It should be possible to find out potential module name from available schema context.
134 public void missingModuleInfoInTopLevelElement() throws IOException, URISyntaxException {
135 final String inputJson = loadTextFile("/complexjson/missing-module-in-top-level.json");
136 verifyTransformationToNormalizedNode(inputJson, TestingNormalizedNodeStructuresCreator.topLevelContainer());
140 * Exception expected.
143 * It tests case when several elements with the same name and various namespaces exists and are in JSON specified
144 * without module name prefix.
147 public void leafNamesakes() throws IOException, URISyntaxException {
148 final String inputJson = loadTextFile("/complexjson/namesakes.json");
150 //second parameter isn't necessary because error will be raised before it is used.
151 verifyTransformationToNormalizedNode(inputJson, null);
152 fail("Expected exception not raised");
153 } catch (final IllegalStateException e) {
154 final String errorMessage = e.getMessage();
155 assertTrue(errorMessage.contains("Choose suitable module name for element lf11-namesake:"));
156 assertTrue(errorMessage.contains("complexjson-augmentation"));
157 assertTrue(errorMessage.contains("complexjson-augmentation-namesake"));
162 public void emptyTypeTest() throws IOException, URISyntaxException {
163 final String inputJson = loadTextFile("/complexjson/type-empty.json");
164 final ContainerNode awaitedStructure = containerBuilder()
165 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(CONT_1))
166 .addChild(leafNode(EMPTY_LEAF, null))
169 verifyTransformationToNormalizedNode(inputJson, awaitedStructure);
173 * Exception expected.
176 * Json input contains element which doesn't exist in YANG schema
179 public void parsingNotExistingElement() throws IOException, URISyntaxException {
180 final String inputJson = loadTextFile("/complexjson/not-existing-element.json");
182 //second parameter isn't necessary because error will be raised before it is used.
183 verifyTransformationToNormalizedNode(inputJson, null);
184 } catch (final IllegalStateException e) {
185 assertTrue(e.getMessage().contains("Schema node with name dummy-element was not found"));
190 public void listItemWithoutArray() throws IOException, URISyntaxException {
191 final String inputJson = loadTextFile("/complexjson/keyed-list-restconf-behaviour.json");
193 final NormalizedNodeResult result = new NormalizedNodeResult();
194 final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
195 final SchemaNode parentNode = schemaContext.getDataChildByName(CONT_1);
196 final JsonParserStream jsonParser = JsonParserStream.create(streamWriter, schemaContext, parentNode);
197 jsonParser.parse(new JsonReader(new StringReader(inputJson)));
198 final NormalizedNode<?, ?> transformedInput = result.getResult();
199 assertNotNull(transformedInput);
203 public void listItemWithArray() throws IOException, URISyntaxException {
204 final String inputJson = loadTextFile("/complexjson/keyed-list-yang-json-behaviour.json");
206 final NormalizedNodeResult result = new NormalizedNodeResult();
207 final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
208 final SchemaNode parentNode = schemaContext.getDataChildByName(CONT_1);
209 final JsonParserStream jsonParser = JsonParserStream.create(streamWriter, schemaContext, parentNode);
210 jsonParser.parse(new JsonReader(new StringReader(inputJson)));
211 final NormalizedNode<?, ?> transformedInput = result.getResult();
212 assertNotNull(transformedInput);
216 public void multipleChoiceAugmentation() throws IOException, URISyntaxException {
217 final String inputJson = loadTextFile("/complexjson/multiple-choice-augmentation-in-container.json");
219 final NormalizedNodeResult result = new NormalizedNodeResult();
220 final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
221 final SchemaNode parentNode = schemaContext.getDataChildByName(CONT_1);
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");
228 final YangInstanceIdentifier.AugmentationIdentifier aug1Id =
229 new YangInstanceIdentifier.AugmentationIdentifier(Sets.newHashSet(augmentChoice1QName));
230 final YangInstanceIdentifier.AugmentationIdentifier aug2Id =
231 new YangInstanceIdentifier.AugmentationIdentifier(Sets.newHashSet(augmentChoice2QName));
232 final YangInstanceIdentifier.NodeIdentifier augmentChoice1Id =
233 new YangInstanceIdentifier.NodeIdentifier(augmentChoice1QName);
234 final YangInstanceIdentifier.NodeIdentifier augmentChoice2Id =
235 new YangInstanceIdentifier.NodeIdentifier(augmentChoice2QName);
236 final YangInstanceIdentifier.NodeIdentifier containerId =
237 new YangInstanceIdentifier.NodeIdentifier(containerQName);
239 final NormalizedNode<?, ?> cont1Normalized =
240 containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(parentNode.getQName()))
241 .withChild(augmentationBuilder().withNodeIdentifier(aug1Id)
242 .withChild(choiceBuilder().withNodeIdentifier(augmentChoice1Id)
243 .withChild(augmentationBuilder().withNodeIdentifier(aug2Id)
244 .withChild(choiceBuilder().withNodeIdentifier(augmentChoice2Id)
245 .withChild(containerBuilder().withNodeIdentifier(containerId)
246 .withChild(leafNode(leafQName, "leaf-value"))
253 final JsonParserStream jsonParser = JsonParserStream.create(streamWriter, schemaContext);
254 jsonParser.parse(new JsonReader(new StringReader(inputJson)));
255 final NormalizedNode<?, ?> transformedInput = result.getResult();
256 assertNotNull(transformedInput);
257 assertEquals(cont1Normalized, transformedInput);
260 private static void verifyTransformationToNormalizedNode(final String inputJson,
261 final NormalizedNode<?, ?> awaitedStructure) {
262 final NormalizedNodeResult result = new NormalizedNodeResult();
263 final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
264 final JsonParserStream jsonParser = JsonParserStream.create(streamWriter, schemaContext);
265 jsonParser.parse(new JsonReader(new StringReader(inputJson)));
266 final NormalizedNode<?, ?> transformedInput = result.getResult();
267 assertEquals("Transformation of json input to normalized node wasn't successful.", awaitedStructure,