From 13d05bc8458758ee39cb829098241e89616717ee Mon Sep 17 00:00:00 2001 From: Ashlee Young Date: Wed, 9 Sep 2015 22:15:21 -0700 Subject: ONOS checkin based on commit tag e796610b1f721d02f9b0e213cf6f7790c10ecd60 Change-Id: Ife8810491034fe7becdba75dda20de4267bd15cd --- framework/src/onos/apps/cordfabric/pom.xml | 135 +++++++ .../onosproject/cordfabric/CordFabricManager.java | 433 +++++++++++++++++++++ .../org/onosproject/cordfabric/FabricService.java | 50 +++ .../org/onosproject/cordfabric/FabricVlan.java | 57 +++ .../onosproject/cordfabric/FabricVlanCodec.java | 68 ++++ .../onosproject/cordfabric/FabricWebResource.java | 99 +++++ .../cordfabric/cli/FabricAddCommand.java | 64 +++ .../cordfabric/cli/FabricRemoveCommand.java | 44 +++ .../cordfabric/cli/FabricShowCommand.java | 47 +++ .../onosproject/cordfabric/cli/package-info.java | 20 + .../org/onosproject/cordfabric/package-info.java | 20 + .../resources/OSGI-INF/blueprint/shell-config.xml | 36 ++ .../cordfabric/src/main/webapp/WEB-INF/web.xml | 44 +++ 13 files changed, 1117 insertions(+) create mode 100644 framework/src/onos/apps/cordfabric/pom.xml create mode 100644 framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/CordFabricManager.java create mode 100644 framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricService.java create mode 100644 framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricVlan.java create mode 100644 framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricVlanCodec.java create mode 100644 framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricWebResource.java create mode 100644 framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/FabricAddCommand.java create mode 100644 framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/FabricRemoveCommand.java create mode 100644 framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/FabricShowCommand.java create mode 100644 framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/package-info.java create mode 100644 framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/package-info.java create mode 100644 framework/src/onos/apps/cordfabric/src/main/resources/OSGI-INF/blueprint/shell-config.xml create mode 100644 framework/src/onos/apps/cordfabric/src/main/webapp/WEB-INF/web.xml (limited to 'framework/src/onos/apps/cordfabric') diff --git a/framework/src/onos/apps/cordfabric/pom.xml b/framework/src/onos/apps/cordfabric/pom.xml new file mode 100644 index 00000000..f5388553 --- /dev/null +++ b/framework/src/onos/apps/cordfabric/pom.xml @@ -0,0 +1,135 @@ + + + + + onos-apps + org.onosproject + 1.3.0-SNAPSHOT + ../pom.xml + + 4.0.0 + + onos-app-cordfabric + + bundle + Simple fabric application for CORD + + + org.onosproject.cordfabric + /onos/cordfabric + 1.0.0 + ONOS CORD Fabric REST API + + APIs for interacting with the CORD Fabric application. + + org.onosproject.cordfabric + + + + + org.onosproject + onos-cli + ${project.version} + + + + org.apache.karaf.shell + org.apache.karaf.shell.console + + + org.onosproject + onos-rest + ${project.version} + + + org.onosproject + onlab-rest + ${project.version} + + + javax.ws.rs + jsr311-api + 1.1.1 + + + com.sun.jersey + jersey-servlet + + + com.fasterxml.jackson.core + jackson-databind + + + + com.fasterxml.jackson.core + jackson-annotations + + + + org.osgi + org.osgi.compendium + + + org.osgi + org.osgi.core + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + <_wab>src/main/webapp/ + + WEB-INF/classes/apidoc/swagger.json=target/swagger.json, + {maven-resources} + + + ${project.groupId}.${project.artifactId} + + + 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.* + + ${web.context} + + + + + + diff --git a/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/CordFabricManager.java b/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/CordFabricManager.java new file mode 100644 index 00000000..1523e9c2 --- /dev/null +++ b/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/CordFabricManager.java @@ -0,0 +1,433 @@ +/* + * 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.HashMultimap; +import com.google.common.collect.Multimap; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.onlab.packet.Ethernet; +import org.onlab.packet.IPv4; +import org.onlab.packet.MacAddress; +import org.onlab.packet.TpPort; +import org.onlab.packet.VlanId; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.PortNumber; +import org.onosproject.net.device.DeviceEvent; +import org.onosproject.net.device.DeviceListener; +import org.onosproject.net.device.DeviceService; +import org.onosproject.net.flow.DefaultTrafficSelector; +import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; +import org.onosproject.net.flowobjective.DefaultForwardingObjective; +import org.onosproject.net.flowobjective.FlowObjectiveService; +import org.onosproject.net.flowobjective.ForwardingObjective; +import org.onosproject.net.flowobjective.Objective; +import org.onosproject.net.flowobjective.ObjectiveContext; +import org.onosproject.net.flowobjective.ObjectiveError; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * CORD fabric application. + */ +@Service +@Component(immediate = true) +public class CordFabricManager implements FabricService { + + private final Logger log = getLogger(getClass()); + + private ApplicationId appId; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected FlowObjectiveService flowObjectiveService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DeviceService deviceService; + + private InternalDeviceListener deviceListener = new InternalDeviceListener(); + + private static final int PRIORITY = 50000; + private static final int TESTPRIO = 49999; + + private short radiusPort = 1812; + + private short ofPort = 6633; + + private DeviceId fabricDeviceId = DeviceId.deviceId("of:5e3e486e73000187"); + + private final Multimap vlans = HashMultimap.create(); + + //TODO make this configurable + private boolean testMode = true; + + + @Activate + public void activate() { + appId = coreService.registerApplication("org.onosproject.cordfabric"); + + deviceService.addListener(deviceListener); + + if (deviceService.isAvailable(fabricDeviceId)) { + setupDefaultFlows(); + } + + log.info("Started"); + } + + @Deactivate + public void deactivate() { + deviceService.removeListener(deviceListener); + + log.info("Stopped"); + } + + private void setupDefaultFlows() { + TrafficSelector ofInBandMatchUp = DefaultTrafficSelector.builder() + .matchEthType(Ethernet.TYPE_IPV4) + .matchIPProtocol(IPv4.PROTOCOL_TCP) + .matchTcpDst(TpPort.tpPort(ofPort)) + .matchInPort(PortNumber.portNumber(6)) + .build(); + + TrafficSelector ofInBandMatchDown = DefaultTrafficSelector.builder() + .matchEthType(Ethernet.TYPE_IPV4) + .matchIPProtocol(IPv4.PROTOCOL_TCP) + .matchTcpSrc(TpPort.tpPort(ofPort)) + .matchInPort(PortNumber.portNumber(1)) + .build(); + + TrafficSelector oltMgmtUp = DefaultTrafficSelector.builder() + .matchEthSrc(MacAddress.valueOf("00:0c:d5:00:01:01")) + .matchInPort(PortNumber.portNumber(2)) + .build(); + + TrafficSelector oltMgmtDown = DefaultTrafficSelector.builder() + .matchEthDst(MacAddress.valueOf("00:0c:d5:00:01:01")) + .matchInPort(PortNumber.portNumber(9)) + .build(); + + TrafficTreatment up = DefaultTrafficTreatment.builder() + .setOutput(PortNumber.portNumber(1)) + .build(); + + TrafficTreatment down = DefaultTrafficTreatment.builder() + .setOutput(PortNumber.portNumber(6)) + .build(); + + TrafficSelector toRadius = DefaultTrafficSelector.builder() + .matchInPort(PortNumber.portNumber(2)) + .matchEthType(Ethernet.TYPE_IPV4) + .matchIPProtocol(IPv4.PROTOCOL_UDP) + .matchUdpDst(TpPort.tpPort(radiusPort)) + .build(); + + TrafficSelector fromRadius = DefaultTrafficSelector.builder() + .matchInPort(PortNumber.portNumber(5)) + .matchEthType(Ethernet.TYPE_IPV4) + .matchIPProtocol(IPv4.PROTOCOL_UDP) + .matchUdpDst(TpPort.tpPort(radiusPort)) + .build(); + + TrafficTreatment toOlt = DefaultTrafficTreatment.builder() + .setOutput(PortNumber.portNumber(2)) + .build(); + + TrafficTreatment toVolt = DefaultTrafficTreatment.builder() + .setOutput(PortNumber.portNumber(9)) + .build(); + + TrafficTreatment sentToRadius = DefaultTrafficTreatment.builder() + .setOutput(PortNumber.portNumber(5)) + .build(); + + TrafficTreatment testPort = DefaultTrafficTreatment.builder() + .setOutput(PortNumber.portNumber(8)) + .build(); + + ForwardingObjective ofTestPath = DefaultForwardingObjective.builder() + .fromApp(appId) + .makePermanent() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(TESTPRIO) + .withSelector( + DefaultTrafficSelector.builder() + .matchInPort(PortNumber.portNumber(2)) + .build()) + .withTreatment(testPort) + .add(); + + ForwardingObjective radiusToServer = DefaultForwardingObjective.builder() + .fromApp(appId) + .makePermanent() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(PRIORITY) + .withSelector(toRadius) + .withTreatment(sentToRadius) + .add(); + + ForwardingObjective serverToRadius = DefaultForwardingObjective.builder() + .fromApp(appId) + .makePermanent() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(PRIORITY) + .withSelector(fromRadius) + .withTreatment(toOlt) + .add(); + + + + ForwardingObjective upCtrl = DefaultForwardingObjective.builder() + .fromApp(appId) + .makePermanent() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(PRIORITY) + .withSelector(ofInBandMatchUp) + .withTreatment(up) + .add(); + + ForwardingObjective downCtrl = DefaultForwardingObjective.builder() + .fromApp(appId) + .makePermanent() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(PRIORITY) + .withSelector(ofInBandMatchDown) + .withTreatment(down) + .add(); + + ForwardingObjective upOltMgmt = DefaultForwardingObjective.builder() + .fromApp(appId) + .makePermanent() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(PRIORITY) + .withSelector(oltMgmtUp) + .withTreatment(toVolt) + .add(); + + ForwardingObjective downOltMgmt = DefaultForwardingObjective.builder() + .fromApp(appId) + .makePermanent() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(PRIORITY) + .withSelector(oltMgmtDown) + .withTreatment(toOlt) + .add(); + + if (testMode) { + flowObjectiveService.forward(fabricDeviceId, ofTestPath); + } + + flowObjectiveService.forward(fabricDeviceId, upCtrl); + flowObjectiveService.forward(fabricDeviceId, downCtrl); + flowObjectiveService.forward(fabricDeviceId, radiusToServer); + flowObjectiveService.forward(fabricDeviceId, serverToRadius); + flowObjectiveService.forward(fabricDeviceId, upOltMgmt); + flowObjectiveService.forward(fabricDeviceId, downOltMgmt); + } + + @Override + public void addVlan(FabricVlan vlan) { + checkNotNull(vlan); + checkArgument(vlan.ports().size() > 1); + verifyPorts(vlan.ports()); + + removeVlan(vlan.vlan()); + + if (vlan.iptv()) { + provisionIPTV(); + } + + 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())); + } + }); + } + + //FIXME: pass iptv vlan in here. + private void provisionIPTV() { + TrafficSelector ipTvUp = DefaultTrafficSelector.builder() + .matchVlanId(VlanId.vlanId((short) 7)) + .matchInPort(PortNumber.portNumber(2)) + .build(); + + TrafficTreatment ipTvActUp = DefaultTrafficTreatment.builder() + .setOutput(PortNumber.portNumber(7)).build(); + + TrafficSelector ipTvDown = DefaultTrafficSelector.builder() + .matchVlanId(VlanId.vlanId((short) 7)) + .matchInPort(PortNumber.portNumber(7)) + .build(); + + TrafficTreatment ipTvActDown = DefaultTrafficTreatment.builder() + .setOutput(PortNumber.portNumber(2)).build(); + + ForwardingObjective ipTvUpstream = DefaultForwardingObjective.builder() + .fromApp(appId) + .makePermanent() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(PRIORITY) + .withSelector(ipTvUp) + .withTreatment(ipTvActUp) + .add(); + + ForwardingObjective ipTvDownstream = DefaultForwardingObjective.builder() + .fromApp(appId) + .makePermanent() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(PRIORITY) + .withSelector(ipTvDown) + .withTreatment(ipTvActDown) + .add(); + + flowObjectiveService.forward(fabricDeviceId, ipTvUpstream); + flowObjectiveService.forward(fabricDeviceId, ipTvDownstream); + } + + @Override + public void removeVlan(VlanId vlanId) { + Collection ports = vlans.removeAll(vlanId); + + ports.forEach(cp -> removeForwarding(vlanId, cp.deviceId(), cp.port(), + ports.stream() + .filter(p -> p != cp) + .map(ConnectPoint::port) + .collect(Collectors.toList()))); + } + + @Override + public List getVlans() { + List fVlans = new ArrayList<>(); + vlans.keySet().forEach(vlan -> fVlans.add( + //FIXME: Very aweful but will fo for now + new FabricVlan(vlan, vlans.get(vlan), vlan.toShort() == 201))); + return fVlans; + } + + private static void verifyPorts(List ports) { + DeviceId deviceId = ports.get(0).deviceId(); + for (ConnectPoint connectPoint : ports) { + if (!connectPoint.deviceId().equals(deviceId)) { + throw new IllegalArgumentException("Ports must all be on the same device"); + } + } + } + + private void addForwarding(VlanId vlanId, DeviceId deviceId, PortNumber inPort, + List outPorts) { + + TrafficSelector selector = DefaultTrafficSelector.builder() + .matchVlanId(vlanId) + .matchInPort(inPort) + .build(); + + TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder(); + + outPorts.forEach(p -> treatmentBuilder.setOutput(p)); + + ForwardingObjective objective = DefaultForwardingObjective.builder() + .fromApp(appId) + .makePermanent() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(PRIORITY) + .withSelector(selector) + .withTreatment(treatmentBuilder.build()) + .add(new ObjectiveHandler()); + + flowObjectiveService.forward(deviceId, objective); + } + + private void removeForwarding(VlanId vlanId, DeviceId deviceId, PortNumber inPort, + List outPorts) { + TrafficSelector selector = DefaultTrafficSelector.builder() + .matchVlanId(vlanId) + .matchInPort(inPort) + .build(); + + TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder(); + + outPorts.forEach(p -> treatmentBuilder.setOutput(p)); + + ForwardingObjective objective = DefaultForwardingObjective.builder() + .fromApp(appId) + .makePermanent() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(PRIORITY) + .withSelector(selector) + .withTreatment(treatmentBuilder.build()) + .remove(new ObjectiveHandler()); + + flowObjectiveService.forward(deviceId, objective); + } + + private static class ObjectiveHandler implements ObjectiveContext { + private static Logger log = LoggerFactory.getLogger(ObjectiveHandler.class); + + @Override + public void onSuccess(Objective objective) { + log.info("Flow objective operation successful: {}", objective); + } + + @Override + public void onError(Objective objective, ObjectiveError error) { + log.info("Flow objective operation failed: {}", objective); + } + } + + /** + * Internal listener for device service events. + */ + private class InternalDeviceListener implements DeviceListener { + @Override + public void event(DeviceEvent event) { + switch (event.type()) { + case DEVICE_ADDED: + case DEVICE_AVAILABILITY_CHANGED: + if (event.subject().id().equals(fabricDeviceId) && + deviceService.isAvailable(event.subject().id())) { + setupDefaultFlows(); + } + default: + break; + } + } + } +} diff --git a/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricService.java b/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricService.java new file mode 100644 index 00000000..5c2ce25c --- /dev/null +++ b/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricService.java @@ -0,0 +1,50 @@ +/* + * 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 org.onlab.packet.VlanId; + +import java.util.List; + +/** + * Service used to interact with fabric. + */ +public interface FabricService { + + /** + * Remaps a vlan to the specified ports. The specified ports will be the + * only ports in this vlan once the operation completes. + * + * @param vlan vlan object to add + */ + void addVlan(FabricVlan vlan); + + /** + * Removes a vlan from all ports in the fabric. + * + * @param vlanId ID of vlan to remove + */ + void removeVlan(VlanId vlanId); + + /** + * Returns the vlan to port mapping for all vlans/ports configured in the + * fabric. + * + * @return mapping of vlan to port + */ + List getVlans(); +} diff --git a/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricVlan.java b/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricVlan.java new file mode 100644 index 00000000..a5cfc07f --- /dev/null +++ b/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricVlan.java @@ -0,0 +1,57 @@ +/* + * 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 ports; + private final boolean iptv; + + public FabricVlan(VlanId vlan, Collection ports, boolean iptv) { + checkNotNull(vlan); + checkNotNull(ports); + this.vlan = vlan; + this.ports = ImmutableList.copyOf(ports); + this.iptv = iptv; + } + + public VlanId vlan() { + return vlan; + } + + public List ports() { + return ports; + } + + public boolean iptv() { + return iptv; + } +} diff --git a/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricVlanCodec.java b/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricVlanCodec.java new file mode 100644 index 00000000..00736bca --- /dev/null +++ b/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricVlanCodec.java @@ -0,0 +1,68 @@ +/* + * 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 { + + // JSON field names + private static final String VLAN = "vlan"; + private static final String PORTS = "ports"; + private static final String IPTV = "iptv"; + + @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(); + boolean iptv = json.path(IPTV).booleanValue(); + List 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, iptv); + } +} diff --git a/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricWebResource.java b/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricWebResource.java new file mode 100644 index 00000000..c35d975b --- /dev/null +++ b/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/FabricWebResource.java @@ -0,0 +1,99 @@ +/* + * 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 all CORD fabric VLANs. + * + * @return array of cord VLANs in the system. + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + public Response getVlans() { + FabricService fabricService = get(FabricService.class); + List vlans = fabricService.getVlans(); + ObjectNode result = new ObjectMapper().createObjectNode(); + result.set("vlans", new FabricVlanCodec().encode(vlans, this)); + + return ok(result.toString()).build(); + } + + /** + * Create a CORD fabric VLAN. + * + * @param input JSON stream describing new VLAN + * @return status of the request - CREATED if the JSON is correct, + * INTERNAL_SERVER_ERROR if the JSON is invalid + * @throws IOException if the JSON is invalid + */ + @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 a CORD fabric VLAN. + * + * @param vlan identifier of the VLAN to remove + * @return status of the request - OK + */ + @DELETE + @Path("{vlan}") + public Response deleteVlan(@PathParam("vlan") String vlan) { + VlanId vlanId = VlanId.vlanId(Short.parseShort(vlan)); + + FabricService fabricService = get(FabricService.class); + + fabricService.removeVlan(vlanId); + + return Response.ok().build(); + } +} diff --git a/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/FabricAddCommand.java b/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/FabricAddCommand.java new file mode 100644 index 00000000..e8cc6419 --- /dev/null +++ b/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/FabricAddCommand.java @@ -0,0 +1,64 @@ +/* + * 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.cli; + +import org.apache.karaf.shell.commands.Argument; +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.cordfabric.FabricVlan; +import org.onosproject.net.ConnectPoint; + +import java.util.ArrayList; +import java.util.List; + +/** + * Adds a vlan to the fabric. + */ +@Command(scope = "onos", name = "add-fabric-vlan", + description = "Adds a VLAN to the fabric") +public class FabricAddCommand extends AbstractShellCommand { + + @Argument(index = 0, name = "vlanid", description = "VLAN ID", + required = true, multiValued = false) + private String vlanIdString = null; + + @Argument(index = 1, name = "ports", + description = "List of ports in the VLAN", + required = true, multiValued = true) + private String[] portStrings = null; + + @Override + protected void execute() { + FabricService service = AbstractShellCommand.get(FabricService.class); + + VlanId vlan = VlanId.vlanId(Short.parseShort(vlanIdString)); + + if (portStrings.length < 2) { + throw new IllegalArgumentException("Must have at least 2 ports"); + } + + List ports = new ArrayList<>(portStrings.length); + + for (String portString : portStrings) { + ports.add(ConnectPoint.deviceConnectPoint(portString)); + } + + service.addVlan(new FabricVlan(vlan, ports, false)); + } +} diff --git a/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/FabricRemoveCommand.java b/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/FabricRemoveCommand.java new file mode 100644 index 00000000..9e470442 --- /dev/null +++ b/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/FabricRemoveCommand.java @@ -0,0 +1,44 @@ +/* + * 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.cli; + +import org.apache.karaf.shell.commands.Argument; +import org.apache.karaf.shell.commands.Command; +import org.onlab.packet.VlanId; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.cordfabric.FabricService; + +/** + * Removes a vlan from the fabric. + */ +@Command(scope = "onos", name = "remove-fabric-vlan", + description = "Removes a VLAN from the fabric") +public class FabricRemoveCommand extends AbstractShellCommand { + + @Argument(index = 0, name = "vlanid", description = "VLAN ID", + required = true, multiValued = false) + private String vlanIdString = null; + + @Override + protected void execute() { + FabricService service = AbstractShellCommand.get(FabricService.class); + + VlanId vlan = VlanId.vlanId(Short.parseShort(vlanIdString)); + + service.removeVlan(vlan); + } +} diff --git a/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/FabricShowCommand.java b/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/FabricShowCommand.java new file mode 100644 index 00000000..f632a883 --- /dev/null +++ b/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/FabricShowCommand.java @@ -0,0 +1,47 @@ +/* + * 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.cli; + +import org.apache.karaf.shell.commands.Command; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.cordfabric.FabricService; +import org.onosproject.cordfabric.FabricVlan; + +import java.util.List; + +/** + * Shows the vlans in the fabric. + */ +@Command(scope = "onos", name = "fabric", + description = "Shows the fabric vlans") +public class FabricShowCommand extends AbstractShellCommand { + + private static final String VLAN_HEADER_LINE_FORMAT = "VLAN %s"; + private static final String PORT_LINE_FORMAT = "\t%s"; + + @Override + protected void execute() { + FabricService service = AbstractShellCommand.get(FabricService.class); + + List vlans = service.getVlans(); + + vlans.forEach(fabricVlan -> { + print(VLAN_HEADER_LINE_FORMAT, fabricVlan.vlan()); + fabricVlan.ports().forEach(cp -> print(PORT_LINE_FORMAT, cp)); + }); + } +} diff --git a/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/package-info.java b/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/package-info.java new file mode 100644 index 00000000..e86ee9ef --- /dev/null +++ b/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/cli/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Console commands for managing fabric of VLANs. + */ +package org.onosproject.cordfabric.cli; \ No newline at end of file diff --git a/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/package-info.java b/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/package-info.java new file mode 100644 index 00000000..d895f1f3 --- /dev/null +++ b/framework/src/onos/apps/cordfabric/src/main/java/org/onosproject/cordfabric/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Service for managing fabric of VLANs. + */ +package org.onosproject.cordfabric; \ No newline at end of file diff --git a/framework/src/onos/apps/cordfabric/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/framework/src/onos/apps/cordfabric/src/main/resources/OSGI-INF/blueprint/shell-config.xml new file mode 100644 index 00000000..128f8612 --- /dev/null +++ b/framework/src/onos/apps/cordfabric/src/main/resources/OSGI-INF/blueprint/shell-config.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/framework/src/onos/apps/cordfabric/src/main/webapp/WEB-INF/web.xml b/framework/src/onos/apps/cordfabric/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000..06d3a355 --- /dev/null +++ b/framework/src/onos/apps/cordfabric/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,44 @@ + + + + CORD Fabric REST API v1.0 + + + JAX-RS Service + com.sun.jersey.spi.container.servlet.ServletContainer + + com.sun.jersey.config.property.resourceConfigClass + com.sun.jersey.api.core.ClassNamesResourceConfig + + + com.sun.jersey.config.property.classnames + + org.onosproject.cordfabric.FabricWebResource + + + 1 + + + + JAX-RS Service + /* + + + -- cgit 1.2.3-korg