b6289b400976515319ecc04679cb542beec39da6
[netconf.git] / restconf / restconf-nb-bierman02 / src / test / java / org / opendaylight / controller / sal / restconf / impl / json / to / nn / test / JsonToNnTest.java
1 /*
2  * Copyright (c) 2014 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.controller.sal.restconf.impl.json.to.nn.test;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertNull;
13 import static org.junit.Assert.assertTrue;
14 import static org.junit.Assert.fail;
15
16 import java.io.File;
17 import java.io.FileNotFoundException;
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.util.Collection;
21 import javax.ws.rs.WebApplicationException;
22 import javax.ws.rs.core.MediaType;
23 import org.junit.BeforeClass;
24 import org.junit.Test;
25 import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
26 import org.opendaylight.controller.sal.rest.impl.test.providers.AbstractBodyReaderTest;
27 import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
28 import org.opendaylight.restconf.common.context.NormalizedNodeContext;
29 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
30 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
31 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
32 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 public class JsonToNnTest extends AbstractBodyReaderTest {
37
38     private static final Logger LOG = LoggerFactory.getLogger(AbstractBodyReaderTest.class);
39
40     private final JsonNormalizedNodeBodyReader jsonBodyReader;
41     private static SchemaContext schemaContext;
42
43     public JsonToNnTest() {
44         super(schemaContext, null);
45         this.jsonBodyReader = new JsonNormalizedNodeBodyReader(controllerContext);
46     }
47
48     @BeforeClass
49     public static void initialize() throws FileNotFoundException {
50         final Collection<File> testFiles = TestRestconfUtils.loadFiles("/json-to-nn/simple-list-yang/1");
51         testFiles.addAll(TestRestconfUtils.loadFiles("/json-to-nn/simple-list-yang/3"));
52         testFiles.addAll(TestRestconfUtils.loadFiles("/json-to-nn/simple-list-yang/4"));
53         testFiles.addAll(TestRestconfUtils.loadFiles("/json-to-nn/simple-container-yang"));
54         testFiles.addAll(TestRestconfUtils.loadFiles("/common/augment/yang"));
55         schemaContext = YangParserTestUtils.parseYangFiles(testFiles);
56     }
57
58     @Test
59     public void simpleListTest() throws Exception {
60         simpleTest("/json-to-nn/simple-list.json",
61                 "lst", "simple-list-yang1");
62     }
63
64     @Test
65     public void simpleContainerTest() throws Exception {
66         simpleTest("/json-to-nn/simple-container.json",
67                 "cont", "simple-container-yang");
68     }
69
70     @Test
71     public void multipleItemsInLeafListTest() throws Exception {
72         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
73                 "/json-to-nn/multiple-leaflist-items.json",
74                 "simple-list-yang1:lst");
75         assertNotNull(normalizedNodeContext);
76
77         final String dataTree = NormalizedNodes.toStringTree(normalizedNodeContext
78                 .getData());
79         assertTrue(dataTree.contains("45"));
80         assertTrue(dataTree.contains("55"));
81         assertTrue(dataTree.contains("66"));
82     }
83
84     @Test
85     public void multipleItemsInListTest() throws Exception {
86         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
87                 "/json-to-nn/multiple-items-in-list.json",
88                 "multiple-items-yang:lst");
89         assertNotNull(normalizedNodeContext);
90
91         assertEquals("lst", normalizedNodeContext.getData().getNodeType()
92                 .getLocalName());
93
94         verityMultipleItemsInList(normalizedNodeContext);
95     }
96
97     @Test
98     public void nullArrayToSimpleNodeWithNullValueTest() throws Exception {
99         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
100                 "/json-to-nn/array-with-null.json", "array-with-null-yang:cont");
101         assertNotNull(normalizedNodeContext);
102
103         assertEquals("cont", normalizedNodeContext.getData().getNodeType()
104                 .getLocalName());
105
106         final String dataTree = NormalizedNodes.toStringTree(normalizedNodeContext
107                 .getData());
108         assertTrue(dataTree.contains("lf"));
109         assertTrue(dataTree.contains("empty"));
110     }
111
112     @Test
113     public void incorrectTopLevelElementsTest() throws Exception {
114         mockBodyReader("simple-list-yang1:lst", this.jsonBodyReader, false);
115
116         InputStream inputStream = this.getClass().getResourceAsStream(
117                 "/json-to-nn/wrong-top-level1.json");
118
119         int countExceptions = 0;
120         RestconfDocumentedException exception = null;
121
122         try {
123             this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
124                     inputStream);
125         } catch (final RestconfDocumentedException e) {
126             exception = e;
127             countExceptions++;
128         }
129         assertNotNull(exception);
130         assertEquals(
131                 "Error parsing input: Schema node with name wrong was not found under "
132                         + "(urn:ietf:params:xml:ns:netconf:base:1.0)data.",
133                 exception.getErrors().get(0).getErrorMessage());
134
135         inputStream = this.getClass().getResourceAsStream(
136                 "/json-to-nn/wrong-top-level2.json");
137         exception = null;
138         try {
139             this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
140                     inputStream);
141         } catch (final RestconfDocumentedException e) {
142             exception = e;
143             countExceptions++;
144         }
145         assertNotNull(exception);
146         assertEquals(
147                 "Error parsing input: Schema node with name lst1 was not found under "
148                         + "(urn:ietf:params:xml:ns:netconf:base:1.0)data.",
149                 exception.getErrors().get(0).getErrorMessage());
150
151         inputStream = this.getClass().getResourceAsStream(
152                 "/json-to-nn/wrong-top-level3.json");
153         exception = null;
154         try {
155             this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
156                     inputStream);
157         } catch (final RestconfDocumentedException e) {
158             exception = e;
159             countExceptions++;
160         }
161         assertNotNull(exception);
162         assertEquals(
163                 "Error parsing input: Schema node with name lf was not found under "
164                         + "(urn:ietf:params:xml:ns:netconf:base:1.0)data.",
165                 exception.getErrors().get(0).getErrorMessage());
166         assertEquals(3, countExceptions);
167     }
168
169     @Test
170     public void emptyDataReadTest() throws Exception {
171         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
172                 "/json-to-nn/empty-data.json", "array-with-null-yang:cont");
173         assertNotNull(normalizedNodeContext);
174
175         assertEquals("cont", normalizedNodeContext.getData().getNodeType()
176                 .getLocalName());
177
178         final String dataTree = NormalizedNodes.toStringTree(normalizedNodeContext
179                 .getData());
180
181         assertTrue(dataTree.contains("lflst1"));
182
183         assertTrue(dataTree.contains("lflst2 45"));
184
185         RestconfDocumentedException exception = null;
186         mockBodyReader("array-with-null-yang:cont", this.jsonBodyReader, false);
187         final InputStream inputStream = this.getClass().getResourceAsStream(
188                 "/json-to-nn/empty-data.json1");
189
190         try {
191             this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
192                     inputStream);
193         } catch (final RestconfDocumentedException e) {
194             exception = e;
195         }
196         assertNotNull(exception);
197         assertEquals("Error parsing input: null", exception.getErrors().get(0)
198                 .getErrorMessage());
199     }
200
201     @Test
202     public void testJsonBlankInput() throws Exception {
203         final NormalizedNodeContext normalizedNodeContext = prepareNNC("",
204                 "array-with-null-yang:cont");
205         assertNull(normalizedNodeContext);
206     }
207
208     @Test
209     public void notSupplyNamespaceIfAlreadySupplied()throws Exception {
210         final String uri = "simple-list-yang1" + ":" + "lst";
211
212         final NormalizedNodeContext normalizedNodeContext = prepareNNC(
213                 "/json-to-nn/simple-list.json", uri);
214         assertNotNull(normalizedNodeContext);
215
216         verifyNormaluizedNodeContext(normalizedNodeContext, "lst");
217
218         mockBodyReader("simple-list-yang2:lst", this.jsonBodyReader, false);
219         final InputStream inputStream = this.getClass().getResourceAsStream(
220                 "/json-to-nn/simple-list.json");
221
222         try {
223             this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
224                     inputStream);
225             fail("NormalizedNodeContext should not be create because of different namespace");
226         } catch (final RestconfDocumentedException e) {
227             LOG.warn("Read from InputStream failed. Message: {}. Status: {}", e.getMessage(), e.getStatus());
228         }
229
230         verifyNormaluizedNodeContext(normalizedNodeContext, "lst");
231     }
232
233     @Test
234     public void dataAugmentedTest() throws Exception {
235         NormalizedNodeContext normalizedNodeContext = prepareNNC(
236                 "/common/augment/json/dataa.json", "main:cont");
237
238         assertNotNull(normalizedNodeContext);
239         assertEquals("cont", normalizedNodeContext.getData().getNodeType()
240                 .getLocalName());
241
242         String dataTree = NormalizedNodes.toStringTree(normalizedNodeContext
243                 .getData());
244         assertTrue(dataTree.contains("cont1"));
245         assertTrue(dataTree.contains("lf11 lf11 value from a"));
246
247         normalizedNodeContext = prepareNNC("/common/augment/json/datab.json",
248                 "main:cont");
249
250         assertNotNull(normalizedNodeContext);
251         assertEquals("cont", normalizedNodeContext.getData().getNodeType()
252                 .getLocalName());
253         dataTree = NormalizedNodes
254                 .toStringTree(normalizedNodeContext.getData());
255         assertTrue(dataTree.contains("cont1"));
256         assertTrue(dataTree.contains("lf11 lf11 value from b"));
257     }
258
259     private void simpleTest(final String jsonPath, final String topLevelElementName,
260             final String moduleName) throws Exception {
261         final String uri = moduleName + ":" + topLevelElementName;
262
263         final NormalizedNodeContext normalizedNodeContext = prepareNNC(jsonPath, uri);
264         assertNotNull(normalizedNodeContext);
265
266         verifyNormaluizedNodeContext(normalizedNodeContext, topLevelElementName);
267     }
268
269     private NormalizedNodeContext prepareNNC(final String jsonPath, final String uri) throws Exception {
270         try {
271             mockBodyReader(uri, this.jsonBodyReader, false);
272         } catch (NoSuchFieldException | SecurityException
273                 | IllegalArgumentException | IllegalAccessException e) {
274             LOG.warn("Operation failed due to: {}", e.getMessage());
275         }
276         final InputStream inputStream = this.getClass().getResourceAsStream(jsonPath);
277
278         NormalizedNodeContext normalizedNodeContext = null;
279
280         try {
281             normalizedNodeContext = this.jsonBodyReader.readFrom(null, null, null,
282                     this.mediaType, null, inputStream);
283         } catch (WebApplicationException | IOException e) {
284             // TODO Auto-generated catch block
285         }
286
287         return normalizedNodeContext;
288     }
289
290     private static void verifyNormaluizedNodeContext(final NormalizedNodeContext normalizedNodeContext,
291             final String topLevelElementName) {
292         assertEquals(topLevelElementName, normalizedNodeContext.getData()
293                 .getNodeType().getLocalName());
294
295         final String dataTree = NormalizedNodes.toStringTree(normalizedNodeContext
296                 .getData());
297         assertTrue(dataTree.contains("cont1"));
298         assertTrue(dataTree.contains("lst1"));
299         assertTrue(dataTree.contains("lflst1"));
300         assertTrue(dataTree.contains("lflst1_1"));
301         assertTrue(dataTree.contains("lflst1_2"));
302         assertTrue(dataTree.contains("lf1"));
303     }
304
305     private static void verityMultipleItemsInList(final NormalizedNodeContext normalizedNodeContext) {
306
307         final String dataTree = NormalizedNodes.toStringTree(normalizedNodeContext
308                 .getData());
309         assertTrue(dataTree.contains("lf11"));
310         assertTrue(dataTree.contains("lf11_1"));
311         assertTrue(dataTree.contains("lflst11"));
312         assertTrue(dataTree.contains("45"));
313         assertTrue(dataTree.contains("cont11"));
314         assertTrue(dataTree.contains("lst11"));
315     }
316
317     @Test
318     public void unsupportedDataFormatTest() throws Exception {
319         mockBodyReader("simple-list-yang1:lst", this.jsonBodyReader, false);
320
321         final InputStream inputStream = this.getClass().getResourceAsStream(
322                 "/json-to-nn/unsupported-json-format.json");
323
324         RestconfDocumentedException exception = null;
325
326         try {
327             this.jsonBodyReader.readFrom(null, null, null, this.mediaType, null,
328                     inputStream);
329         } catch (final RestconfDocumentedException e) {
330             exception = e;
331         }
332         LOG.info(exception.getErrors().get(0).getErrorMessage());
333
334         assertTrue(exception.getErrors().get(0).getErrorMessage()
335                 .contains("is not a simple type"));
336     }
337
338     @Test
339     public void invalidUriCharacterInValue() throws Exception {
340         mockBodyReader("array-with-null-yang:cont", this.jsonBodyReader, false);
341
342         final InputStream inputStream = this.getClass().getResourceAsStream(
343                 "/json-to-nn/invalid-uri-character-in-value.json");
344
345         final NormalizedNodeContext normalizedNodeContext = this.jsonBodyReader.readFrom(
346                 null, null, null, this.mediaType, null, inputStream);
347         assertNotNull(normalizedNodeContext);
348
349         assertEquals("cont", normalizedNodeContext.getData().getNodeType()
350                 .getLocalName());
351
352         final String dataTree = NormalizedNodes.toStringTree(normalizedNodeContext
353                 .getData());
354         assertTrue(dataTree.contains("lf1 module<Name:value lf1"));
355         assertTrue(dataTree.contains("lf2 module>Name:value lf2"));
356     }
357
358     @Override
359     protected MediaType getMediaType() {
360         return null;
361     }
362
363 }