Add REST API to CORD fabric app.
Change-Id: I6d22302bdbbcd2c75f9358196ca505fba500b348
diff --git a/apps/cordfabric/pom.xml b/apps/cordfabric/pom.xml
index 008702a..8087f34 100644
--- a/apps/cordfabric/pom.xml
+++ b/apps/cordfabric/pom.xml
@@ -32,6 +32,7 @@
<properties>
<onos.app.name>org.onosproject.cordfabric</onos.app.name>
+ <web.context>/onos/cordfabric</web.context>
</properties>
<dependencies>
@@ -45,5 +46,80 @@
<groupId>org.apache.karaf.shell</groupId>
<artifactId>org.apache.karaf.shell.console</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-rest</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onlab-rest</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>jsr311-api</artifactId>
+ <version>1.1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.jersey</groupId>
+ <artifactId>jersey-servlet</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ </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>
+ <Bundle-SymbolicName>
+ ${project.groupId}.${project.artifactId}
+ </Bundle-SymbolicName>
+ <Import-Package>
+ org.slf4j,
+ org.osgi.framework,
+ javax.ws.rs,
+ javax.ws.rs.core,
+ com.sun.jersey.api.core,
+ com.sun.jersey.spi.container.servlet,
+ com.sun.jersey.server.impl.container.servlet,
+ com.fasterxml.jackson.databind,
+ com.fasterxml.jackson.databind.node,
+ org.apache.karaf.shell.commands,
+ org.apache.commons.lang.math.*,
+ com.google.common.*,
+ org.onlab.packet.*,
+ org.onlab.rest.*,
+ org.onosproject.*,
+ org.onlab.util.*,
+ org.jboss.netty.util.*
+ </Import-Package>
+ <Web-ContextPath>${web.context}</Web-ContextPath>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
diff --git a/apps/cordfabric/src/main/java/org/onosproject/cordfabric/CordFabricManager.java b/apps/cordfabric/src/main/java/org/onosproject/cordfabric/CordFabricManager.java
index a6f9d43..ca8501a 100644
--- a/apps/cordfabric/src/main/java/org/onosproject/cordfabric/CordFabricManager.java
+++ b/apps/cordfabric/src/main/java/org/onosproject/cordfabric/CordFabricManager.java
@@ -18,7 +18,6 @@
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
-import com.google.common.collect.Multimaps;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -44,6 +43,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@@ -85,18 +85,17 @@
}
@Override
- public void addVlan(VlanId vlanId, List<ConnectPoint> ports) {
- checkNotNull(vlanId);
- checkNotNull(ports);
- checkArgument(ports.size() > 1);
- verifyPorts(ports);
+ public void addVlan(FabricVlan vlan) {
+ checkNotNull(vlan);
+ checkArgument(vlan.ports().size() > 1);
+ verifyPorts(vlan.ports());
- removeVlan(vlanId);
+ removeVlan(vlan.vlan());
- ports.forEach(cp -> {
- if (vlans.put(vlanId, cp)) {
- addForwarding(vlanId, cp.deviceId(), cp.port(),
- ports.stream()
+ vlan.ports().forEach(cp -> {
+ if (vlans.put(vlan.vlan(), cp)) {
+ addForwarding(vlan.vlan(), cp.deviceId(), cp.port(),
+ vlan.ports().stream()
.filter(p -> p != cp)
.map(ConnectPoint::port)
.collect(Collectors.toList()));
@@ -111,8 +110,11 @@
}
@Override
- public Multimap<VlanId, ConnectPoint> getVlans() {
- return Multimaps.unmodifiableMultimap(vlans);
+ public List<FabricVlan> getVlans() {
+ List<FabricVlan> fVlans = new ArrayList<>();
+ vlans.keySet().forEach(vlan -> fVlans.add(
+ new FabricVlan(vlan, vlans.get(vlan))));
+ return fVlans;
}
private static void verifyPorts(List<ConnectPoint> ports) {
diff --git a/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricService.java b/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricService.java
index 60ece29..5c2ce25 100644
--- a/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricService.java
+++ b/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricService.java
@@ -16,9 +16,7 @@
package org.onosproject.cordfabric;
-import com.google.common.collect.Multimap;
import org.onlab.packet.VlanId;
-import org.onosproject.net.ConnectPoint;
import java.util.List;
@@ -31,10 +29,9 @@
* Remaps a vlan to the specified ports. The specified ports will be the
* only ports in this vlan once the operation completes.
*
- * @param vlanId vlan ID to add/modify
- * @param ports list of ports to add to the vlan
+ * @param vlan vlan object to add
*/
- void addVlan(VlanId vlanId, List<ConnectPoint> ports);
+ void addVlan(FabricVlan vlan);
/**
* Removes a vlan from all ports in the fabric.
@@ -49,5 +46,5 @@
*
* @return mapping of vlan to port
*/
- Multimap<VlanId, ConnectPoint> getVlans();
+ List<FabricVlan> getVlans();
}
diff --git a/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricVlan.java b/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricVlan.java
new file mode 100644
index 0000000..d145928
--- /dev/null
+++ b/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricVlan.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.cordfabric;
+
+import com.google.common.collect.ImmutableList;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+
+import java.util.Collection;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Vlan which spans multiple fabric ports.
+ */
+public class FabricVlan {
+
+ private final VlanId vlan;
+
+ private final List<ConnectPoint> ports;
+
+ public FabricVlan(VlanId vlan, Collection<ConnectPoint> ports) {
+ checkNotNull(vlan);
+ checkNotNull(ports);
+ this.vlan = vlan;
+ this.ports = ImmutableList.copyOf(ports);
+ }
+
+ public VlanId vlan() {
+ return vlan;
+ }
+
+ public List<ConnectPoint> ports() {
+ return ports;
+ }
+}
diff --git a/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricVlanCodec.java b/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricVlanCodec.java
new file mode 100644
index 0000000..0a097b2
--- /dev/null
+++ b/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricVlanCodec.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.cordfabric;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onlab.packet.VlanId;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.net.ConnectPoint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Codec for encoding/decoding a FabricVlan object to/from JSON.
+ */
+public final class FabricVlanCodec extends JsonCodec<FabricVlan> {
+
+ // JSON field names
+ private static final String VLAN = "vlan";
+ private static final String PORTS = "ports";
+
+ @Override
+ public ObjectNode encode(FabricVlan vlan, CodecContext context) {
+ checkNotNull(vlan, "Vlan cannot be null");
+ final ObjectNode result = context.mapper().createObjectNode()
+ .put(VLAN, vlan.vlan().toShort());
+
+ final ArrayNode jsonPorts = result.putArray(PORTS);
+
+ vlan.ports().forEach(cp -> jsonPorts.add(context.codec(ConnectPoint.class).encode(cp, context)));
+
+ return result;
+ }
+
+ @Override
+ public FabricVlan decode(ObjectNode json, CodecContext context) {
+ short vlan = json.path(VLAN).shortValue();
+ List<ConnectPoint> ports = new ArrayList<>();
+
+ ArrayNode portArray = (ArrayNode) json.path(PORTS);
+ for (JsonNode o : portArray) {
+ ports.add(context.codec(ConnectPoint.class).decode((ObjectNode) o, context));
+ }
+
+ return new FabricVlan(VlanId.vlanId(vlan), ports);
+ }
+}
diff --git a/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricWebResource.java b/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricWebResource.java
new file mode 100644
index 0000000..5878e6b
--- /dev/null
+++ b/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricWebResource.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.cordfabric;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onlab.packet.VlanId;
+import org.onosproject.rest.AbstractWebResource;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+/**
+ * Web resource for interacting with the fabric.
+ */
+@Path("vlans")
+public class FabricWebResource extends AbstractWebResource {
+
+ private static final FabricVlanCodec VLAN_CODEC = new FabricVlanCodec();
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response getVlans() {
+ FabricService fabricService = get(FabricService.class);
+ List<FabricVlan> vlans = fabricService.getVlans();
+ ObjectNode result = new ObjectMapper().createObjectNode();
+ result.set("vlans", new FabricVlanCodec().encode(vlans, this));
+
+ return ok(result.toString()).build();
+ }
+
+ @POST
+ @Path("add")
+ @Consumes(MediaType.APPLICATION_JSON)
+ public Response addVlan(InputStream input) throws IOException {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode vlanJson = (ObjectNode) mapper.readTree(input);
+ FabricService fabricService = get(FabricService.class);
+
+ fabricService.addVlan(VLAN_CODEC.decode(vlanJson, this));
+
+ return Response.ok().build();
+ }
+
+ @DELETE
+ @Path("{vlan}")
+ public Response deleteVlan(@PathParam("vlan") String vlan) throws IOException {
+ VlanId vlanId = VlanId.vlanId(Short.parseShort(vlan));
+
+ FabricService fabricService = get(FabricService.class);
+
+ fabricService.removeVlan(vlanId);
+
+ return Response.ok().build();
+ }
+}
diff --git a/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/FabricAddCommand.java b/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/FabricAddCommand.java
index cedde04..cfa26be 100644
--- a/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/FabricAddCommand.java
+++ b/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/FabricAddCommand.java
@@ -21,6 +21,7 @@
import org.onlab.packet.VlanId;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.cordfabric.FabricService;
+import org.onosproject.cordfabric.FabricVlan;
import org.onosproject.net.ConnectPoint;
import java.util.ArrayList;
@@ -58,6 +59,6 @@
ports.add(ConnectPoint.deviceConnectPoint(portString));
}
- service.addVlan(vlan, ports);
+ service.addVlan(new FabricVlan(vlan, ports));
}
}
diff --git a/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/FabricShowCommand.java b/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/FabricShowCommand.java
index 1db4222..f632a88 100644
--- a/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/FabricShowCommand.java
+++ b/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/FabricShowCommand.java
@@ -16,12 +16,12 @@
package org.onosproject.cordfabric.cli;
-import com.google.common.collect.Multimap;
import org.apache.karaf.shell.commands.Command;
-import org.onlab.packet.VlanId;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.cordfabric.FabricService;
-import org.onosproject.net.ConnectPoint;
+import org.onosproject.cordfabric.FabricVlan;
+
+import java.util.List;
/**
* Shows the vlans in the fabric.
@@ -37,11 +37,11 @@
protected void execute() {
FabricService service = AbstractShellCommand.get(FabricService.class);
- Multimap<VlanId, ConnectPoint> vlans = service.getVlans();
+ List<FabricVlan> vlans = service.getVlans();
- vlans.keySet().forEach(vlanId -> {
- print(VLAN_HEADER_LINE_FORMAT, vlanId);
- vlans.get(vlanId).forEach(cp -> print(PORT_LINE_FORMAT, cp));
+ vlans.forEach(fabricVlan -> {
+ print(VLAN_HEADER_LINE_FORMAT, fabricVlan.vlan());
+ fabricVlan.ports().forEach(cp -> print(PORT_LINE_FORMAT, cp));
});
}
}
diff --git a/apps/cordfabric/src/main/webapp/WEB-INF/web.xml b/apps/cordfabric/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..06d3a35
--- /dev/null
+++ b/apps/cordfabric/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright 2015 Open Networking Laboratory
+ ~
+ ~ 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.
+ -->
+<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>CORD Fabric REST API v1.0</display-name>
+
+ <servlet>
+ <servlet-name>JAX-RS Service</servlet-name>
+ <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
+ <init-param>
+ <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
+ <param-value>com.sun.jersey.api.core.ClassNamesResourceConfig</param-value>
+ </init-param>
+ <init-param>
+ <param-name>com.sun.jersey.config.property.classnames</param-name>
+ <param-value>
+ org.onosproject.cordfabric.FabricWebResource
+ </param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>JAX-RS Service</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+
+</web-app>
diff --git a/apps/virtualbng/src/main/webapp/WEB-INF/web.xml b/apps/virtualbng/src/main/webapp/WEB-INF/web.xml
index 34c9a11..e8e0071 100644
--- a/apps/virtualbng/src/main/webapp/WEB-INF/web.xml
+++ b/apps/virtualbng/src/main/webapp/WEB-INF/web.xml
@@ -18,7 +18,7 @@
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>ONOS Virual BNG APP REST API</display-name>
+ <display-name>ONOS Virtual BNG APP REST API</display-name>
<servlet>
<servlet-name>JAX-RS Service</servlet-name>