2 * Copyright (c) 2014 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.controller.sal.restconf.impl.test;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertTrue;
12 import static org.mockito.Matchers.any;
13 import static org.mockito.Mockito.mock;
14 import static org.mockito.Mockito.when;
16 import java.io.FileNotFoundException;
17 import java.io.UnsupportedEncodingException;
19 import java.net.URISyntaxException;
20 import java.util.ArrayList;
21 import java.util.List;
22 import java.util.regex.Matcher;
23 import java.util.regex.Pattern;
25 import javax.ws.rs.core.Application;
26 import javax.ws.rs.core.MediaType;
27 import javax.ws.rs.core.Response;
29 import org.glassfish.jersey.server.ResourceConfig;
30 import org.glassfish.jersey.test.JerseyTest;
31 import org.junit.BeforeClass;
32 import org.junit.Test;
33 import org.opendaylight.controller.sal.core.api.mount.MountInstance;
34 import org.opendaylight.controller.sal.core.api.mount.MountService;
35 import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
36 import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
37 import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
38 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
39 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
40 import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
41 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
42 import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
43 import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
44 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
45 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
46 import org.opendaylight.yangtools.yang.data.api.Node;
47 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
49 public class RestGetOperationTest extends JerseyTest {
51 private static BrokerFacade brokerFacade;
52 private static RestconfImpl restconfImpl;
53 private static SchemaContext schemaContextYangsIetf;
54 private static SchemaContext schemaContextTestModule;
55 private static CompositeNode answerFromGet;
57 private static SchemaContext schemaContextModules;
58 private static SchemaContext schemaContextBehindMountPoint;
61 public static void init() throws FileNotFoundException {
62 schemaContextYangsIetf = TestUtils.loadSchemaContext("/full-versions/yangs");
63 schemaContextTestModule = TestUtils.loadSchemaContext("/full-versions/test-module");
64 ControllerContext controllerContext = ControllerContext.getInstance();
65 controllerContext.setSchemas(schemaContextYangsIetf);
66 brokerFacade = mock(BrokerFacade.class);
67 restconfImpl = RestconfImpl.getInstance();
68 restconfImpl.setBroker(brokerFacade);
69 restconfImpl.setControllerContext(controllerContext);
70 answerFromGet = prepareCompositeNodeWithIetfInterfacesInterfacesData();
72 schemaContextModules = TestUtils.loadSchemaContext("/modules");
73 schemaContextBehindMountPoint = TestUtils.loadSchemaContext("/modules/modules-behind-mount-point");
77 protected Application configure() {
78 /* enable/disable Jersey logs to console */
79 // enable(TestProperties.LOG_TRAFFIC);
80 // enable(TestProperties.DUMP_ENTITY);
81 // enable(TestProperties.RECORD_LOG_LEVEL);
82 // set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
83 ResourceConfig resourceConfig = new ResourceConfig();
84 resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
85 StructuredDataToJsonProvider.INSTANCE, XmlToCompositeNodeProvider.INSTANCE,
86 JsonToCompositeNodeProvider.INSTANCE);
87 return resourceConfig;
91 * Tests of status codes for "/operational/{identifier}".
94 public void getOperationalStatusCodes() throws UnsupportedEncodingException {
95 mockReadOperationalDataMethod();
96 String uri = "/operational/ietf-interfaces:interfaces/interface/eth0";
97 assertEquals(200, get(uri, MediaType.APPLICATION_XML));
99 uri = "/operational/wrong-module:interfaces/interface/eth0";
100 assertEquals(400, get(uri, MediaType.APPLICATION_XML));
104 * Tests of status codes for "/config/{identifier}".
107 public void getConfigStatusCodes() throws UnsupportedEncodingException {
108 mockReadConfigurationDataMethod();
109 String uri = "/config/ietf-interfaces:interfaces/interface/eth0";
110 assertEquals(200, get(uri, MediaType.APPLICATION_XML));
112 uri = "/config/wrong-module:interfaces/interface/eth0";
113 assertEquals(400, get(uri, MediaType.APPLICATION_XML));
117 * MountPoint test. URI represents mount point.
120 public void getDataWithUrlMountPoint() throws UnsupportedEncodingException, URISyntaxException {
122 brokerFacade.readConfigurationDataBehindMountPoint(any(MountInstance.class),
123 any(InstanceIdentifier.class))).thenReturn(prepareCnDataForMountPointTest());
124 MountInstance mountInstance = mock(MountInstance.class);
125 when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
126 MountService mockMountService = mock(MountService.class);
127 when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
129 ControllerContext.getInstance().setMountService(mockMountService);
131 String uri = "/config/ietf-interfaces:interfaces/interface/0/yang-ext:mount/test-module:cont/cont1";
132 assertEquals(200, get(uri, MediaType.APPLICATION_XML));
134 uri = "/config/ietf-interfaces:interfaces/yang-ext:mount/test-module:cont/cont1";
135 assertEquals(200, get(uri, MediaType.APPLICATION_XML));
139 public void getDataMountPointIntoHighestElement() throws UnsupportedEncodingException, URISyntaxException {
141 brokerFacade.readConfigurationDataBehindMountPoint(any(MountInstance.class),
142 any(InstanceIdentifier.class))).thenReturn(prepareCnDataForMountPointTest());
143 MountInstance mountInstance = mock(MountInstance.class);
144 when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
145 MountService mockMountService = mock(MountService.class);
146 when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
148 ControllerContext.getInstance().setMountService(mockMountService);
150 String uri = "/config/ietf-interfaces:interfaces/interface/0/yang-ext:mount/";
151 assertEquals(200, get(uri, MediaType.APPLICATION_XML));
156 public void getModulesTest() throws UnsupportedEncodingException, FileNotFoundException {
157 ControllerContext.getInstance().setGlobalSchema(schemaContextModules);
159 String uri = "/modules";
161 Response response = target(uri).request("application/yang.api+json").get();
162 validateModulesResponseJson(response);
164 response = target(uri).request("application/yang.api+xml").get();
165 validateModulesResponseXml(response);
170 public void getModuleTest() throws FileNotFoundException, UnsupportedEncodingException {
171 ControllerContext.getInstance().setGlobalSchema(schemaContextModules);
173 String uri = "/modules/module/module2/2014-01-02";
175 Response response = target(uri).request("application/yang.api+xml").get();
176 assertEquals(200, response.getStatus());
177 String responseBody = response.readEntity(String.class);
178 assertTrue("Module2 in xml wasn't found", prepareXmlRegex("module2", "2014-01-02", "module:2", responseBody)
180 String[] split = responseBody.split("<module");
181 assertEquals("<module element is returned more then once",2,split.length);
183 response = target(uri).request("application/yang.api+json").get();
184 assertEquals(200, response.getStatus());
185 responseBody = response.readEntity(String.class);
186 assertTrue("Module2 in json wasn't found", prepareJsonRegex("module2", "2014-01-02", "module:2", responseBody)
188 split = responseBody.split("\"module\"");
189 assertEquals("\"module\" element is returned more then once",2,split.length);
195 public void getOperationsTest() throws FileNotFoundException, UnsupportedEncodingException {
196 ControllerContext.getInstance().setGlobalSchema(schemaContextModules);
198 String uri = "/operations";
200 Response response = target(uri).request("application/yang.api+xml").get();
201 assertEquals(200, response.getStatus());
202 String responseBody = response.readEntity(String.class);
203 assertTrue("Xml response for /operations dummy-rpc1-module1 is incorrect",
204 validateOperationsResponseXml(responseBody, "dummy-rpc1-module1", "module:1").find());
205 assertTrue("Xml response for /operations dummy-rpc2-module1 is incorrect",
206 validateOperationsResponseXml(responseBody, "dummy-rpc2-module1", "module:1").find());
207 assertTrue("Xml response for /operations dummy-rpc1-module2 is incorrect",
208 validateOperationsResponseXml(responseBody, "dummy-rpc1-module2", "module:2").find());
209 assertTrue("Xml response for /operations dummy-rpc2-module2 is incorrect",
210 validateOperationsResponseXml(responseBody, "dummy-rpc2-module2", "module:2").find());
212 response = target(uri).request("application/yang.api+json").get();
213 assertEquals(200, response.getStatus());
214 responseBody = response.readEntity(String.class);
215 assertTrue("Json response for /operations dummy-rpc1-module1 is incorrect",
216 validateOperationsResponseJson(responseBody, "dummy-rpc1-module1", "module1").find());
217 assertTrue("Json response for /operations dummy-rpc2-module1 is incorrect",
218 validateOperationsResponseJson(responseBody, "dummy-rpc2-module1", "module1").find());
219 assertTrue("Json response for /operations dummy-rpc1-module2 is incorrect",
220 validateOperationsResponseJson(responseBody, "dummy-rpc1-module2", "module2").find());
221 assertTrue("Json response for /operations dummy-rpc2-module2 is incorrect",
222 validateOperationsResponseJson(responseBody, "dummy-rpc2-module2", "module2").find());
226 // /operations/pathToMountPoint/yang-ext:mount
228 public void getOperationsBehindMountPointTest() throws FileNotFoundException, UnsupportedEncodingException {
229 ControllerContext controllerContext = ControllerContext.getInstance();
230 controllerContext.setGlobalSchema(schemaContextModules);
232 MountInstance mountInstance = mock(MountInstance.class);
233 when(mountInstance.getSchemaContext()).thenReturn(schemaContextBehindMountPoint);
234 MountService mockMountService = mock(MountService.class);
235 when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
237 controllerContext.setMountService(mockMountService);
239 String uri = "/operations/ietf-interfaces:interfaces/interface/0/yang-ext:mount/";
241 Response response = target(uri).request("application/yang.api+xml").get();
242 assertEquals(200, response.getStatus());
243 String responseBody = response.readEntity(String.class);
244 assertTrue("Xml response for /operations/mount_point rpc-behind-module1 is incorrect",
245 validateOperationsResponseXml(responseBody, "rpc-behind-module1", "module:1:behind:mount:point").find());
246 assertTrue("Xml response for /operations/mount_point rpc-behind-module2 is incorrect",
247 validateOperationsResponseXml(responseBody, "rpc-behind-module2", "module:2:behind:mount:point").find());
249 response = target(uri).request("application/yang.api+json").get();
250 assertEquals(200, response.getStatus());
251 responseBody = response.readEntity(String.class);
252 assertTrue("Json response for /operations/mount_point rpc-behind-module1 is incorrect",
253 validateOperationsResponseJson(responseBody, "rpc-behind-module1", "module1-behind-mount-point").find());
254 assertTrue("Json response for /operations/mount_point rpc-behind-module2 is incorrect",
255 validateOperationsResponseJson(responseBody, "rpc-behind-module2", "module2-behind-mount-point").find());
259 private Matcher validateOperationsResponseJson(String searchIn, String rpcName, String moduleName) {
260 StringBuilder regex = new StringBuilder();
263 regex.append(".*\\{");
264 regex.append(".*\"");
266 // operations prefix optional
268 regex.append("ietf-restconf:");
270 // :operations prefix optional
272 regex.append("operations\"");
274 regex.append(".*\\{");
276 regex.append(".*\"" + moduleName);
278 regex.append(rpcName + "\"");
279 regex.append(".*\\[");
280 regex.append(".*null");
281 regex.append(".*\\]");
283 regex.append(".*\\}");
284 regex.append(".*\\}");
288 Pattern ptrn = Pattern.compile(regex.toString(), Pattern.DOTALL);
289 return ptrn.matcher(searchIn);
293 private Matcher validateOperationsResponseXml(String searchIn, String rpcName, String namespace) {
294 StringBuilder regex = new StringBuilder();
298 regex.append(".*<operations");
299 regex.append(".*xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf\"");
303 regex.append(".*" + rpcName);
304 regex.append(".*" + namespace);
308 regex.append(".*</operations.*");
313 Pattern ptrn = Pattern.compile(regex.toString(), Pattern.DOTALL);
314 return ptrn.matcher(searchIn);
317 // /restconf/modules/pathToMountPoint/yang-ext:mount
319 public void getModulesBehindMountPoint() throws FileNotFoundException, UnsupportedEncodingException {
320 ControllerContext controllerContext = ControllerContext.getInstance();
321 controllerContext.setGlobalSchema(schemaContextModules);
323 MountInstance mountInstance = mock(MountInstance.class);
324 when(mountInstance.getSchemaContext()).thenReturn(schemaContextBehindMountPoint);
325 MountService mockMountService = mock(MountService.class);
326 when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
328 controllerContext.setMountService(mockMountService);
330 String uri = "/modules/ietf-interfaces:interfaces/interface/0/yang-ext:mount/";
332 Response response = target(uri).request("application/yang.api+json").get();
333 assertEquals(200, response.getStatus());
334 String responseBody = response.readEntity(String.class);
337 "module1-behind-mount-point in json wasn't found",
338 prepareJsonRegex("module1-behind-mount-point", "2014-02-03", "module:1:behind:mount:point",
339 responseBody).find());
341 "module2-behind-mount-point in json wasn't found",
342 prepareJsonRegex("module2-behind-mount-point", "2014-02-04", "module:2:behind:mount:point",
343 responseBody).find());
345 response = target(uri).request("application/yang.api+xml").get();
346 assertEquals(200, response.getStatus());
347 responseBody = response.readEntity(String.class);
349 "module1-behind-mount-point in json wasn't found",
350 prepareXmlRegex("module1-behind-mount-point", "2014-02-03", "module:1:behind:mount:point", responseBody)
353 "module2-behind-mount-point in json wasn't found",
354 prepareXmlRegex("module2-behind-mount-point", "2014-02-04", "module:2:behind:mount:point", responseBody)
359 // /restconf/modules/module/pathToMountPoint/yang-ext:mount/moduleName/revision
361 public void getModuleBehindMountPoint() throws FileNotFoundException, UnsupportedEncodingException {
362 ControllerContext controllerContext = ControllerContext.getInstance();
363 controllerContext.setGlobalSchema(schemaContextModules);
365 MountInstance mountInstance = mock(MountInstance.class);
366 when(mountInstance.getSchemaContext()).thenReturn(schemaContextBehindMountPoint);
367 MountService mockMountService = mock(MountService.class);
368 when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
370 controllerContext.setMountService(mockMountService);
372 String uri = "/modules/module/ietf-interfaces:interfaces/interface/0/yang-ext:mount/module1-behind-mount-point/2014-02-03";
374 Response response = target(uri).request("application/yang.api+json").get();
375 assertEquals(200, response.getStatus());
376 String responseBody = response.readEntity(String.class);
379 "module1-behind-mount-point in json wasn't found",
380 prepareJsonRegex("module1-behind-mount-point", "2014-02-03", "module:1:behind:mount:point",
381 responseBody).find());
382 String[] split = responseBody.split("\"module\"");
383 assertEquals("\"module\" element is returned more then once",2,split.length);
386 response = target(uri).request("application/yang.api+xml").get();
387 assertEquals(200, response.getStatus());
388 responseBody = response.readEntity(String.class);
390 "module1-behind-mount-point in json wasn't found",
391 prepareXmlRegex("module1-behind-mount-point", "2014-02-03", "module:1:behind:mount:point", responseBody)
393 split = responseBody.split("<module");
394 assertEquals("<module element is returned more then once",2,split.length);
401 private void validateModulesResponseXml(Response response) {
402 assertEquals(200, response.getStatus());
403 String responseBody = response.readEntity(String.class);
405 assertTrue("Module1 in xml wasn't found", prepareXmlRegex("module1", "2014-01-01", "module:1", responseBody)
407 assertTrue("Module2 in xml wasn't found", prepareXmlRegex("module2", "2014-01-02", "module:2", responseBody)
409 assertTrue("Module3 in xml wasn't found", prepareXmlRegex("module3", "2014-01-03", "module:3", responseBody)
413 private void validateModulesResponseJson(Response response) {
414 assertEquals(200, response.getStatus());
415 String responseBody = response.readEntity(String.class);
417 assertTrue("Module1 in json wasn't found", prepareJsonRegex("module1", "2014-01-01", "module:1", responseBody)
419 assertTrue("Module2 in json wasn't found", prepareJsonRegex("module2", "2014-01-02", "module:2", responseBody)
421 assertTrue("Module3 in json wasn't found", prepareJsonRegex("module3", "2014-01-03", "module:3", responseBody)
425 private Matcher prepareJsonRegex(String module, String revision, String namespace, String searchIn) {
426 StringBuilder regex = new StringBuilder();
429 regex.append(".*\\{");
430 regex.append(".*\"name\"");
432 regex.append(".*\"" + module + "\",");
434 regex.append(".*\"revision\"");
436 regex.append(".*\"" + revision + "\",");
438 regex.append(".*\"namespace\"");
440 regex.append(".*\"" + namespace + "\"");
442 regex.append(".*\\}");
446 Pattern ptrn = Pattern.compile(regex.toString(), Pattern.DOTALL);
447 return ptrn.matcher(searchIn);
451 private Matcher prepareXmlRegex(String module, String revision, String namespace, String searchIn) {
452 StringBuilder regex = new StringBuilder();
455 regex.append(".*<module.*");
458 regex.append(".*<name>");
459 regex.append(".*" + module);
460 regex.append(".*<\\/name>");
462 regex.append(".*<revision>");
463 regex.append(".*" + revision);
464 regex.append(".*<\\/revision>");
466 regex.append(".*<namespace>");
467 regex.append(".*" + namespace);
468 regex.append(".*<\\/namespace>");
470 regex.append(".*<\\/module.*>");
475 Pattern ptrn = Pattern.compile(regex.toString(), Pattern.DOTALL);
476 return ptrn.matcher(searchIn);
479 private void prepareMockForModulesTest(ControllerContext mockedControllerContext) throws FileNotFoundException {
480 SchemaContext schemaContext = TestUtils.loadSchemaContext("/modules");
481 mockedControllerContext.setGlobalSchema(schemaContext);
482 // when(mockedControllerContext.getGlobalSchema()).thenReturn(schemaContext);
485 private int get(String uri, String mediaType) {
486 return target(uri).request(mediaType).get().getStatus();
489 private CompositeNode prepareCnDataForMountPointTest() throws URISyntaxException {
490 CompositeNodeWrapper cont1 = new CompositeNodeWrapper(new URI("test:module"), "cont1");
491 SimpleNodeWrapper lf11 = new SimpleNodeWrapper(new URI("test:module"), "lf11", "lf11 value");
492 cont1.addValue(lf11);
493 return cont1.unwrap();
496 private void mockReadOperationalDataMethod() {
497 when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(answerFromGet);
500 private void mockReadConfigurationDataMethod() {
501 when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(answerFromGet);
504 private static CompositeNode prepareCompositeNodeWithIetfInterfacesInterfacesData() {
505 CompositeNode intface;
507 intface = new CompositeNodeWrapper(new URI("interface"), "interface");
508 List<Node<?>> childs = new ArrayList<>();
510 childs.add(new SimpleNodeWrapper(new URI("name"), "name", "eth0"));
511 childs.add(new SimpleNodeWrapper(new URI("type"), "type", "ethernetCsmacd"));
512 childs.add(new SimpleNodeWrapper(new URI("enabled"), "enabled", Boolean.FALSE));
513 childs.add(new SimpleNodeWrapper(new URI("description"), "description", "some interface"));
514 intface.setValue(childs);
516 } catch (URISyntaxException e) {