Add unit test of openstack node REST API
Change-Id: I114dcec0558b450cc0fd5683cca91ee07ee8e733
diff --git a/apps/openstacknode/app/BUCK b/apps/openstacknode/app/BUCK
index ee11cb5..4612f6a 100644
--- a/apps/openstacknode/app/BUCK
+++ b/apps/openstacknode/app/BUCK
@@ -16,6 +16,8 @@
'//lib:TEST_ADAPTERS',
'//core/api:onos-api-tests',
'//core/common:onos-core-common-tests',
+ '//web/api:onos-rest-tests',
+ '//lib:TEST_REST',
]
osgi_jar_with_tests (
diff --git a/apps/openstacknode/app/pom.xml b/apps/openstacknode/app/pom.xml
index 7a2cec2..3555cf8 100644
--- a/apps/openstacknode/app/pom.xml
+++ b/apps/openstacknode/app/pom.xml
@@ -40,6 +40,14 @@
org.onosproject.ovsdb-base,
org.onosproject.drivers.ovsdb
</onos.app.requires>
+
+ <web.context>/onos/openstacknode</web.context>
+ <api.version>1.0</api.version>
+ <api.title>OpenStack Node API</api.title>
+ <api.description>
+ REST API for OpenStack Node
+ </api.description>
+ <api.package>org.onosproject.openstacknode.web</api.package>
</properties>
<dependencies>
@@ -123,5 +131,68 @@
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.core</groupId>
+ <artifactId>jersey-client</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-servlet</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework</groupId>
+ <artifactId>jersey-test-framework-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+ <artifactId>jersey-test-framework-provider-jetty</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onlab-osgi</artifactId>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-rest</artifactId>
+ <version>${project.version}</version>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
+
</dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <_wab>src/main/webapp/</_wab>
+ <Include-Resource>
+ WEB-INF/classes/apidoc/swagger.json=target/swagger.json,
+ {maven-resources}
+ </Include-Resource>
+ <Bundle-SymbolicName>
+ ${project.groupId}.${project.artifactId}
+ </Bundle-SymbolicName>
+ <Import-Package>
+ *,org.glassfish.jersey.servlet
+ </Import-Package>
+ <Web-ContextPath>${web.context}</Web-ContextPath>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
diff --git a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/web/OpenstackNodeWebApplication.java b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/web/OpenstackNodeWebApplication.java
new file mode 100644
index 0000000..88e9b19
--- /dev/null
+++ b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/web/OpenstackNodeWebApplication.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openstacknode.web;
+
+import org.onlab.rest.AbstractWebApplication;
+
+import java.util.Set;
+
+/**
+ * Openstack node REST APIs web application.
+ */
+public class OpenstackNodeWebApplication extends AbstractWebApplication {
+ @Override
+ public Set<Class<?>> getClasses() {
+ return getClasses(OpenstackNodeWebResource.class);
+ }
+}
diff --git a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/web/OpenstackNodeWebResource.java b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/web/OpenstackNodeWebResource.java
index e960d4b..e0f6e53 100644
--- a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/web/OpenstackNodeWebResource.java
+++ b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/web/OpenstackNodeWebResource.java
@@ -19,7 +19,6 @@
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.Sets;
-import org.onlab.osgi.DefaultServiceDirectory;
import org.onosproject.openstacknode.api.OpenstackNode;
import org.onosproject.openstacknode.api.OpenstackNodeAdminService;
import org.onosproject.openstacknode.api.OpenstackNodeService;
@@ -60,9 +59,9 @@
private static final String DELETE = "DELETE";
private final OpenstackNodeAdminService osNodeAdminService =
- DefaultServiceDirectory.getService(OpenstackNodeAdminService.class);
+ get(OpenstackNodeAdminService.class);
private final OpenstackNodeService osNodeService =
- DefaultServiceDirectory.getService(OpenstackNodeService.class);
+ get(OpenstackNodeService.class);
@Context
private UriInfo uriInfo;
diff --git a/apps/openstacknode/app/src/main/webapp/WEB-INF/web.xml b/apps/openstacknode/app/src/main/webapp/WEB-INF/web.xml
index 689c8ec..e1f7ceb 100644
--- a/apps/openstacknode/app/src/main/webapp/WEB-INF/web.xml
+++ b/apps/openstacknode/app/src/main/webapp/WEB-INF/web.xml
@@ -14,20 +14,38 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="ONOS" version="2.5">
<display-name>Openstack Node REST API v1.0</display-name>
+ <security-constraint>
+ <web-resource-collection>
+ <web-resource-name>Secured</web-resource-name>
+ <url-pattern>/*</url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name>admin</role-name>
+ </auth-constraint>
+ </security-constraint>
+
+ <security-role>
+ <role-name>admin</role-name>
+ </security-role>
+
+ <login-config>
+ <auth-method>BASIC</auth-method>
+ <realm-name>karaf</realm-name>
+ </login-config>
+
<servlet>
<servlet-name>JAX-RS Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
- <param-name>jersey.config.server.provider.classnames</param-name>
- <param-value>
- org.onosproject.openstacknode.web.OpenstackNodeWebResource
- </param-value>
+ <param-name>javax.ws.rs.Application</param-name>
+ <param-value>org.onosproject.openstacknode.web.OpenstackNodeWebApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
diff --git a/apps/openstacknode/app/src/test/java/org/onosproject/openstacknode/web/OpenstackNodeWebResourceTest.java b/apps/openstacknode/app/src/test/java/org/onosproject/openstacknode/web/OpenstackNodeWebResourceTest.java
new file mode 100644
index 0000000..ed8cd9a
--- /dev/null
+++ b/apps/openstacknode/app/src/test/java/org/onosproject/openstacknode/web/OpenstackNodeWebResourceTest.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openstacknode.web;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onlab.packet.IpAddress;
+import org.onosproject.codec.CodecService;
+import org.onosproject.codec.impl.CodecManager;
+import org.onosproject.net.DeviceId;
+import org.onosproject.openstacknode.api.NodeState;
+import org.onosproject.openstacknode.api.OpenstackNode;
+import org.onosproject.openstacknode.api.OpenstackNodeAdminService;
+import org.onosproject.openstacknode.api.OpenstackNodeService;
+import org.onosproject.openstacknode.codec.OpenstackNodeCodec;
+import org.onosproject.openstacknode.impl.DefaultOpenstackNode;
+import org.onosproject.rest.resources.ResourceTest;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.InputStream;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.anyString;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Unit test for Openstack node REST API.
+ */
+public class OpenstackNodeWebResourceTest extends ResourceTest {
+
+ final OpenstackNodeService mockOpenstackNodeService =
+ createMock(OpenstackNodeService.class);
+ final OpenstackNodeAdminService mockOpenstackNodeAdminService =
+ createMock(OpenstackNodeAdminService.class);
+ private static final String PATH = "configure";
+
+ /**
+ * Constructs an openstack node resource test instance.
+ */
+ public OpenstackNodeWebResourceTest() {
+ super(ResourceConfig.forApplicationClass(OpenstackNodeWebApplication.class));
+ }
+
+ private OpenstackNode openstackNode;
+
+ /**
+ * Sets up the global values for all the tests.
+ */
+ @Before
+ public void setUpTest() {
+ final CodecManager codecService = new CodecManager();
+ codecService.activate();
+ codecService.registerCodec(OpenstackNode.class, new OpenstackNodeCodec());
+ ServiceDirectory testDirectory =
+ new TestServiceDirectory()
+ .add(OpenstackNodeService.class, mockOpenstackNodeService)
+ .add(OpenstackNodeAdminService.class, mockOpenstackNodeAdminService)
+ .add(CodecService.class, codecService);
+ setServiceDirectory(testDirectory);
+
+ openstackNode = DefaultOpenstackNode.builder()
+ .hostname("compute-node")
+ .type(OpenstackNode.NodeType.COMPUTE)
+ .dataIp(IpAddress.valueOf("10.134.34.222"))
+ .managementIp(IpAddress.valueOf("10.134.231.30"))
+ .intgBridge(DeviceId.deviceId("of:00000000000000a1"))
+ .uplinkPort("eth2")
+ .state(NodeState.INIT)
+ .build();
+ }
+
+ /**
+ * Tests the results of the REST API POST with creating new nodes operation.
+ */
+ @Test
+ public void testCreateNodesWithCreateOperation() {
+ expect(mockOpenstackNodeService.node(anyString())).andReturn(null).once();
+ replay(mockOpenstackNodeService);
+
+ mockOpenstackNodeAdminService.createNode(anyObject());
+ replay(mockOpenstackNodeAdminService);
+
+ final WebTarget wt = target();
+ InputStream jsonStream = OpenstackNodeWebResourceTest.class
+ .getResourceAsStream("openstack-node-gateway-config.json");
+ Response response = wt.path(PATH).request(MediaType.APPLICATION_JSON_TYPE)
+ .post(Entity.json(jsonStream));
+ final int status = response.getStatus();
+
+ assertThat(status, is(201));
+
+ verify(mockOpenstackNodeService);
+ verify(mockOpenstackNodeAdminService);
+ }
+
+ /**
+ * Tests the results of the REST API POST without creating new nodes operation.
+ */
+ @Test
+ public void testCreateNodesWithoutCreateOperation() {
+ expect(mockOpenstackNodeService.node(anyString())).andReturn(openstackNode).once();
+ replay(mockOpenstackNodeService);
+
+ final WebTarget wt = target();
+ InputStream jsonStream = OpenstackNodeWebResourceTest.class
+ .getResourceAsStream("openstack-node-gateway-config.json");
+ Response response = wt.path(PATH).request(MediaType.APPLICATION_JSON_TYPE)
+ .post(Entity.json(jsonStream));
+ final int status = response.getStatus();
+
+ assertThat(status, is(201));
+
+ verify(mockOpenstackNodeService);
+ }
+
+ /**
+ * Tests the results of the REST API PUT with modifying the nodes.
+ */
+ @Test
+ public void testUpdateNodesWithoutModifyOperation() {
+ expect(mockOpenstackNodeService.node(anyString())).andReturn(openstackNode).once();
+ replay(mockOpenstackNodeService);
+
+ mockOpenstackNodeAdminService.updateNode(anyObject());
+ replay(mockOpenstackNodeAdminService);
+
+ final WebTarget wt = target();
+ InputStream jsonStream = OpenstackNodeWebResourceTest.class
+ .getResourceAsStream("openstack-node-gateway-config.json");
+ Response response = wt.path(PATH).request(MediaType.APPLICATION_JSON_TYPE)
+ .put(Entity.json(jsonStream));
+ final int status = response.getStatus();
+
+ assertThat(status, is(200));
+
+ verify(mockOpenstackNodeService);
+ verify(mockOpenstackNodeAdminService);
+ }
+
+ /**
+ * Tests the results of the REST API PUT without modifying the nodes.
+ */
+ @Test
+ public void testUpdateNodesWithModifyOperation() {
+ expect(mockOpenstackNodeService.node(anyString())).andReturn(null).once();
+ replay(mockOpenstackNodeService);
+
+ final WebTarget wt = target();
+ InputStream jsonStream = OpenstackNodeWebResourceTest.class
+ .getResourceAsStream("openstack-node-gateway-config.json");
+ Response response = wt.path(PATH).request(MediaType.APPLICATION_JSON_TYPE)
+ .put(Entity.json(jsonStream));
+ final int status = response.getStatus();
+
+ assertThat(status, is(304));
+
+ verify(mockOpenstackNodeService);
+ }
+}
diff --git a/apps/openstacknode/app/src/test/resources/org/onosproject/openstacknode/web/openstack-node-gateway-config.json b/apps/openstacknode/app/src/test/resources/org/onosproject/openstacknode/web/openstack-node-gateway-config.json
new file mode 100644
index 0000000..af4537f
--- /dev/null
+++ b/apps/openstacknode/app/src/test/resources/org/onosproject/openstacknode/web/openstack-node-gateway-config.json
@@ -0,0 +1,14 @@
+{
+ "nodes" : [
+ {
+ "hostname" : "gateway-node",
+ "type" : "GATEWAY",
+ "managementIp" : "10.134.231.32",
+ "dataIp" : "10.134.34.224",
+ "integrationBridge" : "of:00000000000000a2",
+ "routerBridge" : "of:00000000000000b1",
+ "uplinkPort" : "eth2",
+ "routerController" : "172.17.0.2"
+ }
+ ]
+}
\ No newline at end of file