test of namespace supplement
[controller.git] / opendaylight / md-sal / sal-rest-connector / src / test / java / org / opendaylight / controller / sal / restconf / impl / test / FromJsonToCompositeNode.java
1 package org.opendaylight.controller.sal.restconf.impl.test;
2
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertNotNull;
5 import static org.junit.Assert.assertTrue;
6 import static org.mockito.Matchers.any;
7 import static org.mockito.Mockito.mock;
8 import static org.mockito.Mockito.when;
9
10 import java.io.*;
11 import java.net.*;
12 import java.util.*;
13 import java.util.concurrent.*;
14
15 import javax.ws.rs.WebApplicationException;
16
17 import org.junit.Test;
18 import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
19 import org.opendaylight.controller.sal.restconf.impl.*;
20 import org.opendaylight.yangtools.yang.data.api.*;
21 import org.slf4j.*;
22 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
23 import org.opendaylight.yangtools.yang.common.RpcResult;
24 import org.opendaylight.yangtools.yang.model.api.*;
25
26 import com.google.gson.JsonSyntaxException;
27
28 public class FromJsonToCompositeNode {
29
30     /**
31      * 
32      * It is just dummy class which is used in mock method to specify return
33      * type
34      */
35     private class DummyFuture implements Future<RpcResult<TransactionStatus>> {
36
37         @Override
38         public boolean cancel(boolean mayInterruptIfRunning) {
39             return false;
40         }
41
42         @Override
43         public boolean isCancelled() {
44             return false;
45         }
46
47         @Override
48         public boolean isDone() {
49             return false;
50         }
51
52         @Override
53         public RpcResult<TransactionStatus> get() throws InterruptedException, ExecutionException {
54             return null;
55         }
56
57         @Override
58         public RpcResult<TransactionStatus> get(long timeout, TimeUnit unit) throws InterruptedException,
59                 ExecutionException, TimeoutException {
60             return null;
61         }
62     };
63
64     Logger LOG = LoggerFactory.getLogger(FromJsonToCompositeNode.class);
65
66     @Test
67     public void simpleListTest() {
68         simpleTest("/json-to-composite-node/simple-list.json", "/json-to-composite-node/simple-list-yang", "lst",
69                 "simple:data:types");
70     }
71
72     @Test
73     public void simpleContainerTest() {
74         simpleTest("/json-to-composite-node/simple-container.json", "/json-to-composite-node/simple-list-yang", "cont",
75                 "simple:data:types");
76     }
77
78     /**
79      * List contains 4 items and in every item are other elements. It is
80      * supposed that there should be: lf11, lflst11, cont11, lst11
81      */
82     @Test
83     public void multipleItemsInListTest() {
84         CompositeNode compositeNode = compositeContainerFromJson("/json-to-composite-node/multiple-items-in-list.json",
85                 true);
86         assertNotNull(compositeNode);
87
88         assertEquals("lst", compositeNode.getNodeType().getLocalName());
89
90         verityMultipleItemsInList(compositeNode);
91     }
92
93     @Test
94     public void incorrectTopLevelElementsTest() {
95         Throwable cause1 = null;
96         try {
97             compositeContainerFromJson("/json-to-composite-node/wrong-top-level1.json", true);
98         } catch (WebApplicationException e) {
99             cause1 = e;
100         }
101
102         assertNotNull(cause1);
103         assertTrue(cause1
104                 .getCause()
105                 .getMessage()
106                 .contains(
107                         "First element in Json Object has to be \"Object\" or \"Array with one Object element\". Other scenarios are not supported yet."));
108
109         Throwable cause2 = null;
110         try {
111             compositeContainerFromJson("/json-to-composite-node/wrong-top-level2.json", true);
112         } catch (WebApplicationException e) {
113             cause2 = e;
114         }
115         assertNotNull(cause2);
116         assertTrue(cause2.getCause().getMessage().contains("Json Object should contain one element"));
117
118         Throwable cause3 = null;
119         try {
120             compositeContainerFromJson("/json-to-composite-node/wrong-top-level3.json", true);
121         } catch (WebApplicationException e) {
122             cause3 = e;
123         }
124         assertNotNull(cause3);
125         assertTrue(cause3
126                 .getCause()
127                 .getMessage()
128                 .contains(
129                         "First element in Json Object has to be \"Object\" or \"Array with one Object element\". Other scenarios are not supported yet."));
130
131     }
132
133     /**
134      * if leaf list with no data is in json then no corresponding data is
135      * created in composite node. if leaf with no data then exception is raised
136      */
137     @Test
138     public void emptyDataReadTest() {
139         CompositeNode compositeNode = compositeContainerFromJson("/json-to-composite-node/empty-data.json", true);
140
141         assertNotNull(compositeNode);
142
143         assertEquals("cont", compositeNode.getNodeType().getLocalName());
144         assertTrue(compositeNode instanceof CompositeNode);
145         List<Node<?>> children = ((CompositeNode) compositeNode).getChildren();
146         assertEquals(1, children.size());
147         assertEquals("lflst2", children.get(0).getNodeType().getLocalName());
148         assertEquals("45", children.get(0).getValue());
149
150         String reason = null;
151         try {
152             compositeContainerFromJson("/json-to-composite-node/empty-data1.json", true);
153         } catch (JsonSyntaxException e) {
154             reason = e.getMessage();
155         }
156
157         assertTrue(reason.contains("Expected value at line"));
158
159     }
160
161     private void simpleTest(String jsonPath, String yangPath, String topLevelElementName, String namespace) {
162         CompositeNode compositeNode = compositeContainerFromJson(jsonPath);
163         assertNotNull(compositeNode);
164
165         DataSchemaNode dataSchemaNode = obtainSchemaFromYang(yangPath);
166         assertNotNull(dataSchemaNode);
167
168         supplementNamespace(dataSchemaNode, compositeNode);
169
170         assertTrue(compositeNode instanceof CompositeNodeWrapper);
171         CompositeNode compNode = ((CompositeNodeWrapper) compositeNode).unwrap(null);
172
173         assertEquals(topLevelElementName, compNode.getNodeType().getLocalName());
174         verifyCompositeNode(compNode, namespace);
175     }
176
177     private DataSchemaNode obtainSchemaFromYang(String yangFolder) {
178         Set<Module> modules = null;
179         try {
180             modules = TestUtils.loadModules(ToJsonBasicDataTypesTest.class.getResource(yangFolder).getPath());
181         } catch (FileNotFoundException e) {
182             LOG.error(e.getMessage());
183             assertTrue(false);
184         }
185
186         assertNotNull(modules);
187         assertEquals(1, modules.size());
188         Module module = modules.iterator().next();
189         assertNotNull(module.getChildNodes());
190         assertEquals(1, module.getChildNodes().size());
191         DataSchemaNode dataSchemaNode = module.getChildNodes().iterator().next();
192         return dataSchemaNode;
193     }
194
195     private void supplementNamespace(DataSchemaNode dataSchemaNode, CompositeNode compositeNode) {
196         RestconfImpl restconf = RestconfImpl.getInstance();
197
198         InstanceIdWithSchemaNode instIdAndSchema = new InstanceIdWithSchemaNode(mock(InstanceIdentifier.class),
199                 dataSchemaNode);
200
201         ControllerContext controllerContext = mock(ControllerContext.class);
202         BrokerFacade broker = mock(BrokerFacade.class);
203
204         when(controllerContext.toInstanceIdentifier(any(String.class))).thenReturn(instIdAndSchema);
205         when(broker.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(
206                 new DummyFuture());
207
208         restconf.setControllerContext(controllerContext);
209         restconf.setBroker(broker);
210
211         // method is called only because it contains call of method which
212         // supplement namespaces to compositeNode
213         restconf.createConfigurationData("something", compositeNode);
214     }
215
216     private void verityMultipleItemsInList(CompositeNode compositeNode) {
217         List<Node<?>> childrenNodes = compositeNode.getChildren();
218         assertEquals(4, childrenNodes.size());
219         boolean lf11Found = false;
220         boolean cont11Found = false;
221         boolean lst11Found = false;
222         for (Node<?> lst1Item : childrenNodes) {
223             assertEquals("lst1", lst1Item.getNodeType().getLocalName());
224             assertTrue(lst1Item instanceof CompositeNode);
225
226             List<Node<?>> childrenLst1 = ((CompositeNode) lst1Item).getChildren();
227             assertEquals(1, childrenLst1.size());
228             String localName = childrenLst1.get(0).getNodeType().getLocalName();
229             if (localName.equals("lf11")) {
230                 assertTrue(childrenLst1.get(0) instanceof SimpleNode);
231                 lf11Found = true;
232             } else if (localName.equals("lflst11")) {
233                 assertTrue(childrenLst1.get(0) instanceof SimpleNode);
234                 assertEquals("45", ((SimpleNode<?>) childrenLst1.get(0)).getValue());
235                 lf11Found = true;
236             } else if (localName.equals("cont11")) {
237                 assertTrue(childrenLst1.get(0) instanceof CompositeNode);
238                 cont11Found = true;
239             } else if (localName.equals("lst11")) {
240                 lst11Found = true;
241                 assertTrue(childrenLst1.get(0) instanceof CompositeNode);
242                 assertEquals(0, ((CompositeNode) childrenLst1.get(0)).getChildren().size());
243             }
244
245         }
246         assertTrue(lf11Found);
247         assertTrue(cont11Found);
248         assertTrue(lst11Found);
249     }
250
251     private void verifyCompositeNode(CompositeNode compositeNode, String namespace) {
252         boolean cont1Found = false;
253         boolean lst1Found = false;
254         boolean lflst1_1Found = false;
255         boolean lflst1_2Found = false;
256         boolean lf1Found = false;
257
258         assertEquals(namespace, compositeNode.getNodeType().getNamespace().toString());
259
260         for (Node<?> node : compositeNode.getChildren()) {
261             if (node.getNodeType().getLocalName().equals("cont1")) {
262                 if (node instanceof CompositeNode) {
263                     cont1Found = true;
264                     assertEquals(0, ((CompositeNode) node).getChildren().size());
265                 }
266             } else if (node.getNodeType().getLocalName().equals("lst1")) {
267                 if (node instanceof CompositeNode) {
268                     lst1Found = true;
269                     assertEquals(0, ((CompositeNode) node).getChildren().size());
270                 }
271             } else if (node.getNodeType().getLocalName().equals("lflst1")) {
272                 if (node instanceof SimpleNode) {
273                     if (((SimpleNode<?>) node).getValue().equals("lflst1_1")) {
274                         lflst1_1Found = true;
275                     } else if (((SimpleNode<?>) node).getValue().equals("lflst1_2")) {
276                         lflst1_2Found = true;
277                     }
278                 }
279
280             } else if (node.getNodeType().getLocalName().equals("lf1")) {
281                 if (node instanceof SimpleNode) {
282                     if (((SimpleNode<?>) node).getValue().equals("lf1")) {
283                         lf1Found = true;
284                     }
285                 }
286             }
287             assertEquals(namespace, node.getNodeType().getNamespace().toString());
288         }
289         assertTrue(cont1Found);
290         assertTrue(lst1Found);
291         assertTrue(lflst1_1Found);
292         assertTrue(lflst1_2Found);
293         assertTrue(lf1Found);
294     }
295
296     private CompositeNode compositeContainerFromJson(String jsonPath) {
297         return compositeContainerFromJson(jsonPath, false);
298     }
299
300     private CompositeNode compositeContainerFromJson(String jsonPath, boolean dummyNamespaces)
301             throws WebApplicationException {
302
303         JsonToCompositeNodeProvider jsonToCompositeNodeProvider = JsonToCompositeNodeProvider.INSTANCE;
304         InputStream jsonStream = FromJsonToCompositeNode.class.getResourceAsStream(jsonPath);
305         try {
306             CompositeNode compositeNode = jsonToCompositeNodeProvider
307                     .readFrom(null, null, null, null, null, jsonStream);
308             assertTrue(compositeNode instanceof CompositeNodeWrapper);
309             if (dummyNamespaces) {
310                 try {
311                     addDummyNamespaceToAllNodes((CompositeNodeWrapper) compositeNode);
312                     return ((CompositeNodeWrapper) compositeNode).unwrap(null);
313                 } catch (URISyntaxException e) {
314                     LOG.error(e.getMessage());
315                     assertTrue(e.getMessage(), false);
316                 }
317             }
318             return compositeNode;
319         } catch (IOException e) {
320             LOG.error(e.getMessage());
321             assertTrue(e.getMessage(), false);
322         }
323         return null;
324     }
325
326     private void addDummyNamespaceToAllNodes(NodeWrapper<?> wrappedNode) throws URISyntaxException {
327         wrappedNode.setNamespace(new URI(""));
328         if (wrappedNode instanceof CompositeNodeWrapper) {
329             for (NodeWrapper<?> childNodeWrapper : ((CompositeNodeWrapper) wrappedNode).getValues()) {
330                 addDummyNamespaceToAllNodes(childNodeWrapper);
331             }
332         }
333     }
334 }