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