Jonathan Hart

Add REST API to CORD fabric app.

Change-Id: I6d22302bdbbcd2c75f9358196ca505fba500b348
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
32 32
33 <properties> 33 <properties>
34 <onos.app.name>org.onosproject.cordfabric</onos.app.name> 34 <onos.app.name>org.onosproject.cordfabric</onos.app.name>
35 + <web.context>/onos/cordfabric</web.context>
35 </properties> 36 </properties>
36 37
37 <dependencies> 38 <dependencies>
...@@ -45,5 +46,80 @@ ...@@ -45,5 +46,80 @@
45 <groupId>org.apache.karaf.shell</groupId> 46 <groupId>org.apache.karaf.shell</groupId>
46 <artifactId>org.apache.karaf.shell.console</artifactId> 47 <artifactId>org.apache.karaf.shell.console</artifactId>
47 </dependency> 48 </dependency>
49 + <dependency>
50 + <groupId>org.onosproject</groupId>
51 + <artifactId>onos-rest</artifactId>
52 + <version>${project.version}</version>
53 + </dependency>
54 + <dependency>
55 + <groupId>org.onosproject</groupId>
56 + <artifactId>onlab-rest</artifactId>
57 + <version>${project.version}</version>
58 + </dependency>
59 + <dependency>
60 + <groupId>javax.ws.rs</groupId>
61 + <artifactId>jsr311-api</artifactId>
62 + <version>1.1.1</version>
63 + </dependency>
64 + <dependency>
65 + <groupId>com.sun.jersey</groupId>
66 + <artifactId>jersey-servlet</artifactId>
67 + </dependency>
68 + <dependency>
69 + <groupId>com.fasterxml.jackson.core</groupId>
70 + <artifactId>jackson-databind</artifactId>
71 + </dependency>
72 +
73 + <dependency>
74 + <groupId>com.fasterxml.jackson.core</groupId>
75 + <artifactId>jackson-annotations</artifactId>
76 + </dependency>
77 +
78 + <dependency>
79 + <groupId>org.osgi</groupId>
80 + <artifactId>org.osgi.compendium</artifactId>
81 + </dependency>
82 + <dependency>
83 + <groupId>org.osgi</groupId>
84 + <artifactId>org.osgi.core</artifactId>
85 + </dependency>
48 </dependencies> 86 </dependencies>
87 +
88 + <build>
89 + <plugins>
90 + <plugin>
91 + <groupId>org.apache.felix</groupId>
92 + <artifactId>maven-bundle-plugin</artifactId>
93 + <extensions>true</extensions>
94 + <configuration>
95 + <instructions>
96 + <_wab>src/main/webapp/</_wab>
97 + <Bundle-SymbolicName>
98 + ${project.groupId}.${project.artifactId}
99 + </Bundle-SymbolicName>
100 + <Import-Package>
101 + org.slf4j,
102 + org.osgi.framework,
103 + javax.ws.rs,
104 + javax.ws.rs.core,
105 + com.sun.jersey.api.core,
106 + com.sun.jersey.spi.container.servlet,
107 + com.sun.jersey.server.impl.container.servlet,
108 + com.fasterxml.jackson.databind,
109 + com.fasterxml.jackson.databind.node,
110 + org.apache.karaf.shell.commands,
111 + org.apache.commons.lang.math.*,
112 + com.google.common.*,
113 + org.onlab.packet.*,
114 + org.onlab.rest.*,
115 + org.onosproject.*,
116 + org.onlab.util.*,
117 + org.jboss.netty.util.*
118 + </Import-Package>
119 + <Web-ContextPath>${web.context}</Web-ContextPath>
120 + </instructions>
121 + </configuration>
122 + </plugin>
123 + </plugins>
124 + </build>
49 </project> 125 </project>
......
...@@ -18,7 +18,6 @@ package org.onosproject.cordfabric; ...@@ -18,7 +18,6 @@ package org.onosproject.cordfabric;
18 18
19 import com.google.common.collect.HashMultimap; 19 import com.google.common.collect.HashMultimap;
20 import com.google.common.collect.Multimap; 20 import com.google.common.collect.Multimap;
21 -import com.google.common.collect.Multimaps;
22 import org.apache.felix.scr.annotations.Activate; 21 import org.apache.felix.scr.annotations.Activate;
23 import org.apache.felix.scr.annotations.Component; 22 import org.apache.felix.scr.annotations.Component;
24 import org.apache.felix.scr.annotations.Deactivate; 23 import org.apache.felix.scr.annotations.Deactivate;
...@@ -44,6 +43,7 @@ import org.onosproject.net.flowobjective.ObjectiveError; ...@@ -44,6 +43,7 @@ import org.onosproject.net.flowobjective.ObjectiveError;
44 import org.slf4j.Logger; 43 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory; 44 import org.slf4j.LoggerFactory;
46 45
46 +import java.util.ArrayList;
47 import java.util.List; 47 import java.util.List;
48 import java.util.stream.Collectors; 48 import java.util.stream.Collectors;
49 49
...@@ -85,18 +85,17 @@ public class CordFabricManager implements FabricService { ...@@ -85,18 +85,17 @@ public class CordFabricManager implements FabricService {
85 } 85 }
86 86
87 @Override 87 @Override
88 - public void addVlan(VlanId vlanId, List<ConnectPoint> ports) { 88 + public void addVlan(FabricVlan vlan) {
89 - checkNotNull(vlanId); 89 + checkNotNull(vlan);
90 - checkNotNull(ports); 90 + checkArgument(vlan.ports().size() > 1);
91 - checkArgument(ports.size() > 1); 91 + verifyPorts(vlan.ports());
92 - verifyPorts(ports); 92 +
93 - 93 + removeVlan(vlan.vlan());
94 - removeVlan(vlanId); 94 +
95 - 95 + vlan.ports().forEach(cp -> {
96 - ports.forEach(cp -> { 96 + if (vlans.put(vlan.vlan(), cp)) {
97 - if (vlans.put(vlanId, cp)) { 97 + addForwarding(vlan.vlan(), cp.deviceId(), cp.port(),
98 - addForwarding(vlanId, cp.deviceId(), cp.port(), 98 + vlan.ports().stream()
99 - ports.stream()
100 .filter(p -> p != cp) 99 .filter(p -> p != cp)
101 .map(ConnectPoint::port) 100 .map(ConnectPoint::port)
102 .collect(Collectors.toList())); 101 .collect(Collectors.toList()));
...@@ -111,8 +110,11 @@ public class CordFabricManager implements FabricService { ...@@ -111,8 +110,11 @@ public class CordFabricManager implements FabricService {
111 } 110 }
112 111
113 @Override 112 @Override
114 - public Multimap<VlanId, ConnectPoint> getVlans() { 113 + public List<FabricVlan> getVlans() {
115 - return Multimaps.unmodifiableMultimap(vlans); 114 + List<FabricVlan> fVlans = new ArrayList<>();
115 + vlans.keySet().forEach(vlan -> fVlans.add(
116 + new FabricVlan(vlan, vlans.get(vlan))));
117 + return fVlans;
116 } 118 }
117 119
118 private static void verifyPorts(List<ConnectPoint> ports) { 120 private static void verifyPorts(List<ConnectPoint> ports) {
......
...@@ -16,9 +16,7 @@ ...@@ -16,9 +16,7 @@
16 16
17 package org.onosproject.cordfabric; 17 package org.onosproject.cordfabric;
18 18
19 -import com.google.common.collect.Multimap;
20 import org.onlab.packet.VlanId; 19 import org.onlab.packet.VlanId;
21 -import org.onosproject.net.ConnectPoint;
22 20
23 import java.util.List; 21 import java.util.List;
24 22
...@@ -31,10 +29,9 @@ public interface FabricService { ...@@ -31,10 +29,9 @@ public interface FabricService {
31 * Remaps a vlan to the specified ports. The specified ports will be the 29 * Remaps a vlan to the specified ports. The specified ports will be the
32 * only ports in this vlan once the operation completes. 30 * only ports in this vlan once the operation completes.
33 * 31 *
34 - * @param vlanId vlan ID to add/modify 32 + * @param vlan vlan object to add
35 - * @param ports list of ports to add to the vlan
36 */ 33 */
37 - void addVlan(VlanId vlanId, List<ConnectPoint> ports); 34 + void addVlan(FabricVlan vlan);
38 35
39 /** 36 /**
40 * Removes a vlan from all ports in the fabric. 37 * Removes a vlan from all ports in the fabric.
...@@ -49,5 +46,5 @@ public interface FabricService { ...@@ -49,5 +46,5 @@ public interface FabricService {
49 * 46 *
50 * @return mapping of vlan to port 47 * @return mapping of vlan to port
51 */ 48 */
52 - Multimap<VlanId, ConnectPoint> getVlans(); 49 + List<FabricVlan> getVlans();
53 } 50 }
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.cordfabric;
18 +
19 +import com.google.common.collect.ImmutableList;
20 +import org.onlab.packet.VlanId;
21 +import org.onosproject.net.ConnectPoint;
22 +
23 +import java.util.Collection;
24 +import java.util.List;
25 +
26 +import static com.google.common.base.Preconditions.checkNotNull;
27 +
28 +/**
29 + * Vlan which spans multiple fabric ports.
30 + */
31 +public class FabricVlan {
32 +
33 + private final VlanId vlan;
34 +
35 + private final List<ConnectPoint> ports;
36 +
37 + public FabricVlan(VlanId vlan, Collection<ConnectPoint> ports) {
38 + checkNotNull(vlan);
39 + checkNotNull(ports);
40 + this.vlan = vlan;
41 + this.ports = ImmutableList.copyOf(ports);
42 + }
43 +
44 + public VlanId vlan() {
45 + return vlan;
46 + }
47 +
48 + public List<ConnectPoint> ports() {
49 + return ports;
50 + }
51 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.cordfabric;
18 +
19 +import com.fasterxml.jackson.databind.JsonNode;
20 +import com.fasterxml.jackson.databind.node.ArrayNode;
21 +import com.fasterxml.jackson.databind.node.ObjectNode;
22 +import org.onlab.packet.VlanId;
23 +import org.onosproject.codec.CodecContext;
24 +import org.onosproject.codec.JsonCodec;
25 +import org.onosproject.net.ConnectPoint;
26 +
27 +import java.util.ArrayList;
28 +import java.util.List;
29 +
30 +import static com.google.common.base.Preconditions.checkNotNull;
31 +
32 +/**
33 + * Codec for encoding/decoding a FabricVlan object to/from JSON.
34 + */
35 +public final class FabricVlanCodec extends JsonCodec<FabricVlan> {
36 +
37 + // JSON field names
38 + private static final String VLAN = "vlan";
39 + private static final String PORTS = "ports";
40 +
41 + @Override
42 + public ObjectNode encode(FabricVlan vlan, CodecContext context) {
43 + checkNotNull(vlan, "Vlan cannot be null");
44 + final ObjectNode result = context.mapper().createObjectNode()
45 + .put(VLAN, vlan.vlan().toShort());
46 +
47 + final ArrayNode jsonPorts = result.putArray(PORTS);
48 +
49 + vlan.ports().forEach(cp -> jsonPorts.add(context.codec(ConnectPoint.class).encode(cp, context)));
50 +
51 + return result;
52 + }
53 +
54 + @Override
55 + public FabricVlan decode(ObjectNode json, CodecContext context) {
56 + short vlan = json.path(VLAN).shortValue();
57 + List<ConnectPoint> ports = new ArrayList<>();
58 +
59 + ArrayNode portArray = (ArrayNode) json.path(PORTS);
60 + for (JsonNode o : portArray) {
61 + ports.add(context.codec(ConnectPoint.class).decode((ObjectNode) o, context));
62 + }
63 +
64 + return new FabricVlan(VlanId.vlanId(vlan), ports);
65 + }
66 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.cordfabric;
18 +
19 +import com.fasterxml.jackson.databind.ObjectMapper;
20 +import com.fasterxml.jackson.databind.node.ObjectNode;
21 +import org.onlab.packet.VlanId;
22 +import org.onosproject.rest.AbstractWebResource;
23 +
24 +import javax.ws.rs.Consumes;
25 +import javax.ws.rs.DELETE;
26 +import javax.ws.rs.GET;
27 +import javax.ws.rs.POST;
28 +import javax.ws.rs.Path;
29 +import javax.ws.rs.PathParam;
30 +import javax.ws.rs.Produces;
31 +import javax.ws.rs.core.MediaType;
32 +import javax.ws.rs.core.Response;
33 +import java.io.IOException;
34 +import java.io.InputStream;
35 +import java.util.List;
36 +
37 +/**
38 + * Web resource for interacting with the fabric.
39 + */
40 +@Path("vlans")
41 +public class FabricWebResource extends AbstractWebResource {
42 +
43 + private static final FabricVlanCodec VLAN_CODEC = new FabricVlanCodec();
44 +
45 + @GET
46 + @Produces(MediaType.APPLICATION_JSON)
47 + public Response getVlans() {
48 + FabricService fabricService = get(FabricService.class);
49 + List<FabricVlan> vlans = fabricService.getVlans();
50 + ObjectNode result = new ObjectMapper().createObjectNode();
51 + result.set("vlans", new FabricVlanCodec().encode(vlans, this));
52 +
53 + return ok(result.toString()).build();
54 + }
55 +
56 + @POST
57 + @Path("add")
58 + @Consumes(MediaType.APPLICATION_JSON)
59 + public Response addVlan(InputStream input) throws IOException {
60 + ObjectMapper mapper = new ObjectMapper();
61 + ObjectNode vlanJson = (ObjectNode) mapper.readTree(input);
62 + FabricService fabricService = get(FabricService.class);
63 +
64 + fabricService.addVlan(VLAN_CODEC.decode(vlanJson, this));
65 +
66 + return Response.ok().build();
67 + }
68 +
69 + @DELETE
70 + @Path("{vlan}")
71 + public Response deleteVlan(@PathParam("vlan") String vlan) throws IOException {
72 + VlanId vlanId = VlanId.vlanId(Short.parseShort(vlan));
73 +
74 + FabricService fabricService = get(FabricService.class);
75 +
76 + fabricService.removeVlan(vlanId);
77 +
78 + return Response.ok().build();
79 + }
80 +}
...@@ -21,6 +21,7 @@ import org.apache.karaf.shell.commands.Command; ...@@ -21,6 +21,7 @@ import org.apache.karaf.shell.commands.Command;
21 import org.onlab.packet.VlanId; 21 import org.onlab.packet.VlanId;
22 import org.onosproject.cli.AbstractShellCommand; 22 import org.onosproject.cli.AbstractShellCommand;
23 import org.onosproject.cordfabric.FabricService; 23 import org.onosproject.cordfabric.FabricService;
24 +import org.onosproject.cordfabric.FabricVlan;
24 import org.onosproject.net.ConnectPoint; 25 import org.onosproject.net.ConnectPoint;
25 26
26 import java.util.ArrayList; 27 import java.util.ArrayList;
...@@ -58,6 +59,6 @@ public class FabricAddCommand extends AbstractShellCommand { ...@@ -58,6 +59,6 @@ public class FabricAddCommand extends AbstractShellCommand {
58 ports.add(ConnectPoint.deviceConnectPoint(portString)); 59 ports.add(ConnectPoint.deviceConnectPoint(portString));
59 } 60 }
60 61
61 - service.addVlan(vlan, ports); 62 + service.addVlan(new FabricVlan(vlan, ports));
62 } 63 }
63 } 64 }
......
...@@ -16,12 +16,12 @@ ...@@ -16,12 +16,12 @@
16 16
17 package org.onosproject.cordfabric.cli; 17 package org.onosproject.cordfabric.cli;
18 18
19 -import com.google.common.collect.Multimap;
20 import org.apache.karaf.shell.commands.Command; 19 import org.apache.karaf.shell.commands.Command;
21 -import org.onlab.packet.VlanId;
22 import org.onosproject.cli.AbstractShellCommand; 20 import org.onosproject.cli.AbstractShellCommand;
23 import org.onosproject.cordfabric.FabricService; 21 import org.onosproject.cordfabric.FabricService;
24 -import org.onosproject.net.ConnectPoint; 22 +import org.onosproject.cordfabric.FabricVlan;
23 +
24 +import java.util.List;
25 25
26 /** 26 /**
27 * Shows the vlans in the fabric. 27 * Shows the vlans in the fabric.
...@@ -37,11 +37,11 @@ public class FabricShowCommand extends AbstractShellCommand { ...@@ -37,11 +37,11 @@ public class FabricShowCommand extends AbstractShellCommand {
37 protected void execute() { 37 protected void execute() {
38 FabricService service = AbstractShellCommand.get(FabricService.class); 38 FabricService service = AbstractShellCommand.get(FabricService.class);
39 39
40 - Multimap<VlanId, ConnectPoint> vlans = service.getVlans(); 40 + List<FabricVlan> vlans = service.getVlans();
41 41
42 - vlans.keySet().forEach(vlanId -> { 42 + vlans.forEach(fabricVlan -> {
43 - print(VLAN_HEADER_LINE_FORMAT, vlanId); 43 + print(VLAN_HEADER_LINE_FORMAT, fabricVlan.vlan());
44 - vlans.get(vlanId).forEach(cp -> print(PORT_LINE_FORMAT, cp)); 44 + fabricVlan.ports().forEach(cp -> print(PORT_LINE_FORMAT, cp));
45 }); 45 });
46 } 46 }
47 } 47 }
......
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<!--
3 + ~ Copyright 2015 Open Networking Laboratory
4 + ~
5 + ~ Licensed under the Apache License, Version 2.0 (the "License");
6 + ~ you may not use this file except in compliance with the License.
7 + ~ You may obtain a copy of the License at
8 + ~
9 + ~ http://www.apache.org/licenses/LICENSE-2.0
10 + ~
11 + ~ Unless required by applicable law or agreed to in writing, software
12 + ~ distributed under the License is distributed on an "AS IS" BASIS,
13 + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 + ~ See the License for the specific language governing permissions and
15 + ~ limitations under the License.
16 + -->
17 +<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
18 + xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
19 + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
20 + id="ONOS" version="2.5">
21 + <display-name>CORD Fabric REST API v1.0</display-name>
22 +
23 + <servlet>
24 + <servlet-name>JAX-RS Service</servlet-name>
25 + <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
26 + <init-param>
27 + <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
28 + <param-value>com.sun.jersey.api.core.ClassNamesResourceConfig</param-value>
29 + </init-param>
30 + <init-param>
31 + <param-name>com.sun.jersey.config.property.classnames</param-name>
32 + <param-value>
33 + org.onosproject.cordfabric.FabricWebResource
34 + </param-value>
35 + </init-param>
36 + <load-on-startup>1</load-on-startup>
37 + </servlet>
38 +
39 + <servlet-mapping>
40 + <servlet-name>JAX-RS Service</servlet-name>
41 + <url-pattern>/*</url-pattern>
42 + </servlet-mapping>
43 +
44 +</web-app>
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
18 xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 18 xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
19 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 19 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
20 id="ONOS" version="2.5"> 20 id="ONOS" version="2.5">
21 - <display-name>ONOS Virual BNG APP REST API</display-name> 21 + <display-name>ONOS Virtual BNG APP REST API</display-name>
22 22
23 <servlet> 23 <servlet>
24 <servlet-name>JAX-RS Service</servlet-name> 24 <servlet-name>JAX-RS Service</servlet-name>
......