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 java.io.FileNotFoundException;
11 import java.io.UnsupportedEncodingException;
13 import java.net.URISyntaxException;
14 import java.util.ArrayList;
15 import java.util.List;
16 import java.util.regex.Matcher;
17 import java.util.regex.Pattern;
18 import javax.ws.rs.core.Application;
19 import javax.ws.rs.core.MediaType;
20 import javax.ws.rs.core.Response;
21 import org.glassfish.jersey.server.ResourceConfig;
22 import org.glassfish.jersey.test.JerseyTest;
23 import org.junit.BeforeClass;
24 import org.junit.Test;
25 import org.opendaylight.controller.sal.core.api.mount.MountInstance;
26 import org.opendaylight.controller.sal.core.api.mount.MountService;
27 import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
28 import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
29 import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
30 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
31 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
32 import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
33 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
34 import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
35 import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
36 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
37 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
38 import org.opendaylight.yangtools.yang.data.api.Node;
39 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
40 import static junit.framework.Assert.assertNotNull;
41 import static org.junit.Assert.assertEquals;
42 import static org.junit.Assert.assertTrue;
43 import static org.mockito.Matchers.any;
44 import static org.mockito.Mockito.mock;
45 import static org.mockito.Mockito.when;
47 public class RestGetOperationTest extends JerseyTest {
49 private static BrokerFacade brokerFacade;
50 private static RestconfImpl restconfImpl;
51 private static SchemaContext schemaContextYangsIetf;
52 private static SchemaContext schemaContextTestModule;
53 private static CompositeNode answerFromGet;
55 private static SchemaContext schemaContextModules;
56 private static SchemaContext schemaContextBehindMountPoint;
59 public static void init() throws FileNotFoundException {
60 schemaContextYangsIetf = TestUtils.loadSchemaContext("/full-versions/yangs");
61 schemaContextTestModule = TestUtils.loadSchemaContext("/full-versions/test-module");
62 ControllerContext controllerContext = ControllerContext.getInstance();
63 controllerContext.setSchemas(schemaContextYangsIetf);
64 brokerFacade = mock(BrokerFacade.class);
65 restconfImpl = RestconfImpl.getInstance();
66 restconfImpl.setBroker(brokerFacade);
67 restconfImpl.setControllerContext(controllerContext);
68 answerFromGet = prepareCompositeNodeWithIetfInterfacesInterfacesData();
70 schemaContextModules = TestUtils.loadSchemaContext("/modules");
71 schemaContextBehindMountPoint = TestUtils.loadSchemaContext("/modules/modules-behind-mount-point");
75 protected Application configure() {
76 /* enable/disable Jersey logs to console */
77 // enable(TestProperties.LOG_TRAFFIC);
78 // enable(TestProperties.DUMP_ENTITY);
79 // enable(TestProperties.RECORD_LOG_LEVEL);
80 // set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
81 ResourceConfig resourceConfig = new ResourceConfig();
82 resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
83 StructuredDataToJsonProvider.INSTANCE, XmlToCompositeNodeProvider.INSTANCE,
84 JsonToCompositeNodeProvider.INSTANCE);
85 return resourceConfig;
89 * Tests of status codes for "/operational/{identifier}".
92 public void getOperationalStatusCodes() throws UnsupportedEncodingException {
93 mockReadOperationalDataMethod();
94 String uri = "/operational/ietf-interfaces:interfaces/interface/eth0";
95 assertEquals(200, get(uri, MediaType.APPLICATION_XML));
97 uri = "/operational/wrong-module:interfaces/interface/eth0";
98 assertEquals(400, get(uri, MediaType.APPLICATION_XML));
102 * Tests of status codes for "/config/{identifier}".
105 public void getConfigStatusCodes() throws UnsupportedEncodingException {
106 mockReadConfigurationDataMethod();
107 String uri = "/config/ietf-interfaces:interfaces/interface/eth0";
108 assertEquals(200, get(uri, MediaType.APPLICATION_XML));
110 uri = "/config/wrong-module:interfaces/interface/eth0";
111 assertEquals(400, get(uri, MediaType.APPLICATION_XML));
115 * MountPoint test. URI represents mount point.
118 public void getDataWithUrlMountPoint() throws UnsupportedEncodingException, URISyntaxException {
120 brokerFacade.readConfigurationDataBehindMountPoint(any(MountInstance.class),
121 any(InstanceIdentifier.class))).thenReturn(prepareCnDataForMountPointTest());
122 MountInstance mountInstance = mock(MountInstance.class);
123 when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
124 MountService mockMountService = mock(MountService.class);
125 when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
127 ControllerContext.getInstance().setMountService(mockMountService);
129 String uri = "/config/ietf-interfaces:interfaces/interface/0/yang-ext:mount/test-module:cont/cont1";
130 assertEquals(200, get(uri, MediaType.APPLICATION_XML));
132 uri = "/config/ietf-interfaces:interfaces/yang-ext:mount/test-module:cont/cont1";
133 assertEquals(200, get(uri, MediaType.APPLICATION_XML));
137 public void getDataMountPointIntoHighestElement() throws UnsupportedEncodingException, URISyntaxException {
139 brokerFacade.readConfigurationDataBehindMountPoint(any(MountInstance.class),
140 any(InstanceIdentifier.class))).thenReturn(prepareCnDataForMountPointTest());
141 MountInstance mountInstance = mock(MountInstance.class);
142 when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
143 MountService mockMountService = mock(MountService.class);
144 when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
146 ControllerContext.getInstance().setMountService(mockMountService);
148 String uri = "/config/ietf-interfaces:interfaces/interface/0/yang-ext:mount/";
149 assertEquals(200, get(uri, MediaType.APPLICATION_XML));
154 public void getModulesTest() throws UnsupportedEncodingException, FileNotFoundException {
155 ControllerContext.getInstance().setGlobalSchema(schemaContextModules);
157 String uri = "/modules";
159 Response response = target(uri).request("application/yang.api+json").get();
160 validateModulesResponseJson(response);
162 response = target(uri).request("application/yang.api+xml").get();
163 validateModulesResponseXml(response);
167 public void getStreamsTest() throws UnsupportedEncodingException, FileNotFoundException {
168 ControllerContext.getInstance().setGlobalSchema(schemaContextModules);
170 String uri = "/streams";
172 Response response = target(uri).request("application/yang.api+json").get();
173 String responseBody = response.readEntity(String.class);
174 assertNotNull(responseBody);
175 assertTrue(responseBody.contains("streams"));
177 response = target(uri).request("application/yang.api+xml").get();
178 responseBody = response.readEntity(String.class);
179 assertNotNull(responseBody);
180 assertTrue(responseBody.contains("<streams xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf\"/>"));
185 public void getModuleTest() throws FileNotFoundException, UnsupportedEncodingException {
186 ControllerContext.getInstance().setGlobalSchema(schemaContextModules);
188 String uri = "/modules/module/module2/2014-01-02";
190 Response response = target(uri).request("application/yang.api+xml").get();
191 assertEquals(200, response.getStatus());
192 String responseBody = response.readEntity(String.class);
193 assertTrue("Module2 in xml wasn't found", prepareXmlRegex("module2", "2014-01-02", "module:2", responseBody)
195 String[] split = responseBody.split("<module");
196 assertEquals("<module element is returned more then once",2,split.length);
198 response = target(uri).request("application/yang.api+json").get();
199 assertEquals(200, response.getStatus());
200 responseBody = response.readEntity(String.class);
201 assertTrue("Module2 in json wasn't found", prepareJsonRegex("module2", "2014-01-02", "module:2", responseBody)
203 split = responseBody.split("\"module\"");
204 assertEquals("\"module\" element is returned more then once",2,split.length);
210 public void getOperationsTest() throws FileNotFoundException, UnsupportedEncodingException {
211 ControllerContext.getInstance().setGlobalSchema(schemaContextModules);
213 String uri = "/operations";
215 Response response = target(uri).request("application/yang.api+xml").get();
216 assertEquals(200, response.getStatus());
217 String responseBody = response.readEntity(String.class);
218 assertTrue("Xml response for /operations dummy-rpc1-module1 is incorrect",
219 validateOperationsResponseXml(responseBody, "dummy-rpc1-module1", "module:1").find());
220 assertTrue("Xml response for /operations dummy-rpc2-module1 is incorrect",
221 validateOperationsResponseXml(responseBody, "dummy-rpc2-module1", "module:1").find());
222 assertTrue("Xml response for /operations dummy-rpc1-module2 is incorrect",
223 validateOperationsResponseXml(responseBody, "dummy-rpc1-module2", "module:2").find());
224 assertTrue("Xml response for /operations dummy-rpc2-module2 is incorrect",
225 validateOperationsResponseXml(responseBody, "dummy-rpc2-module2", "module:2").find());
227 response = target(uri).request("application/yang.api+json").get();
228 assertEquals(200, response.getStatus());
229 responseBody = response.readEntity(String.class);
230 assertTrue("Json response for /operations dummy-rpc1-module1 is incorrect",
231 validateOperationsResponseJson(responseBody, "dummy-rpc1-module1", "module1").find());
232 assertTrue("Json response for /operations dummy-rpc2-module1 is incorrect",
233 validateOperationsResponseJson(responseBody, "dummy-rpc2-module1", "module1").find());
234 assertTrue("Json response for /operations dummy-rpc1-module2 is incorrect",
235 validateOperationsResponseJson(responseBody, "dummy-rpc1-module2", "module2").find());
236 assertTrue("Json response for /operations dummy-rpc2-module2 is incorrect",
237 validateOperationsResponseJson(responseBody, "dummy-rpc2-module2", "module2").find());
241 // /operations/pathToMountPoint/yang-ext:mount
243 public void getOperationsBehindMountPointTest() throws FileNotFoundException, UnsupportedEncodingException {
244 ControllerContext controllerContext = ControllerContext.getInstance();
245 controllerContext.setGlobalSchema(schemaContextModules);
247 MountInstance mountInstance = mock(MountInstance.class);
248 when(mountInstance.getSchemaContext()).thenReturn(schemaContextBehindMountPoint);
249 MountService mockMountService = mock(MountService.class);
250 when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
252 controllerContext.setMountService(mockMountService);
254 String uri = "/operations/ietf-interfaces:interfaces/interface/0/yang-ext:mount/";
256 Response response = target(uri).request("application/yang.api+xml").get();
257 assertEquals(200, response.getStatus());
258 String responseBody = response.readEntity(String.class);
259 assertTrue("Xml response for /operations/mount_point rpc-behind-module1 is incorrect",
260 validateOperationsResponseXml(responseBody, "rpc-behind-module1", "module:1:behind:mount:point").find());
261 assertTrue("Xml response for /operations/mount_point rpc-behind-module2 is incorrect",
262 validateOperationsResponseXml(responseBody, "rpc-behind-module2", "module:2:behind:mount:point").find());
264 response = target(uri).request("application/yang.api+json").get();
265 assertEquals(200, response.getStatus());
266 responseBody = response.readEntity(String.class);
267 assertTrue("Json response for /operations/mount_point rpc-behind-module1 is incorrect",
268 validateOperationsResponseJson(responseBody, "rpc-behind-module1", "module1-behind-mount-point").find());
269 assertTrue("Json response for /operations/mount_point rpc-behind-module2 is incorrect",
270 validateOperationsResponseJson(responseBody, "rpc-behind-module2", "module2-behind-mount-point").find());
274 private Matcher validateOperationsResponseJson(String searchIn, String rpcName, String moduleName) {
275 StringBuilder regex = new StringBuilder();
278 regex.append(".*\\{");
279 regex.append(".*\"");
281 // operations prefix optional
283 regex.append("ietf-restconf:");
285 // :operations prefix optional
287 regex.append("operations\"");
289 regex.append(".*\\{");
291 regex.append(".*\"" + moduleName);
293 regex.append(rpcName + "\"");
294 regex.append(".*\\[");
295 regex.append(".*null");
296 regex.append(".*\\]");
298 regex.append(".*\\}");
299 regex.append(".*\\}");
303 Pattern ptrn = Pattern.compile(regex.toString(), Pattern.DOTALL);
304 return ptrn.matcher(searchIn);
308 private Matcher validateOperationsResponseXml(String searchIn, String rpcName, String namespace) {
309 StringBuilder regex = new StringBuilder();
313 regex.append(".*<operations");
314 regex.append(".*xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf\"");
318 regex.append(".*" + rpcName);
319 regex.append(".*" + namespace);
323 regex.append(".*</operations.*");
328 Pattern ptrn = Pattern.compile(regex.toString(), Pattern.DOTALL);
329 return ptrn.matcher(searchIn);
332 // /restconf/modules/pathToMountPoint/yang-ext:mount
334 public void getModulesBehindMountPoint() throws FileNotFoundException, UnsupportedEncodingException {
335 ControllerContext controllerContext = ControllerContext.getInstance();
336 controllerContext.setGlobalSchema(schemaContextModules);
338 MountInstance mountInstance = mock(MountInstance.class);
339 when(mountInstance.getSchemaContext()).thenReturn(schemaContextBehindMountPoint);
340 MountService mockMountService = mock(MountService.class);
341 when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
343 controllerContext.setMountService(mockMountService);
345 String uri = "/modules/ietf-interfaces:interfaces/interface/0/yang-ext:mount/";
347 Response response = target(uri).request("application/yang.api+json").get();
348 assertEquals(200, response.getStatus());
349 String responseBody = response.readEntity(String.class);
352 "module1-behind-mount-point in json wasn't found",
353 prepareJsonRegex("module1-behind-mount-point", "2014-02-03", "module:1:behind:mount:point",
354 responseBody).find());
356 "module2-behind-mount-point in json wasn't found",
357 prepareJsonRegex("module2-behind-mount-point", "2014-02-04", "module:2:behind:mount:point",
358 responseBody).find());
360 response = target(uri).request("application/yang.api+xml").get();
361 assertEquals(200, response.getStatus());
362 responseBody = response.readEntity(String.class);
364 "module1-behind-mount-point in json wasn't found",
365 prepareXmlRegex("module1-behind-mount-point", "2014-02-03", "module:1:behind:mount:point", responseBody)
368 "module2-behind-mount-point in json wasn't found",
369 prepareXmlRegex("module2-behind-mount-point", "2014-02-04", "module:2:behind:mount:point", responseBody)
374 // /restconf/modules/module/pathToMountPoint/yang-ext:mount/moduleName/revision
376 public void getModuleBehindMountPoint() throws FileNotFoundException, UnsupportedEncodingException {
377 ControllerContext controllerContext = ControllerContext.getInstance();
378 controllerContext.setGlobalSchema(schemaContextModules);
380 MountInstance mountInstance = mock(MountInstance.class);
381 when(mountInstance.getSchemaContext()).thenReturn(schemaContextBehindMountPoint);
382 MountService mockMountService = mock(MountService.class);
383 when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
385 controllerContext.setMountService(mockMountService);
387 String uri = "/modules/module/ietf-interfaces:interfaces/interface/0/yang-ext:mount/module1-behind-mount-point/2014-02-03";
389 Response response = target(uri).request("application/yang.api+json").get();
390 assertEquals(200, response.getStatus());
391 String responseBody = response.readEntity(String.class);
394 "module1-behind-mount-point in json wasn't found",
395 prepareJsonRegex("module1-behind-mount-point", "2014-02-03", "module:1:behind:mount:point",
396 responseBody).find());
397 String[] split = responseBody.split("\"module\"");
398 assertEquals("\"module\" element is returned more then once",2,split.length);
401 response = target(uri).request("application/yang.api+xml").get();
402 assertEquals(200, response.getStatus());
403 responseBody = response.readEntity(String.class);
405 "module1-behind-mount-point in json wasn't found",
406 prepareXmlRegex("module1-behind-mount-point", "2014-02-03", "module:1:behind:mount:point", responseBody)
408 split = responseBody.split("<module");
409 assertEquals("<module element is returned more then once",2,split.length);
416 private void validateModulesResponseXml(Response response) {
417 assertEquals(200, response.getStatus());
418 String responseBody = response.readEntity(String.class);
420 assertTrue("Module1 in xml wasn't found", prepareXmlRegex("module1", "2014-01-01", "module:1", responseBody)
422 assertTrue("Module2 in xml wasn't found", prepareXmlRegex("module2", "2014-01-02", "module:2", responseBody)
424 assertTrue("Module3 in xml wasn't found", prepareXmlRegex("module3", "2014-01-03", "module:3", responseBody)
428 private void validateModulesResponseJson(Response response) {
429 assertEquals(200, response.getStatus());
430 String responseBody = response.readEntity(String.class);
432 assertTrue("Module1 in json wasn't found", prepareJsonRegex("module1", "2014-01-01", "module:1", responseBody)
434 assertTrue("Module2 in json wasn't found", prepareJsonRegex("module2", "2014-01-02", "module:2", responseBody)
436 assertTrue("Module3 in json wasn't found", prepareJsonRegex("module3", "2014-01-03", "module:3", responseBody)
440 private Matcher prepareJsonRegex(String module, String revision, String namespace, String searchIn) {
441 StringBuilder regex = new StringBuilder();
444 regex.append(".*\\{");
445 regex.append(".*\"name\"");
447 regex.append(".*\"" + module + "\",");
449 regex.append(".*\"revision\"");
451 regex.append(".*\"" + revision + "\",");
453 regex.append(".*\"namespace\"");
455 regex.append(".*\"" + namespace + "\"");
457 regex.append(".*\\}");
461 Pattern ptrn = Pattern.compile(regex.toString(), Pattern.DOTALL);
462 return ptrn.matcher(searchIn);
466 private Matcher prepareXmlRegex(String module, String revision, String namespace, String searchIn) {
467 StringBuilder regex = new StringBuilder();
470 regex.append(".*<module.*");
473 regex.append(".*<name>");
474 regex.append(".*" + module);
475 regex.append(".*<\\/name>");
477 regex.append(".*<revision>");
478 regex.append(".*" + revision);
479 regex.append(".*<\\/revision>");
481 regex.append(".*<namespace>");
482 regex.append(".*" + namespace);
483 regex.append(".*<\\/namespace>");
485 regex.append(".*<\\/module.*>");
490 Pattern ptrn = Pattern.compile(regex.toString(), Pattern.DOTALL);
491 return ptrn.matcher(searchIn);
494 private void prepareMockForModulesTest(ControllerContext mockedControllerContext) throws FileNotFoundException {
495 SchemaContext schemaContext = TestUtils.loadSchemaContext("/modules");
496 mockedControllerContext.setGlobalSchema(schemaContext);
497 // when(mockedControllerContext.getGlobalSchema()).thenReturn(schemaContext);
500 private int get(String uri, String mediaType) {
501 return target(uri).request(mediaType).get().getStatus();
504 private CompositeNode prepareCnDataForMountPointTest() throws URISyntaxException {
505 CompositeNodeWrapper cont1 = new CompositeNodeWrapper(new URI("test:module"), "cont1");
506 SimpleNodeWrapper lf11 = new SimpleNodeWrapper(new URI("test:module"), "lf11", "lf11 value");
507 cont1.addValue(lf11);
508 return cont1.unwrap();
511 private void mockReadOperationalDataMethod() {
512 when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(answerFromGet);
515 private void mockReadConfigurationDataMethod() {
516 when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(answerFromGet);
519 private static CompositeNode prepareCompositeNodeWithIetfInterfacesInterfacesData() {
520 CompositeNode intface;
522 intface = new CompositeNodeWrapper(new URI("interface"), "interface");
523 List<Node<?>> childs = new ArrayList<>();
525 childs.add(new SimpleNodeWrapper(new URI("name"), "name", "eth0"));
526 childs.add(new SimpleNodeWrapper(new URI("type"), "type", "ethernetCsmacd"));
527 childs.add(new SimpleNodeWrapper(new URI("enabled"), "enabled", Boolean.FALSE));
528 childs.add(new SimpleNodeWrapper(new URI("description"), "description", "some interface"));
529 intface.setValue(childs);
531 } catch (URISyntaxException e) {