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.hamcrest.CoreMatchers.containsString;
11 import static org.hamcrest.MatcherAssert.assertThat;
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertNotNull;
14 import static org.junit.Assert.assertThrows;
15 import static org.opendaylight.yangtools.yang.data.codec.gson.TestUtils.loadTextFile;
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.gson.stream.JsonReader;
21 import java.io.IOException;
22 import java.io.StringReader;
23 import java.net.URISyntaxException;
24 import org.junit.Test;
25 import org.opendaylight.yangtools.yang.common.QName;
26 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
27 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
28 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
29 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizationResultHolder;
30 import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
33 * Each test tests whether json input is correctly transformed to normalized node structure.
35 public class JsonStreamToNormalizedNodeTest extends AbstractComplexJsonTest {
37 public void leafNodeInContainer() throws IOException, URISyntaxException {
38 final String inputJson = loadTextFile("/complexjson/leaf-node-in-container.json");
39 verifyTransformationToNormalizedNode(inputJson, TestingNormalizedNodeStructuresCreator.leafNodeInContainer());
43 public void leafNodeViaAugmentationInContainer() throws IOException, URISyntaxException {
44 final String inputJson = loadTextFile("/complexjson/leaf-node-via-augmentation-in-container.json");
45 verifyTransformationToNormalizedNode(inputJson,
46 TestingNormalizedNodeStructuresCreator.leafNodeViaAugmentationInContainer());
50 public void leafListNodeInContainer() throws IOException, URISyntaxException {
51 final String inputJson = loadTextFile("/complexjson/leaflist-node-in-container.json");
52 verifyTransformationToNormalizedNode(inputJson,
53 TestingNormalizedNodeStructuresCreator.leafListNodeInContainer());
57 public void keyedListNodeInContainer() throws IOException, URISyntaxException {
58 final String inputJson = loadTextFile("/complexjson/keyed-list-node-in-container.json");
59 verifyTransformationToNormalizedNode(inputJson,
60 TestingNormalizedNodeStructuresCreator.keyedListNodeInContainer());
64 public void choiceNodeInContainer() throws IOException, URISyntaxException {
65 final String inputJson = loadTextFile("/complexjson/choice-node-in-container.json");
66 verifyTransformationToNormalizedNode(inputJson, TestingNormalizedNodeStructuresCreator.choiceNodeInContainer());
70 * Test of translating internal augmentations to normalized nodes structure.
73 * 2 nodes are added via internal augmentation A, 1 node via internal augmentation B and one node is originally
77 public void caseNodeAugmentationInChoiceInContainer() throws IOException, URISyntaxException {
78 final String inputJson = loadTextFile("/complexjson/case-node-augmentation-in-choice-in-container.json");
79 verifyTransformationToNormalizedNode(inputJson,
80 TestingNormalizedNodeStructuresCreator.caseNodeAugmentationInChoiceInContainer());
84 * also test using of namesakes (equal local names with different.
87 public void caseNodeExternalAugmentationInChoiceInContainer() throws IOException, URISyntaxException {
88 final String inputJson =
89 loadTextFile("/complexjson/case-node-external-augmentation-in-choice-in-container.json");
90 verifyTransformationToNormalizedNode(inputJson,
91 TestingNormalizedNodeStructuresCreator.caseNodeExternalAugmentationInChoiceInContainer());
95 * augmentation of choice - adding new case.
98 public void choiceNodeAugmentationInContainer() throws IOException, URISyntaxException {
99 final String inputJson = loadTextFile("/complexjson/choice-node-augmentation-in-container.json");
100 verifyTransformationToNormalizedNode(inputJson,
101 TestingNormalizedNodeStructuresCreator.choiceNodeAugmentationInContainer());
105 public void unkeyedNodeInContainer() throws IOException, URISyntaxException {
106 final String inputJson = loadTextFile("/complexjson/unkeyed-node-in-container.json");
107 verifyTransformationToNormalizedNode(inputJson,
108 TestingNormalizedNodeStructuresCreator.unkeyedNodeInContainer());
112 * Top level JSON element contains no information about module name.
115 * It should be possible to find out potential module name from available schema context.
118 public void missingModuleInfoInTopLevelElement() throws IOException, URISyntaxException {
119 final String inputJson = loadTextFile("/complexjson/missing-module-in-top-level.json");
120 verifyTransformationToNormalizedNode(inputJson, TestingNormalizedNodeStructuresCreator.topLevelContainer());
124 * Exception expected.
127 * It tests case when several elements with the same name and various namespaces exists and are in JSON specified
128 * without module name prefix.
131 public void leafNamesakes() throws IOException, URISyntaxException {
132 final String inputJson = loadTextFile("/complexjson/namesakes.json");
133 final IllegalStateException ex = assertThrows(IllegalStateException.class,
134 // second parameter isn't necessary because error will be raised before it is used.
135 () -> verifyTransformationToNormalizedNode(inputJson, null));
137 final String errorMessage = ex.getMessage();
138 assertThat(errorMessage, containsString("Choose suitable module name for element lf11-namesake:"));
139 assertThat(errorMessage, containsString("complexjson-augmentation"));
140 assertThat(errorMessage, containsString("complexjson-augmentation-namesake"));
144 public void emptyTypeTest() throws IOException, URISyntaxException {
145 final String inputJson = loadTextFile("/complexjson/type-empty.json");
146 verifyTransformationToNormalizedNode(inputJson, CONT1_WITH_EMPTYLEAF);
150 * Exception expected.
153 * Json input contains element which doesn't exist in YANG schema
156 public void parsingNotExistingElement() throws IOException, URISyntaxException {
157 final String inputJson = loadTextFile("/complexjson/not-existing-element.json");
158 final IllegalStateException ex = assertThrows(IllegalStateException.class,
159 //second parameter isn't necessary because error will be raised before it is used.
160 () -> verifyTransformationToNormalizedNode(inputJson, null));
162 assertThat(ex.getMessage(), containsString("Schema node with name dummy-element was not found"));
166 * Should not fail as we set the parser to be lenient.
169 * Json input contains element which doesn't exist in YANG schema
172 public void parsingSkipNotExistingElement() throws IOException, URISyntaxException {
173 final String inputJson = loadTextFile("/complexjson/not-existing-element.json");
174 final var result = new NormalizationResultHolder();
175 final var streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
176 final var jsonParser = JsonParserStream.createLenient(streamWriter,
177 JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02.getShared(schemaContext));
178 jsonParser.parse(new JsonReader(new StringReader(inputJson)));
179 final var transformedInput = result.getResult().data();
180 assertNotNull(transformedInput);
184 public void listItemWithoutArray() throws IOException, URISyntaxException {
185 final String inputJson = loadTextFile("/complexjson/keyed-list-restconf-behaviour.json");
186 final var result = new NormalizationResultHolder();
187 final var streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
188 final var jsonParser = JsonParserStream.create(streamWriter, lhotkaCodecFactory,
189 Inference.ofDataTreePath(schemaContext, CONT_1));
190 jsonParser.parse(new JsonReader(new StringReader(inputJson)));
191 final var transformedInput = result.getResult().data();
192 assertNotNull(transformedInput);
196 public void listItemWithArray() throws IOException, URISyntaxException {
197 final String inputJson = loadTextFile("/complexjson/keyed-list-yang-json-behaviour.json");
198 final var result = new NormalizationResultHolder();
199 final var streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
200 final var jsonParser = JsonParserStream.create(streamWriter, lhotkaCodecFactory,
201 Inference.ofDataTreePath(schemaContext, CONT_1));
202 jsonParser.parse(new JsonReader(new StringReader(inputJson)));
203 final var transformedInput = result.getResult().data();
204 assertNotNull(transformedInput);
208 public void multipleChoiceAugmentation() throws IOException, URISyntaxException {
209 final String inputJson = loadTextFile("/complexjson/multiple-choice-augmentation-in-container.json");
211 final var result = new NormalizationResultHolder();
212 final var streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
214 final QName augmentChoice1QName = QName.create(CONT_1, "augment-choice1");
215 final QName augmentChoice2QName = QName.create(augmentChoice1QName, "augment-choice2");
216 final QName containerQName = QName.create(augmentChoice1QName, "case11-choice-case-container");
217 final QName leafQName = QName.create(augmentChoice1QName, "case11-choice-case-leaf");
219 final var cont1Normalized = containerBuilder()
220 .withNodeIdentifier(new NodeIdentifier(CONT_1))
221 .withChild(choiceBuilder()
222 .withNodeIdentifier(new NodeIdentifier(augmentChoice1QName))
223 .withChild(choiceBuilder()
224 .withNodeIdentifier(new NodeIdentifier(augmentChoice2QName))
225 .withChild(containerBuilder()
226 .withNodeIdentifier(new NodeIdentifier(containerQName))
227 .withChild(leafNode(leafQName, "leaf-value"))
233 final var jsonParser = JsonParserStream.create(streamWriter, lhotkaCodecFactory);
234 jsonParser.parse(new JsonReader(new StringReader(inputJson)));
235 final var transformedInput = result.getResult().data();
236 assertNotNull(transformedInput);
237 assertEquals(cont1Normalized, transformedInput);
240 private static void verifyTransformationToNormalizedNode(final String inputJson,
241 final NormalizedNode awaitedStructure) {
242 final var result = new NormalizationResultHolder();
243 final var streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
244 final var jsonParser = JsonParserStream.create(streamWriter, lhotkaCodecFactory);
245 jsonParser.parse(new JsonReader(new StringReader(inputJson)));
246 final var transformedInput = result.getResult().data();
247 assertEquals("Transformation of json input to normalized node wasn't successful.", awaitedStructure,