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.jupiter.api.Assertions.assertEquals;
13 import static org.junit.jupiter.api.Assertions.assertNotNull;
14 import static org.junit.jupiter.api.Assertions.assertThrows;
15 import static org.opendaylight.yangtools.yang.data.codec.gson.TestUtils.loadTextFile;
17 import com.google.gson.stream.JsonReader;
18 import java.io.StringReader;
19 import org.junit.jupiter.api.Test;
20 import org.opendaylight.yangtools.yang.common.QName;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
22 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
23 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
24 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizationResultHolder;
25 import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
26 import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
29 * Each test tests whether json input is correctly transformed to normalized node structure.
31 class JsonStreamToNormalizedNodeTest extends AbstractComplexJsonTest {
33 void leafNodeInContainer() throws Exception {
34 final var inputJson = loadTextFile("/complexjson/leaf-node-in-container.json");
35 verifyTransformationToNormalizedNode(inputJson, TestingNormalizedNodeStructuresCreator.leafNodeInContainer());
39 void leafNodeViaAugmentationInContainer() throws Exception {
40 final var inputJson = loadTextFile("/complexjson/leaf-node-via-augmentation-in-container.json");
41 verifyTransformationToNormalizedNode(inputJson,
42 TestingNormalizedNodeStructuresCreator.leafNodeViaAugmentationInContainer());
46 void leafListNodeInContainer() throws Exception {
47 final var inputJson = loadTextFile("/complexjson/leaflist-node-in-container.json");
48 verifyTransformationToNormalizedNode(inputJson,
49 TestingNormalizedNodeStructuresCreator.leafListNodeInContainer());
53 void keyedListNodeInContainer() throws Exception {
54 final var inputJson = loadTextFile("/complexjson/keyed-list-node-in-container.json");
55 verifyTransformationToNormalizedNode(inputJson,
56 TestingNormalizedNodeStructuresCreator.keyedListNodeInContainer());
60 void choiceNodeInContainer() throws Exception {
61 final var inputJson = loadTextFile("/complexjson/choice-node-in-container.json");
62 verifyTransformationToNormalizedNode(inputJson, TestingNormalizedNodeStructuresCreator.choiceNodeInContainer());
66 * Test of translating internal augmentations to normalized nodes structure.
69 * 2 nodes are added via internal augmentation A, 1 node via internal augmentation B and one node is originally
73 void caseNodeAugmentationInChoiceInContainer() throws Exception {
74 final var inputJson = loadTextFile("/complexjson/case-node-augmentation-in-choice-in-container.json");
75 verifyTransformationToNormalizedNode(inputJson,
76 TestingNormalizedNodeStructuresCreator.caseNodeAugmentationInChoiceInContainer());
80 * also test using of namesakes (equal local names with different.
83 void caseNodeExternalAugmentationInChoiceInContainer() throws Exception {
85 loadTextFile("/complexjson/case-node-external-augmentation-in-choice-in-container.json");
86 verifyTransformationToNormalizedNode(inputJson,
87 TestingNormalizedNodeStructuresCreator.caseNodeExternalAugmentationInChoiceInContainer());
91 * augmentation of choice - adding new case.
94 void choiceNodeAugmentationInContainer() throws Exception {
95 final var inputJson = loadTextFile("/complexjson/choice-node-augmentation-in-container.json");
96 verifyTransformationToNormalizedNode(inputJson,
97 TestingNormalizedNodeStructuresCreator.choiceNodeAugmentationInContainer());
101 void unkeyedNodeInContainer() throws Exception {
102 final var inputJson = loadTextFile("/complexjson/unkeyed-node-in-container.json");
103 verifyTransformationToNormalizedNode(inputJson,
104 TestingNormalizedNodeStructuresCreator.unkeyedNodeInContainer());
108 * Top level JSON element contains no information about module name.
111 * It should be possible to find out potential module name from available schema context.
114 void missingModuleInfoInTopLevelElement() throws Exception {
115 final var inputJson = loadTextFile("/complexjson/missing-module-in-top-level.json");
116 verifyTransformationToNormalizedNode(inputJson, TestingNormalizedNodeStructuresCreator.topLevelContainer());
120 * Exception expected.
123 * It tests case when several elements with the same name and various namespaces exists and are in JSON specified
124 * without module name prefix.
127 void leafNamesakes() throws Exception {
128 final var inputJson = loadTextFile("/complexjson/namesakes.json");
129 final var ex = assertThrows(IllegalStateException.class,
130 // second parameter isn't necessary because error will be raised before it is used.
131 () -> verifyTransformationToNormalizedNode(inputJson, null));
133 final var errorMessage = ex.getMessage();
134 assertThat(errorMessage, containsString("Choose suitable module name for element lf11-namesake:"));
135 assertThat(errorMessage, containsString("complexjson-augmentation"));
136 assertThat(errorMessage, containsString("complexjson-augmentation-namesake"));
140 void emptyTypeTest() throws Exception {
141 final var inputJson = loadTextFile("/complexjson/type-empty.json");
142 verifyTransformationToNormalizedNode(inputJson, CONT1_WITH_EMPTYLEAF);
146 * Exception expected.
149 * Json input contains element which doesn't exist in YANG schema
152 void parsingNotExistingElement() throws Exception {
153 final var inputJson = loadTextFile("/complexjson/not-existing-element.json");
154 final var ex = assertThrows(IllegalStateException.class,
155 //second parameter isn't necessary because error will be raised before it is used.
156 () -> verifyTransformationToNormalizedNode(inputJson, null));
158 assertThat(ex.getMessage(), containsString("Schema node with name dummy-element was not found"));
162 * Should not fail as we set the parser to be lenient.
165 * Json input contains element which doesn't exist in YANG schema
168 void parsingSkipNotExistingElement() throws Exception {
169 final var inputJson = loadTextFile("/complexjson/not-existing-element.json");
170 final var result = new NormalizationResultHolder();
171 final var streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
172 final var jsonParser = JsonParserStream.createLenient(streamWriter,
173 JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02.getShared(schemaContext));
174 jsonParser.parse(new JsonReader(new StringReader(inputJson)));
175 final var transformedInput = result.getResult().data();
176 assertNotNull(transformedInput);
180 void listItemWithoutArray() throws Exception {
181 final var inputJson = loadTextFile("/complexjson/keyed-list-restconf-behaviour.json");
182 final var result = new NormalizationResultHolder();
183 final var streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
184 final var jsonParser = JsonParserStream.create(streamWriter, lhotkaCodecFactory,
185 Inference.ofDataTreePath(schemaContext, CONT_1));
186 jsonParser.parse(new JsonReader(new StringReader(inputJson)));
187 final var transformedInput = result.getResult().data();
188 assertNotNull(transformedInput);
192 void listItemWithArray() throws Exception {
193 final var inputJson = loadTextFile("/complexjson/keyed-list-yang-json-behaviour.json");
194 final var result = new NormalizationResultHolder();
195 final var streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
196 final var jsonParser = JsonParserStream.create(streamWriter, lhotkaCodecFactory,
197 Inference.ofDataTreePath(schemaContext, CONT_1));
198 jsonParser.parse(new JsonReader(new StringReader(inputJson)));
199 final var transformedInput = result.getResult().data();
200 assertNotNull(transformedInput);
204 void multipleChoiceAugmentation() throws Exception {
205 final var inputJson = loadTextFile("/complexjson/multiple-choice-augmentation-in-container.json");
207 final var result = new NormalizationResultHolder();
208 final var streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
210 final var augmentChoice1QName = QName.create(CONT_1, "augment-choice1");
211 final var augmentChoice2QName = QName.create(augmentChoice1QName, "augment-choice2");
212 final var containerQName = QName.create(augmentChoice1QName, "case11-choice-case-container");
213 final var leafQName = QName.create(augmentChoice1QName, "case11-choice-case-leaf");
215 final var cont1Normalized = ImmutableNodes.newContainerBuilder()
216 .withNodeIdentifier(new NodeIdentifier(CONT_1))
217 .withChild(ImmutableNodes.newChoiceBuilder()
218 .withNodeIdentifier(new NodeIdentifier(augmentChoice1QName))
219 .withChild(ImmutableNodes.newChoiceBuilder()
220 .withNodeIdentifier(new NodeIdentifier(augmentChoice2QName))
221 .withChild(ImmutableNodes.newContainerBuilder()
222 .withNodeIdentifier(new NodeIdentifier(containerQName))
223 .withChild(ImmutableNodes.leafNode(leafQName, "leaf-value"))
229 final var jsonParser = JsonParserStream.create(streamWriter, lhotkaCodecFactory);
230 jsonParser.parse(new JsonReader(new StringReader(inputJson)));
231 final var transformedInput = result.getResult().data();
232 assertNotNull(transformedInput);
233 assertEquals(cont1Normalized, transformedInput);
236 private static void verifyTransformationToNormalizedNode(final String inputJson,
237 final NormalizedNode awaitedStructure) {
238 final var result = new NormalizationResultHolder();
239 final var streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
240 final var jsonParser = JsonParserStream.create(streamWriter, lhotkaCodecFactory);
241 jsonParser.parse(new JsonReader(new StringReader(inputJson)));
242 assertEquals(awaitedStructure, result.getResult().data(),
243 "Transformation of json input to normalized node wasn't successful.");