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);
78 public void createConfigurationDataTest() throws UnsupportedEncodingException, ParseException {
80 String URI_1 = createUri("/config", "");
81 String URI_2 = createUri("/config/", "");
82 String URI_3 = createUri("/config/", "test-interface:interfaces/");
83 String URI_4 = createUri("/config/", "test-interface:interfaces/");
84 String URI_5 = createUri("/config/", "test-interface:interfaces/test-interface2:class");
86 RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(
87 TransactionStatus.COMMITED).build();
88 Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
90 when(brokerFacade.commitConfigurationDataPost(any(InstanceIdentifier.class), any(CompositeNode.class)))
91 .thenReturn(dummyFuture);
93 ArgumentCaptor<InstanceIdentifier> instanceIdCaptor = ArgumentCaptor.forClass(InstanceIdentifier.class);
94 ArgumentCaptor<CompositeNode> compNodeCaptor = ArgumentCaptor.forClass(CompositeNode.class);
97 Entity<String> entity = createEntity("/test-config-data/xml/test-interface.xml");
98 Response response = target(URI_1).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
99 assertEquals(204, response.getStatus());
100 verify(brokerFacade).commitConfigurationDataPost(instanceIdCaptor.capture(), compNodeCaptor.capture());
101 String identifier = "[(urn:ietf:params:xml:ns:yang:test-interface?revision=2014-07-01)interfaces]";
102 assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
105 response = target(URI_2).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
106 assertEquals(204, response.getStatus());
107 verify(brokerFacade, times(2))
108 .commitConfigurationDataPost(instanceIdCaptor.capture(), compNodeCaptor.capture());
109 assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
112 entity = createEntity("/test-config-data/xml/test-interface2.xml");
113 response = target(URI_3).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
114 assertEquals(204, response.getStatus());
115 verify(brokerFacade, times(3))
116 .commitConfigurationDataPost(instanceIdCaptor.capture(), compNodeCaptor.capture());
118 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}]]";
119 assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
122 Set<Module> modules2 = TestUtils.loadModulesFrom("/test-config-data/yang2");
123 SchemaContext schemaContext2 = TestUtils.loadSchemaContext(modules2);
124 MountInstance mountInstance = mock(MountInstance.class);
125 when(mountInstance.getSchemaContext()).thenReturn(schemaContext2);
126 when(mountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
128 entity = createEntity("/test-config-data/xml/test-interface3.xml");
129 response = target(URI_4).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
130 assertEquals(204, response.getStatus());
131 verify(brokerFacade, times(4))
132 .commitConfigurationDataPost(instanceIdCaptor.capture(), compNodeCaptor.capture());
133 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]";
134 assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
137 response = target(URI_5).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
138 assertEquals(204, response.getStatus());
139 verify(brokerFacade, times(5))
140 .commitConfigurationDataPost(instanceIdCaptor.capture(), compNodeCaptor.capture());
141 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]";
142 assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
147 public void testExistingData() throws UnsupportedEncodingException {
149 String URI_1 = createUri("/config", "");
150 String URI_2 = createUri("/config/", "");
151 String URI_3 = createUri("/config/", "test-interface:interfaces/");
152 String URI_4 = createUri("/config/", "test-interface:interfaces/");
153 String URI_5 = createUri("/config/", "test-interface:interfaces/test-interface2:class");
155 when(brokerFacade.commitConfigurationDataPost(any(InstanceIdentifier.class), any(CompositeNode.class)))
159 Entity<String> entity = createEntity("/test-config-data/xml/test-interface.xml");
160 Response response = target(URI_1).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
161 assertEquals(202, response.getStatus());
164 response = target(URI_2).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
165 assertEquals(202, response.getStatus());
168 entity = createEntity("/test-config-data/xml/test-interface2.xml");
169 response = target(URI_3).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
170 assertEquals(202, response.getStatus());
173 Set<Module> modules2 = TestUtils.loadModulesFrom("/test-config-data/yang2");
174 SchemaContext schemaContext2 = TestUtils.loadSchemaContext(modules2);
175 MountInstance mountInstance = mock(MountInstance.class);
176 when(mountInstance.getSchemaContext()).thenReturn(schemaContext2);
177 when(mountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
179 entity = createEntity("/test-config-data/xml/test-interface3.xml");
180 response = target(URI_4).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
181 assertEquals(202, response.getStatus());
184 response = target(URI_5).request(MEDIA_TYPE_XML_DRAFT02).post(entity);
185 assertEquals(202, response.getStatus());
188 private String createUri(String prefix, String encodedPart) throws UnsupportedEncodingException {
189 return URI.create(prefix + URLEncoder.encode(encodedPart, Charsets.US_ASCII.name()).toString()).toASCIIString();
192 private Entity<String> createEntity(final String relativePathToXml) {
193 InputStream inputStream = XmlMapper.class.getResourceAsStream(relativePathToXml);
194 String xml = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(inputStream));
195 Entity<String> entity = Entity.entity(xml, MEDIA_TYPE_XML_DRAFT02);
201 protected Application configure() {
202 enable(TestProperties.LOG_TRAFFIC);
203 enable(TestProperties.DUMP_ENTITY);
204 enable(TestProperties.RECORD_LOG_LEVEL);
205 set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
207 ResourceConfig resourceConfig = new ResourceConfig();
208 resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
209 XmlToCompositeNodeProvider.INSTANCE);
210 return resourceConfig;