1 package org.opendaylight.controller.sal.restconf.impl.test;
3 import static org.mockito.Matchers.any;
4 import static org.mockito.Mockito.mock;
5 import static org.mockito.Mockito.when;
6 import static org.mockito.Mockito.verify;
7 import static org.mockito.Mockito.times;
8 import static org.junit.Assert.assertEquals;
10 import java.io.FileNotFoundException;
11 import java.io.InputStream;
12 import java.io.UnsupportedEncodingException;
14 import java.net.URLEncoder;
15 import java.text.ParseException;
17 import java.util.concurrent.Future;
18 import java.util.logging.Level;
20 import javax.ws.rs.client.Entity;
21 import javax.ws.rs.core.Application;
22 import javax.ws.rs.core.MediaType;
23 import javax.ws.rs.core.Response;
25 import org.glassfish.jersey.server.ResourceConfig;
26 import org.glassfish.jersey.test.JerseyTest;
27 import org.glassfish.jersey.test.TestProperties;
28 import org.junit.BeforeClass;
29 import org.junit.Test;
30 import org.mockito.ArgumentCaptor;
31 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
32 import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
33 import org.opendaylight.controller.sal.rest.impl.XmlMapper;
34 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
35 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
36 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
37 import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
38 import org.opendaylight.yangtools.yang.common.RpcResult;
39 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
40 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
41 import org.opendaylight.yangtools.yang.model.api.Module;
42 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
43 import org.opendaylight.controller.sal.core.api.mount.MountInstance;
44 import org.opendaylight.controller.sal.core.api.mount.MountService;
46 import com.google.common.base.Charsets;
48 public class RestConfigDataTest extends JerseyTest {
50 private static ControllerContext controllerContext;
51 private static BrokerFacade brokerFacade;
52 private static RestconfImpl restconfImpl;
53 private static MountService mountService;
54 private static SchemaContext schemaContext;
56 private static final MediaType MEDIA_TYPE_XML_DRAFT02 = new MediaType("application", "yang.data+xml");
59 public static void init() throws FileNotFoundException {
60 Set<Module> modules = TestUtils.loadModulesFrom("/test-config-data/yang1");
61 schemaContext = TestUtils.loadSchemaContext(modules);
65 private static void initMocking() {
66 controllerContext = ControllerContext.getInstance();
67 controllerContext.setSchemas(schemaContext);
68 mountService = mock(MountService.class);
69 controllerContext.setMountService(mountService);
70 brokerFacade = mock(BrokerFacade.class);
71 restconfImpl = RestconfImpl.getInstance();
72 restconfImpl.setBroker(brokerFacade);
73 restconfImpl.setControllerContext(controllerContext);
77 public void createConfigurationDataTest() throws UnsupportedEncodingException, ParseException {
79 String URI_1 = createUri("/config", "");
80 String URI_2 = createUri("/config/", "");
81 String URI_3 = createUri("/config/", "test-interface:interfaces/");
82 String URI_4 = createUri("/config/", "test-interface:interfaces/");
83 String URI_5 = createUri("/config/", "test-interface:interfaces/test-interface2:class");
85 RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(
86 TransactionStatus.COMMITED).build();
87 Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
89 when(brokerFacade.commitConfigurationDataPost(any(InstanceIdentifier.class), any(CompositeNode.class)))
90 .thenReturn(dummyFuture);
92 ArgumentCaptor<InstanceIdentifier> instanceIdCaptor = ArgumentCaptor.forClass(InstanceIdentifier.class);
93 ArgumentCaptor<CompositeNode> compNodeCaptor = ArgumentCaptor.forClass(CompositeNode.class);
96 Entity<String> entity = createEntity("/test-config-data/xml/test-interface.xml");
97 Response response = target(URI_1).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
98 assertEquals(204, response.getStatus());
99 verify(brokerFacade).commitConfigurationDataPost(instanceIdCaptor.capture(), compNodeCaptor.capture());
100 String identifier = "[(urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)interfaces]";
101 assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
104 response = target(URI_2).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
105 assertEquals(204, response.getStatus());
106 verify(brokerFacade, times(2))
107 .commitConfigurationDataPost(instanceIdCaptor.capture(), compNodeCaptor.capture());
108 assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
111 entity = createEntity("/test-config-data/xml/test-interface2.xml");
112 response = target(URI_3).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
113 assertEquals(204, response.getStatus());
114 verify(brokerFacade, times(3))
115 .commitConfigurationDataPost(instanceIdCaptor.capture(), compNodeCaptor.capture());
117 identifier = "[(urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)interfaces, (urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)interface[{(urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)name=eth0}]]";
118 assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
121 Set<Module> modules2 = TestUtils.loadModulesFrom("/test-config-data/yang2");
122 SchemaContext schemaContext2 = TestUtils.loadSchemaContext(modules2);
123 MountInstance mountInstance = mock(MountInstance.class);
124 when(mountInstance.getSchemaContext()).thenReturn(schemaContext2);
125 when(mountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
127 entity = createEntity("/test-config-data/xml/test-interface3.xml");
128 response = target(URI_4).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
129 assertEquals(204, response.getStatus());
130 verify(brokerFacade, times(4))
131 .commitConfigurationDataPost(instanceIdCaptor.capture(), compNodeCaptor.capture());
132 identifier = "[(urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)interfaces, (urn:ietf:params:xml:ns:yang:test-interface2?revision=2014-08-01)class]";
133 assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
136 response = target(URI_5).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
137 assertEquals(204, response.getStatus());
138 verify(brokerFacade, times(5))
139 .commitConfigurationDataPost(instanceIdCaptor.capture(), compNodeCaptor.capture());
140 identifier = "[(urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)interfaces, (urn:ietf:params:xml:ns:yang:test-interface2?revision=2014-08-01)class, (urn:ietf:params:xml:ns:yang:test-interface2?revision=2014-08-01)class]";
141 assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
145 public void testExistingData() throws UnsupportedEncodingException {
147 String URI_1 = createUri("/config", "");
148 String URI_2 = createUri("/config/", "");
149 String URI_3 = createUri("/config/", "test-interface:interfaces/");
150 String URI_4 = createUri("/config/", "test-interface:interfaces/");
151 String URI_5 = createUri("/config/", "test-interface:interfaces/test-interface2:class");
153 when(brokerFacade.commitConfigurationDataPost(any(InstanceIdentifier.class), any(CompositeNode.class)))
157 Entity<String> entity = createEntity("/test-config-data/xml/test-interface.xml");
158 Response response = target(URI_1).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
159 assertEquals(202, response.getStatus());
162 response = target(URI_2).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
163 assertEquals(202, response.getStatus());
166 entity = createEntity("/test-config-data/xml/test-interface2.xml");
167 response = target(URI_3).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
168 assertEquals(202, response.getStatus());
171 Set<Module> modules2 = TestUtils.loadModulesFrom("/test-config-data/yang2");
172 SchemaContext schemaContext2 = TestUtils.loadSchemaContext(modules2);
173 MountInstance mountInstance = mock(MountInstance.class);
174 when(mountInstance.getSchemaContext()).thenReturn(schemaContext2);
175 when(mountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
177 entity = createEntity("/test-config-data/xml/test-interface3.xml");
178 response = target(URI_4).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
179 assertEquals(202, response.getStatus());
182 response = target(URI_5).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
183 assertEquals(202, response.getStatus());
186 private String createUri(String prefix, String encodedPart) throws UnsupportedEncodingException {
187 return URI.create(prefix + URLEncoder.encode(encodedPart, Charsets.US_ASCII.name()).toString()).toASCIIString();
190 private Entity<String> createEntity(final String relativePathToXml) {
191 InputStream inputStream = XmlMapper.class.getResourceAsStream(relativePathToXml);
192 String xml = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(inputStream));
193 Entity<String> entity = Entity.entity(xml, MEDIA_TYPE_XML_DRAFT02);
199 protected Application configure() {
200 enable(TestProperties.LOG_TRAFFIC);
201 enable(TestProperties.DUMP_ENTITY);
202 enable(TestProperties.RECORD_LOG_LEVEL);
203 set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
205 ResourceConfig resourceConfig = new ResourceConfig();
206 resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
207 XmlToCompositeNodeProvider.INSTANCE);
208 return resourceConfig;