diff options
Diffstat (limited to 'framework/src/onos/apps')
137 files changed, 7176 insertions, 515 deletions
diff --git a/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AAA.java b/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AAA.java index 72a5b122..567944a6 100644 --- a/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AAA.java +++ b/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AAA.java @@ -419,6 +419,7 @@ public class AAA { * Handles RADIUS packets. * * @param radiusPacket RADIUS packet coming from the RADIUS server. + * @throws StateMachineException if an illegal state transition is triggered */ protected void handleRadiusPacket(RADIUS radiusPacket) throws StateMachineException { StateMachine stateMachine = StateMachine.lookupStateMachineById(radiusPacket.getIdentifier()); diff --git a/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java index 4b28a14b..e15bc763 100644 --- a/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java +++ b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java @@ -23,17 +23,27 @@ 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.util.ItemNotFoundException; import org.onlab.util.KryoNamespace; import org.onosproject.cluster.ClusterService; import org.onosproject.core.ApplicationId; import org.onosproject.core.CoreService; +import org.onosproject.net.DefaultAnnotations; import org.onosproject.net.Device; import org.onosproject.net.DeviceId; import org.onosproject.net.Host; +import org.onosproject.net.behaviour.BridgeConfig; +import org.onosproject.net.behaviour.BridgeName; import org.onosproject.net.behaviour.ControllerInfo; +import org.onosproject.net.behaviour.DefaultTunnelDescription; +import org.onosproject.net.behaviour.TunnelConfig; +import org.onosproject.net.behaviour.TunnelDescription; +import org.onosproject.net.behaviour.TunnelName; import org.onosproject.net.device.DeviceEvent; import org.onosproject.net.device.DeviceListener; import org.onosproject.net.device.DeviceService; +import org.onosproject.net.driver.DriverHandler; +import org.onosproject.net.driver.DriverService; import org.onosproject.net.host.HostEvent; import org.onosproject.net.host.HostListener; import org.onosproject.net.host.HostService; @@ -58,6 +68,7 @@ import java.util.concurrent.Executors; import static com.google.common.base.Preconditions.checkNotNull; import static org.onlab.util.Tools.groupedThreads; import static org.onosproject.net.Device.Type.SWITCH; +import static org.onosproject.net.behaviour.TunnelDescription.Type.VXLAN; import static org.slf4j.LoggerFactory.getLogger; /** @@ -79,7 +90,6 @@ public class CordVtn implements CordVtnService { private static final Map<String, String> DEFAULT_TUNNEL_OPTIONS = new HashMap<String, String>() { { put("key", "flow"); - put("local_ip", "flow"); put("remote_ip", "flow"); } }; @@ -99,6 +109,9 @@ public class CordVtn implements CordVtnService { protected HostService hostService; @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DriverService driverService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected OvsdbController controller; @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) @@ -213,8 +226,8 @@ public class CordVtn implements CordVtnService { if (deviceService.getDevice(ovsdb.intBrId()) == null || !deviceService.isAvailable(ovsdb.intBrId())) { createIntegrationBridge(ovsdb); - } else if (!checkVxlanPort(ovsdb)) { - createVxlanPort(ovsdb); + } else if (!checkVxlanInterface(ovsdb)) { + createVxlanInterface(ovsdb); } } @@ -272,26 +285,41 @@ public class CordVtn implements CordVtnService { }); String dpid = ovsdb.intBrId().toString().substring(DPID_BEGIN); - // TODO change to use bridge config - OvsdbClientService ovsdbClient = getOvsdbClient(ovsdb); - ovsdbClient.createBridge(DEFAULT_BRIDGE_NAME, dpid, controllers); + try { + DriverHandler handler = driverService.createHandler(ovsdb.deviceId()); + BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class); + bridgeConfig.addBridge(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME), dpid, controllers); + } catch (ItemNotFoundException e) { + log.warn("Failed to create integration bridge on {}", ovsdb.deviceId()); + } } - private void createVxlanPort(OvsdbNode ovsdb) { - // TODO change to use tunnel config and tunnel description - OvsdbClientService ovsdbClient = getOvsdbClient(ovsdb); - ovsdbClient.createTunnel(DEFAULT_BRIDGE_NAME, DEFAULT_TUNNEL, - DEFAULT_TUNNEL, DEFAULT_TUNNEL_OPTIONS); + private void createVxlanInterface(OvsdbNode ovsdb) { + DefaultAnnotations.Builder optionBuilder = DefaultAnnotations.builder(); + for (String key : DEFAULT_TUNNEL_OPTIONS.keySet()) { + optionBuilder.set(key, DEFAULT_TUNNEL_OPTIONS.get(key)); + } + TunnelDescription description = + new DefaultTunnelDescription(null, null, VXLAN, + TunnelName.tunnelName(DEFAULT_TUNNEL), + optionBuilder.build()); + try { + DriverHandler handler = driverService.createHandler(ovsdb.deviceId()); + TunnelConfig tunnelConfig = handler.behaviour(TunnelConfig.class); + tunnelConfig.createTunnelInterface(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME), description); + } catch (ItemNotFoundException e) { + log.warn("Failed to create VXLAN interface on {}", ovsdb.deviceId()); + } } - private boolean checkVxlanPort(OvsdbNode ovsdb) { - // TODO change to use tunnel config - OvsdbClientService ovsdbClient = getOvsdbClient(ovsdb); + private boolean checkVxlanInterface(OvsdbNode ovsdb) { try { - ovsdbClient.getPorts().stream() - .filter(p -> p.portName().value().equals(DEFAULT_TUNNEL)) - .findFirst().get(); - } catch (NoSuchElementException e) { + DriverHandler handler = driverService.createHandler(ovsdb.deviceId()); + BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class); + bridgeConfig.getPorts().stream() + .filter(p -> p.annotations().value("portName").equals(DEFAULT_TUNNEL)) + .findAny().get(); + } catch (ItemNotFoundException | NoSuchElementException e) { return false; } return true; @@ -374,8 +402,8 @@ public class CordVtn implements CordVtnService { return; } - if (!checkVxlanPort(ovsdb)) { - createVxlanPort(ovsdb); + if (!checkVxlanInterface(ovsdb)) { + createVxlanInterface(ovsdb); } } diff --git a/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnConfigManager.java b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnConfigManager.java index 287f2a34..274ca9b4 100644 --- a/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnConfigManager.java +++ b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnConfigManager.java @@ -72,8 +72,6 @@ public class CordVtnConfigManager { configService.addListener(configListener); configRegistry.registerConfigFactory(configFactory); - - readConfiguration(); } @Deactivate @@ -101,7 +99,22 @@ public class CordVtnConfigManager { @Override public void event(NetworkConfigEvent event) { - // TODO handle update event + if (!event.configClass().equals(CordVtnConfig.class)) { + return; + } + + switch (event.type()) { + case CONFIG_ADDED: + log.info("Network configuration added"); + readConfiguration(); + break; + case CONFIG_UPDATED: + log.info("Network configuration updated"); + readConfiguration(); + break; + default: + break; + } } } } diff --git a/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/DefaultOvsdbNode.java b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/DefaultOvsdbNode.java index eba52108..46f6e29c 100644 --- a/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/DefaultOvsdbNode.java +++ b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/DefaultOvsdbNode.java @@ -61,7 +61,7 @@ public class DefaultOvsdbNode implements OvsdbNode { @Override public DeviceId deviceId() { - return DeviceId.deviceId("ovsdb:" + this.ip.toString() + ":" + this.port.toString()); + return DeviceId.deviceId("ovsdb:" + this.ip.toString()); } @Override diff --git a/framework/src/onos/apps/dhcp/api/pom.xml b/framework/src/onos/apps/dhcp/api/pom.xml new file mode 100644 index 00000000..fb5246f7 --- /dev/null +++ b/framework/src/onos/apps/dhcp/api/pom.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2014 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <artifactId>onos-dhcp</artifactId> + <groupId>org.onosproject</groupId> + <version>1.4.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>onos-app-dhcp-api</artifactId> + <packaging>bundle</packaging> + + <url>http://onosproject.org</url> + + <description>DHCP Server application API</description> + + <dependencies> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onlab-junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-core-serializers</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-incubator-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-api</artifactId> + <version>${project.version}</version> + <classifier>tests</classifier> + <scope>test</scope> + </dependency> + + </dependencies> + + +</project> diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpService.java b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java index 7c2127f9..7c2127f9 100644 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpService.java +++ b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpStore.java b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java index e263b3a2..e263b3a2 100644 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpStore.java +++ b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/IpAssignment.java b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java index 9b3aa686..9b3aa686 100644 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/IpAssignment.java +++ b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/package-info.java b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/package-info.java index 56778a35..56778a35 100644 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/package-info.java +++ b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/package-info.java diff --git a/framework/src/onos/apps/dhcp/src/test/java/org/onosproject/dhcp/IpAssignmentTest.java b/framework/src/onos/apps/dhcp/api/src/test/java/org/onosproject/dhcp/IpAssignmentTest.java index 3ecc5cfa..3ecc5cfa 100644 --- a/framework/src/onos/apps/dhcp/src/test/java/org/onosproject/dhcp/IpAssignmentTest.java +++ b/framework/src/onos/apps/dhcp/api/src/test/java/org/onosproject/dhcp/IpAssignmentTest.java diff --git a/framework/src/onos/apps/dhcp/app/app.xml b/framework/src/onos/apps/dhcp/app/app.xml new file mode 100644 index 00000000..bf324b19 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/app.xml @@ -0,0 +1,23 @@ +<?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. + --> +<app name="org.onosproject.dhcp" origin="ON.Lab" version="${project.version}" + featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features" + features="${project.artifactId}"> + <description>${project.description}</description> + <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact> + <artifact>mvn:${project.groupId}/onos-app-dhcp-api/${project.version}</artifact> +</app> diff --git a/framework/src/onos/apps/dhcp/app/features.xml b/framework/src/onos/apps/dhcp/app/features.xml new file mode 100644 index 00000000..0b277dea --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/features.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!-- + ~ 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. + --> +<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}"> + <repository>mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features</repository> + <feature name="${project.artifactId}" version="${project.version}" + description="${project.description}"> + <feature>onos-api</feature> + <bundle>mvn:${project.groupId}/onos-app-dhcp-api/${project.version}</bundle> + <bundle>mvn:${project.groupId}/onos-app-dhcp/${project.version}</bundle> + </feature> +</features> diff --git a/framework/src/onos/apps/dhcp/app/pom.xml b/framework/src/onos/apps/dhcp/app/pom.xml new file mode 100644 index 00000000..6589402a --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/pom.xml @@ -0,0 +1,166 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2014 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. + --><project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <artifactId>onos-dhcp</artifactId> + <groupId>org.onosproject</groupId> + <version>1.4.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>onos-app-dhcp</artifactId> + <packaging>bundle</packaging> + + <url>http://onosproject.org</url> + + <description>DHCP Server application</description> + + <properties> + <onos.app.name>org.onosproject.dhcp</onos.app.name> + <web.context>/onos/dhcp</web.context> + <api.version>1.0.0</api.version> + <api.title>DHCP Server REST API</api.title> + <api.description> + APIs for interacting with the DHCP Server application. + </api.description> + <api.package>org.onosproject.dhcp.rest</api.package> + </properties> + + <dependencies> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-app-dhcp-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.compendium</artifactId> + </dependency> + + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-cli</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.karaf.shell</groupId> + <artifactId>org.apache.karaf.shell.console</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onlab-junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-core-serializers</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-incubator-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-api</artifactId> + <version>${project.version}</version> + <classifier>tests</classifier> + <scope>test</scope> + </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> + </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.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, + com.fasterxml.jackson.core, + org.apache.karaf.shell.commands, + org.apache.karaf.shell.console, + 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/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpLeaseDetails.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpLeaseDetails.java index 95f49e69..95f49e69 100644 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpLeaseDetails.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpLeaseDetails.java diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java index 209ba683..209ba683 100644 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpRemoveStaticMapping.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpRemoveStaticMapping.java index a92cd250..a92cd250 100644 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpRemoveStaticMapping.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpRemoveStaticMapping.java diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java index 9f4f6580..9f4f6580 100644 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/FreeIpCompleter.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/FreeIpCompleter.java index 228d70fd..228d70fd 100644 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/FreeIpCompleter.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/FreeIpCompleter.java diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/MacIdCompleter.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/MacIdCompleter.java index d6cd73a7..d6cd73a7 100644 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/MacIdCompleter.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/MacIdCompleter.java diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/package-info.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/package-info.java index f8780195..f8780195 100644 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/package-info.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/package-info.java diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java index 4353d623..4353d623 100644 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java index 96d94a2b..96d94a2b 100644 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpUi.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpUi.java index bb2bd2c2..bb2bd2c2 100644 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpUi.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpUi.java diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java index 9ce65d5e..9ce65d5e 100644 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java index 63f69d40..63f69d40 100644 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/package-info.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/package-info.java index 12e14e48..12e14e48 100644 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/package-info.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/package-info.java diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java index 646ab7ea..646ab7ea 100644 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/package-info.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/package-info.java index 73173c55..73173c55 100644 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/package-info.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/package-info.java diff --git a/framework/src/onos/apps/dhcp/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/framework/src/onos/apps/dhcp/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml index ce716315..ce716315 100644 --- a/framework/src/onos/apps/dhcp/src/main/resources/OSGI-INF/blueprint/shell-config.xml +++ b/framework/src/onos/apps/dhcp/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml diff --git a/framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.css b/framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.css index e0a29314..e0a29314 100644 --- a/framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.css +++ b/framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.css diff --git a/framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.html b/framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.html index 5782badf..5782badf 100644 --- a/framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.html +++ b/framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.html diff --git a/framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.js b/framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.js index 061d0de6..061d0de6 100644 --- a/framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.js +++ b/framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.js diff --git a/framework/src/onos/apps/dhcp/src/main/resources/gui/css.html b/framework/src/onos/apps/dhcp/app/src/main/resources/gui/css.html index d02ad44a..d02ad44a 100644 --- a/framework/src/onos/apps/dhcp/src/main/resources/gui/css.html +++ b/framework/src/onos/apps/dhcp/app/src/main/resources/gui/css.html diff --git a/framework/src/onos/apps/dhcp/src/main/resources/gui/js.html b/framework/src/onos/apps/dhcp/app/src/main/resources/gui/js.html index d37b5768..d37b5768 100644 --- a/framework/src/onos/apps/dhcp/src/main/resources/gui/js.html +++ b/framework/src/onos/apps/dhcp/app/src/main/resources/gui/js.html diff --git a/framework/src/onos/apps/dhcp/src/main/webapp/WEB-INF/web.xml b/framework/src/onos/apps/dhcp/app/src/main/webapp/WEB-INF/web.xml index 27504548..27504548 100644 --- a/framework/src/onos/apps/dhcp/src/main/webapp/WEB-INF/web.xml +++ b/framework/src/onos/apps/dhcp/app/src/main/webapp/WEB-INF/web.xml diff --git a/framework/src/onos/apps/dhcp/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java b/framework/src/onos/apps/dhcp/app/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java index fd4701c6..fd4701c6 100644 --- a/framework/src/onos/apps/dhcp/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java +++ b/framework/src/onos/apps/dhcp/app/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java diff --git a/framework/src/onos/apps/dhcp/src/test/resources/dhcp-cfg.json b/framework/src/onos/apps/dhcp/app/src/test/resources/dhcp-cfg.json index abc48a83..abc48a83 100644 --- a/framework/src/onos/apps/dhcp/src/test/resources/dhcp-cfg.json +++ b/framework/src/onos/apps/dhcp/app/src/test/resources/dhcp-cfg.json diff --git a/framework/src/onos/apps/dhcp/pom.xml b/framework/src/onos/apps/dhcp/pom.xml index 0daa4f7b..7a10776e 100644 --- a/framework/src/onos/apps/dhcp/pom.xml +++ b/framework/src/onos/apps/dhcp/pom.xml @@ -13,149 +13,30 @@ ~ 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. - --><project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> - <artifactId>onos-apps</artifactId> <groupId>org.onosproject</groupId> + <artifactId>onos-apps</artifactId> <version>1.4.0-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent> - <artifactId>onos-app-dhcp</artifactId> - <packaging>bundle</packaging> - - <url>http://onosproject.org</url> + <artifactId>onos-dhcp</artifactId> + <packaging>pom</packaging> - <description>DHCP Server application</description> + <description>ONOS sample applications</description> - <properties> - <onos.app.name>org.onosproject.dhcp</onos.app.name> - <web.context>/onos/dhcp</web.context> - <api.version>1.0.0</api.version> - <api.title>DHCP Server REST API</api.title> - <api.description> - APIs for interacting with the DHCP Server application. - </api.description> - <api.package>org.onosproject.dhcp.rest</api.package> - </properties> + <modules> + <module>api</module> + <module>app</module> + </modules> <dependencies> - <dependency> - <groupId>org.osgi</groupId> - <artifactId>org.osgi.compendium</artifactId> - </dependency> - - <dependency> - <groupId>org.onosproject</groupId> - <artifactId>onos-cli</artifactId> - <version>${project.version}</version> - </dependency> - - <dependency> - <groupId>org.apache.karaf.shell</groupId> - <artifactId>org.apache.karaf.shell.console</artifactId> - <scope>compile</scope> - </dependency> - - <dependency> - <groupId>org.onosproject</groupId> - <artifactId>onlab-junit</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.onosproject</groupId> - <artifactId>onos-core-serializers</artifactId> - <version>${project.version}</version> - </dependency> - - <dependency> - <groupId>org.onosproject</groupId> - <artifactId>onos-incubator-api</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>org.onosproject</groupId> - <artifactId>onos-api</artifactId> - <version>${project.version}</version> - <classifier>tests</classifier> - <scope>test</scope> - </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> </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.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, - com.fasterxml.jackson.core, - org.apache.karaf.shell.commands, - org.apache.karaf.shell.console, - 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/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/tunnel/package-info.java b/framework/src/onos/apps/igmp/src/main/java/org/onosproject/igmp/impl/package-info.java index 3a84e6e3..7d420198 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/tunnel/package-info.java +++ b/framework/src/onos/apps/igmp/src/main/java/org/onosproject/igmp/impl/package-info.java @@ -15,6 +15,6 @@ */ /** - * Service for interacting with the inventory of subnets. + * IGMP implementation. */ -package org.onosproject.vtnrsc.tunnel; +package org.onosproject.igmp.impl; diff --git a/framework/src/onos/apps/mfwd/src/main/java/org/onosproject/mfwd/rest/package-info.java b/framework/src/onos/apps/mfwd/src/main/java/org/onosproject/mfwd/rest/package-info.java new file mode 100644 index 00000000..b42586fe --- /dev/null +++ b/framework/src/onos/apps/mfwd/src/main/java/org/onosproject/mfwd/rest/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. + */ + +/** + * REST API for multicase forwarding. + */ +package org.onosproject.mfwd.rest; diff --git a/framework/src/onos/apps/mlb/src/main/java/org/onosproject/mlb/package-info.java b/framework/src/onos/apps/mlb/src/main/java/org/onosproject/mlb/package-info.java new file mode 100644 index 00000000..a7d83757 --- /dev/null +++ b/framework/src/onos/apps/mlb/src/main/java/org/onosproject/mlb/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. + */ + +/** + * Mastership load balancer. + */ +package org.onosproject.mlb; diff --git a/framework/src/onos/apps/openstackswitching/pom.xml b/framework/src/onos/apps/openstackswitching/pom.xml new file mode 100644 index 00000000..245b9e80 --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/pom.xml @@ -0,0 +1,121 @@ +<?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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onosproject</groupId> + <artifactId>onos-apps</artifactId> + <version>1.4.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>onos-app-openstackswitching</artifactId> + <packaging>bundle</packaging> + + <description>SONA Openstack Switching applications</description> + <properties> + <onos.version>1.4.0-SNAPSHOT</onos.version> + <onos.app.name>org.onosproject.openstackswitching</onos.app.name> + <web.context>/onos/openstackswitching</web.context> + <api.version>1.0.0</api.version> + <api.title>ONOS OpenStack Switching REST API</api.title> + <api.description> + APIs for receiving Neutron information. + </api.description> + <api.package>org.onosproject.openstackswitching.web</api.package> + <onos.app.origin>SKT, Inc.</onos.app.origin> + </properties> + + + <dependencies> + <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, + com.fasterxml.jackson.core, + org.apache.karaf.shell.commands, + com.google.common.*, + org.onlab.packet.*, + org.onosproject.* + </Import-Package> + <Web-ContextPath>${web.context}</Web-ContextPath> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + + +</project> diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackArpHandler.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackArpHandler.java new file mode 100644 index 00000000..afaf7a22 --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackArpHandler.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.openstackswitching; + +import org.onosproject.net.packet.InboundPacket; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; + +/** + * It handles ARP packet from VMs. + */ +public class OpenstackArpHandler { + + private static Logger log = LoggerFactory + .getLogger(OpenstackArpHandler.class); + + HashMap<String, OpenstackPort> openstackPortHashMap; + + /** + * Constructs an OpenstackArpHandler. + * + * @param openstackPortMap port map + */ + public OpenstackArpHandler(HashMap<String, OpenstackPort> openstackPortMap) { + this.openstackPortHashMap = openstackPortMap; + } + + /** + * Processes ARP packets. + * + * @param pkt ARP request packet + */ + public void processPacketIn(InboundPacket pkt) { + log.warn("Received an ARP packet"); + } +} diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackDhcpHandler.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackDhcpHandler.java new file mode 100644 index 00000000..9c3641c1 --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackDhcpHandler.java @@ -0,0 +1,45 @@ +/* +* 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.openstackswitching; + +import org.onosproject.net.packet.InboundPacket; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * It handles DHCP request packets. + */ +public class OpenstackDhcpHandler { + + private static Logger log = LoggerFactory + .getLogger(OpenstackDhcpHandler.class); + + /** + * Returns OpenstackDhcpHandler reference. + */ + public OpenstackDhcpHandler() { + + } + + /** + * Processes DHCP request packets. + * + * @param pkt DHCP request packet + */ + public void processPacketIn(InboundPacket pkt) { + log.warn("Received a DHCP packet"); + } +} diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackNetwork.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackNetwork.java new file mode 100644 index 00000000..dc7c0263 --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackNetwork.java @@ -0,0 +1,112 @@ +/* + * 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.openstackswitching; + +import static com.google.common.base.Preconditions.checkNotNull; + + +/** + * Represents the network information given by Neutron. + */ +public final class OpenstackNetwork { + + private String name; + private String tenantId; + private String segmentId; + private String networkType; + private String id; + + /** + * Returns the builder object of the OpenstackNetwork class. + * + * @return OpenstackNetwork builder object + */ + public static OpenstackNetwork.Builder builder() { + return new Builder(); + } + + private OpenstackNetwork(String name, String tenantId, String id, String sid, + String type) { + this.name = checkNotNull(name); + this.tenantId = checkNotNull(tenantId); + this.segmentId = checkNotNull(sid); + this.id = checkNotNull(id); + this.networkType = checkNotNull(type); + } + + public String name() { + return this.name; + } + + public String tenantId() { + return this.tenantId; + } + + public String id() { + return this.id; + } + + public String segmentId() { + return this.segmentId; + } + + public String networkType() { + return this.networkType; + } + + public static final class Builder { + private String name; + private String tenantId; + private String id; + private String sid; + private String networkType; + + public Builder name(String name) { + this.name = name; + + return this; + } + + public Builder tenantId(String tenantId) { + this.tenantId = tenantId; + + return this; + } + + public Builder id(String id) { + this.id = id; + + return this; + } + + public Builder segmentId(String sid) { + this.sid = sid; + + return this; + } + + public Builder networkType(String type) { + this.networkType = type; + + return this; + } + + public OpenstackNetwork build() { + return new OpenstackNetwork(name, tenantId, id, sid, networkType); + } + + } +} diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackPort.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackPort.java new file mode 100644 index 00000000..4326b4fc --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackPort.java @@ -0,0 +1,350 @@ +/* + * 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.openstackswitching; + +import com.google.common.collect.Lists; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.MacAddress; + +import java.util.HashMap; +import java.util.List; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * It represents the Openstack Port information. + */ +public final class OpenstackPort { + + public enum PortStatus { + UP, + DOWN + } + + private PortStatus status; + private String name; + // FIX_ME + private String allowedAddressPairs; + private boolean adminStateUp; + private String networkId; + private String tenantId; + private String deviceOwner; + private MacAddress macAddress; + // <subnet id, ip address> + private HashMap<String, Ip4Address> fixedIps; + private String id; + private List<String> securityGroups; + private String deviceId; + + private OpenstackPort(PortStatus status, String name, boolean adminStateUp, + String networkId, String tenantId, String deviceOwner, + MacAddress macAddress, HashMap fixedIps, String id, + List<String> securityGroups, String deviceId) { + + this.status = status; + this.name = name; + this.adminStateUp = adminStateUp; + this.networkId = checkNotNull(networkId); + this.tenantId = checkNotNull(tenantId); + this.deviceOwner = deviceOwner; + this.macAddress = checkNotNull(macAddress); + this.fixedIps = checkNotNull(fixedIps); + this.id = checkNotNull(id); + this.securityGroups = securityGroups; + this.deviceId = deviceId; + } + + + + /** + * Returns OpenstackPort builder object. + * + * @return OpenstackPort builder + */ + public static OpenstackPort.Builder builder() { + return new Builder(); + } + + /** + * Returns port status. + * + * @return port status + */ + public PortStatus status() { + return status; + } + + /** + * Returns port name. + * + * @return port name + */ + public String name() { + return name; + } + + /** + * Returns whether admin state up or not. + * + * @return true if admin state up, false otherwise + */ + public boolean isAdminStateUp() { + return adminStateUp; + } + + /** + * Returns network ID. + * + * @return network ID + */ + public String networkId() { + return networkId; + } + + /** + * Returns device owner. + * + * @return device owner + */ + public String deviceOwner() { + return deviceOwner; + } + + /** + * Returns mac address. + * + * @return mac address + */ + public MacAddress macAddress() { + return macAddress; + } + + /** + * Returns the fixed IP information. + * + * @return fixed IP info + */ + public HashMap fixedIps() { + return fixedIps; + } + + /** + * Returns port ID. + * + * @return port ID + */ + public String id() { + return id; + } + + /** + * Returns security group information. + * + * @return security group info + */ + public List<String> securityGroups() { + return securityGroups; + } + + /** + * Returns device ID. + * + * @return device ID + */ + public String deviceId() { + return deviceId; + } + + // TODO : Implement the following functions when necessary + //@Override + //public void equals(Object that) { + // + //} + // + //@Override + //public int hashCode() { + // + //} + + /** + * OpenstackPort Builder class. + */ + public static final class Builder { + + private PortStatus status; + private String name; + // FIX_ME + private String allowedAddressPairs; + private boolean adminStateUp; + private String networkId; + private String tenantId; + private String deviceOwner; + private MacAddress macAddress; + // list of hash map <subnet id, ip address> + private HashMap<String, Ip4Address> fixedIps; + private String id; + private List<String> securityGroups; + private String deviceId; + + Builder() { + fixedIps = new HashMap<>(); + securityGroups = Lists.newArrayList(); + } + + /** + * Sets port status. + * + * @param status port status + * @return Builder object + */ + public Builder portStatus(PortStatus status) { + this.status = status; + + return this; + } + + /** + * Sets port name. + * + * @param name port name + * @return Builder object + */ + public Builder name(String name) { + this.name = name; + + return this; + } + + /** + * Sets whether admin state up or not. + * + * @param isAdminStateUp true if admin state is up, false otherwise + * @return Builder object + */ + public Builder adminState(boolean isAdminStateUp) { + this.adminStateUp = isAdminStateUp; + + return this; + } + + /** + * Sets network ID. + * + * @param networkId network ID + * @return Builder object + */ + public Builder netwrokId(String networkId) { + this.networkId = networkId; + + return this; + } + + /** + * Sets tenant ID. + * + * @param tenantId tenant ID + * @return Builder object + */ + public Builder tenantId(String tenantId) { + this.tenantId = tenantId; + + return this; + } + + /** + * Sets device owner. + * + * @param owner device owner + * @return Builder object + */ + public Builder deviceOwner(String owner) { + this.deviceOwner = owner; + + return this; + } + + /** + * Sets MAC address of the port. + * + * @param mac MAC address + * @return Builder object + */ + public Builder macAddress(MacAddress mac) { + this.macAddress = mac; + + return this; + } + + /** + * Sets Fixed IP address information. + * + * @param fixedIpList Fixed IP info + * @return Builder object + */ + public Builder fixedIps(HashMap<String, Ip4Address> fixedIpList) { + fixedIps.putAll(fixedIpList); + + return this; + } + + /** + * Sets ID of the port. + * + * @param id ID of the port + * @return Builder object + */ + public Builder id(String id) { + this.id = id; + + return this; + } + + /** + * Sets security group of the port. + * + * @param securityGroup security group of the port + * @return Builder object + */ + public Builder securityGroup(String securityGroup) { + securityGroups.add(securityGroup); + + return this; + } + + /** + * Sets device ID of the port. + * + * @param deviceId device ID + * @return Builder object + */ + public Builder deviceId(String deviceId) { + this.deviceId = deviceId; + + return this; + } + + /** + * Builds an OpenstackPort object. + * + * @return OpenstackPort objecet + */ + public OpenstackPort build() { + return new OpenstackPort(status, name, adminStateUp, networkId, networkId, + deviceOwner, macAddress, fixedIps, id, securityGroups, deviceId); + } + } +} + diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java new file mode 100644 index 00000000..baae7f80 --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java @@ -0,0 +1,437 @@ +/* + * 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.openstackswitching; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +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.Ip4Address; +import org.onlab.packet.Ip4Prefix; +import org.onlab.packet.MacAddress; +import org.onlab.packet.UDP; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.net.Device; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Port; +import org.onosproject.net.device.DeviceEvent; +import org.onosproject.net.device.DeviceListener; +import org.onosproject.net.device.DeviceService; +import org.onosproject.net.flowobjective.FlowObjectiveService; +import org.onosproject.net.packet.InboundPacket; +import org.onosproject.net.packet.PacketContext; +import org.onosproject.net.packet.PacketProcessor; +import org.onosproject.net.packet.PacketService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +@SuppressWarnings("ALL") +@Service +@Component(immediate = true) +/** + * It populates forwarding rules for VMs created by Openstack. + */ +public class OpenstackSwitchingManager implements OpenstackSwitchingService { + + private static Logger log = LoggerFactory + .getLogger(OpenstackSwitchingManager.class); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected PacketService packetService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DeviceService deviceService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected FlowObjectiveService flowObjectiveService; + + + public static final int DHCP_PORT = 67; + + private ApplicationId appId; + private OpenstackArpHandler arpHandler; + private OpenstackDhcpHandler dhcpHandler = new OpenstackDhcpHandler(); + private OpenstackSwitchingRulePopulator rulePopulator; + private ExecutorService deviceEventExcutorService = Executors.newFixedThreadPool(10); + + private InternalPacketProcessor internalPacketProcessor = new InternalPacketProcessor(); + private InternalDeviceListener internalDeviceListener = new InternalDeviceListener(); + + // Map <port_id, OpenstackPort> + private HashMap<String, OpenstackPort> openstackPortMap; + // Map <network_id, OpenstackNetwork> + private HashMap<String, OpenstackNetwork> openstackNetworkMap; + // Map <vni, List <Entry <portName, host ip>> + private HashMap<String, List<PortInfo>> vniPortMap; + private HashMap<Ip4Address, Port> tunnelPortMap; + + + @Activate + protected void activate() { + appId = coreService + .registerApplication("org.onosproject.openstackswitching"); + rulePopulator = new OpenstackSwitchingRulePopulator(appId, flowObjectiveService); + packetService.addProcessor(internalPacketProcessor, PacketProcessor.director(1)); + deviceService.addListener(internalDeviceListener); + + openstackPortMap = Maps.newHashMap(); + openstackNetworkMap = Maps.newHashMap(); + vniPortMap = Maps.newHashMap(); + tunnelPortMap = Maps.newHashMap(); + + arpHandler = new OpenstackArpHandler(openstackPortMap); + + log.info("Started"); + } + + @Deactivate + protected void deactivate() { + packetService.removeProcessor(internalPacketProcessor); + deviceService.removeListener(internalDeviceListener); + + deviceEventExcutorService.shutdown(); + + log.info("Stopped"); + } + + @Override + public void createPorts(OpenstackPort openstackPort) { + openstackPortMap.put(openstackPort.id(), openstackPort); + } + + @Override + public void deletePorts() { + + } + + @Override + public void updatePorts() { + + } + + @Override + public void createNetwork(OpenstackNetwork openstackNetwork) { + openstackNetworkMap.put(openstackNetwork.id(), openstackNetwork); + } + + private void processDeviceAdded(Device device) { + log.warn("device {} is added", device.id()); + rulePopulator.populateDefaultRules(device.id()); + } + + private void processPortAdded(Device device, Port port) { + // TODO: Simplify the data structure to store the network info + // TODO: Make it stateless + // TODO: All the logics need to be processed inside of the rulePopulator class + synchronized (vniPortMap) { + log.warn("port {} is updated", port.toString()); + + updatePortMaps(device, port); + if (!port.annotations().value("portName").equals("vxlan")) { + populateFlowRulesForTrafficToSameCnode(device, port); + populateFlowRulesForTrafficToDifferentCnode(device, port); + } + } + } + + private void processPortRemoved(Device device, Port port) { + log.warn("port {} is removed", port.toString()); + // TODO: need to update the vniPortMap + } + + /** + * Populates the flow rules for traffic to VMs in different Cnode using + * Nicira extention. + * + * @param device device to put rules + * @param port port information of the VM + */ + private void populateFlowRulesForTrafficToDifferentCnode(Device device, Port port) { + String portName = port.annotations().value("portName"); + String channelId = device.annotations().value("channelId"); + Ip4Address hostIpAddress = Ip4Address.valueOf(channelId.split(":")[0]); + Ip4Address fixedIp = getFixedIpAddressForPort(portName); + // TODO: Avoid duplicate flow rule set up for VMs in other Cnode + // (possibly avoided by flowrule subsystem?) + if (tunnelPortMap.get(hostIpAddress) == null) { + log.warn("There is no tunnel port information"); + return; + } + String vni = getVniForPort(portName); + MacAddress vmMac = getVmMacAddressForPort(portName); + if (!vniPortMap.isEmpty() && vniPortMap.get(vni) != null) { + for (PortInfo portInfo : vniPortMap.get(vni)) { + if (!portInfo.portName.equals(portName) && + !portInfo.hostIp.equals(hostIpAddress)) { + MacAddress vmMacx = getVmMacAddressForPort(portInfo.portName); + rulePopulator.populateForwardingRuleForOtherCnode(vni, + device.id(), portInfo.hostIp, portInfo.fixedIp, vmMacx, + tunnelPortMap.get(hostIpAddress).number(), + portInfo.deviceId, hostIpAddress, fixedIp, vmMac, + tunnelPortMap.get(portInfo.hostIp).number()); + } + } + } + } + + /** + * Populates the flow rules for traffic to VMs in the same Cnode as the sender. + * + * @param device device to put the rules + * @param port port info of the VM + */ + private void populateFlowRulesForTrafficToSameCnode(Device device, Port port) { + Ip4Prefix cidr = getCidrForPort(port.annotations().value("portName")); + Ip4Address vmIp = getFixedIpAddressForPort(port.annotations().value("portName")); + if (vmIp != null) { + rulePopulator.populateForwardingRule(vmIp, device.id(), port, cidr); + } + } + + /** + * Updates the port maps using the port information. + * + * @param device device info + * @param port port of the VM + */ + private void updatePortMaps(Device device, Port port) { + String portName = port.annotations().value("portName"); + String channelId = device.annotations().value("channelId"); + Ip4Address hostIpAddress = Ip4Address.valueOf(channelId.split(":")[0]); + if (portName.startsWith("vxlan")) { + tunnelPortMap.put(hostIpAddress, port); + } else { + String vni = getVniForPort(portName); + Ip4Address fixedIp = getFixedIpAddressForPort(portName); + if (vniPortMap.get(vni) == null) { + vniPortMap.put(vni, Lists.newArrayList()); + } + vniPortMap.get(vni).add(new PortInfo(device.id(), portName, fixedIp, hostIpAddress)); + } + } + + /** + * Returns CIDR information from the subnet map for the port. + * + * @param portName port name of the port of the VM + * @return CIDR of the VNI of the VM + */ + private Ip4Prefix getCidrForPort(String portName) { + String networkId = null; + String uuid = portName.substring(3); + OpenstackPort port = openstackPortMap.values().stream() + .filter(p -> p.id().startsWith(uuid)) + .findFirst().get(); + if (port == null) { + log.warn("No port information for port {}", portName); + return null; + } + + //OpenstackSubnet subnet = openstackSubnetMap.values().stream() + // .filter(s -> s.networkId().equals(port.networkId())) + // .findFirst().get(); + //if (subnet == null) { + // log.warn("No subnet information for network {}", subnet.id()); + // return null; + //} + + //return Ip4Prefix.valueOf(subnet.cidr()); + return null; + } + + /** + * Returns the VNI of the VM of the port. + * + * @param portName VM port + * @return VNI + */ + private String getVniForPort(String portName) { + String networkId = null; + String uuid = portName.substring(3); + OpenstackPort port = openstackPortMap.values().stream() + .filter(p -> p.id().startsWith(uuid)) + .findFirst().get(); + if (port == null) { + log.warn("No port information for port {}", portName); + return null; + } + OpenstackNetwork network = openstackNetworkMap.values().stream() + .filter(n -> n.id().equals(port.networkId())) + .findFirst().get(); + if (network == null) { + log.warn("No VNI information for network {}", network.id()); + return null; + } + + return network.segmentId(); + } + + /** + * Returns the Fixed IP address of the VM. + * + * @param portName VM port info + * @return IP address of the VM + */ + private Ip4Address getFixedIpAddressForPort(String portName) { + + // FIXME - For now we use the information stored from neutron Rest API call. + // TODO - Later, the information needs to be extracted from Neutron on-demand. + String uuid = portName.substring(3); + OpenstackPort port = openstackPortMap.values().stream() + .filter(p -> p.id().startsWith(uuid)) + .findFirst().get(); + + if (port == null) { + log.error("There is no port information for port name {}", portName); + return null; + } + + if (port.fixedIps().isEmpty()) { + log.error("There is no fixed IP info in the port information"); + return null; + } + + return (Ip4Address) port.fixedIps().values().toArray()[0]; + } + + /** + * Returns the MAC address of the VM of the port. + * + * @param portName VM port + * @return MAC address of the VM + */ + private MacAddress getVmMacAddressForPort(String portName) { + + String uuid = portName.substring(3); + OpenstackPort port = openstackPortMap.values().stream() + .filter(p -> p.id().startsWith(uuid)) + .findFirst().get(); + + if (port == null) { + log.error("There is no mac information for port name {}", portName); + return null; + } + + return port.macAddress(); + } + + private class InternalPacketProcessor implements PacketProcessor { + + @Override + public void process(PacketContext context) { + + if (context.isHandled()) { + return; + } + + InboundPacket pkt = context.inPacket(); + Ethernet ethernet = pkt.parsed(); + + if (ethernet.getEtherType() == Ethernet.TYPE_ARP) { + arpHandler.processPacketIn(pkt); + } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) { + IPv4 ipPacket = (IPv4) ethernet.getPayload(); + + if (ipPacket.getProtocol() == IPv4.PROTOCOL_UDP) { + UDP udpPacket = (UDP) ipPacket.getPayload(); + if (udpPacket.getDestinationPort() == DHCP_PORT) { + dhcpHandler.processPacketIn(pkt); + } + } + } + } + } + + private class InternalDeviceListener implements DeviceListener { + + @Override + public void event(DeviceEvent event) { + deviceEventExcutorService.execute(new InternalEventHandler(event)); + } + } + + private class InternalEventHandler implements Runnable { + + volatile DeviceEvent deviceEvent; + + InternalEventHandler(DeviceEvent deviceEvent) { + this.deviceEvent = deviceEvent; + } + + @Override + public void run() { + switch (deviceEvent.type()) { + case DEVICE_ADDED: + processDeviceAdded((Device) deviceEvent.subject()); + break; + case DEVICE_UPDATED: + Port port = (Port) deviceEvent.subject(); + if (port.isEnabled()) { + processPortAdded((Device) deviceEvent.subject(), deviceEvent.port()); + } + break; + case DEVICE_AVAILABILITY_CHANGED: + Device device = (Device) deviceEvent.subject(); + if (deviceService.isAvailable(device.id())) { + processDeviceAdded(device); + } + break; + case PORT_ADDED: + processPortAdded((Device) deviceEvent.subject(), deviceEvent.port()); + break; + case PORT_UPDATED: + processPortAdded((Device) deviceEvent.subject(), deviceEvent.port()); + break; + case PORT_REMOVED: + processPortRemoved((Device) deviceEvent.subject(), deviceEvent.port()); + break; + default: + break; + } + } + } + + private final class PortInfo { + DeviceId deviceId; + String portName; + Ip4Address fixedIp; + Ip4Address hostIp; + + private PortInfo(DeviceId deviceId, String portName, Ip4Address fixedIp, + Ip4Address hostIp) { + this.deviceId = deviceId; + this.portName = portName; + this.fixedIp = fixedIp; + this.hostIp = hostIp; + } + } + +}
\ No newline at end of file diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingRulePopulator.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingRulePopulator.java new file mode 100644 index 00000000..9ead05f0 --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingRulePopulator.java @@ -0,0 +1,228 @@ +/* +* 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.openstackswitching; + +import org.onlab.packet.Ethernet; +import org.onlab.packet.IPv4; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.Ip4Prefix; +import org.onlab.packet.MacAddress; +import org.onlab.packet.TpPort; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Port; +import org.onosproject.net.PortNumber; +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.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * It populates switching flow rules. + * + */ +public class OpenstackSwitchingRulePopulator { + + private static Logger log = LoggerFactory + .getLogger(OpenstackSwitchingRulePopulator.class); + + private FlowObjectiveService flowObjectiveService; + private ApplicationId appId; + + /** + * Creates OpenstackSwitchingRulPopulator. + * + * @param appId application id + * @param flowObjectiveService FlowObjectiveService reference + */ + public OpenstackSwitchingRulePopulator(ApplicationId appId, + FlowObjectiveService flowObjectiveService) { + this.flowObjectiveService = flowObjectiveService; + this.appId = appId; + } + + /** + * Populates flows rules for forwarding packets to and from VMs. + * + * @param ip v4 IP Address + * @param id device ID + * @param port port + * @param cidr v4 IP prefix + * @return true if it succeeds to populate rules, false otherwise. + */ + public boolean populateForwardingRule(Ip4Address ip, DeviceId id, Port port, Ip4Prefix cidr) { + + + setFlowRuleForVMsInSameCnode(ip, id, port, cidr); + + return true; + } + + /** + * Populates the common flows rules for all VMs. + * + * - Send ARP packets to the controller + * - Send DHCP packets to the controller + * + * @param id Device ID to populates rules to + */ + public void populateDefaultRules(DeviceId id) { + + //setFlowRuleForDHCP(id); + setFlowRuleForArp(id); + + log.warn("Default rule has been set"); + } + + /** + * Populates the forwarding rules for VMs with the same VNI but in other Code. + * + * @param vni VNI for the networks + * @param id device ID to populates the flow rules + * @param hostIp host IP address of the VM + * @param vmIp fixed IP address for the VM + * @param vmMac MAC address for the VM + * @param tunnelPort tunnel port number for the VM + * @param idx device ID for OVS of the other VM + * @param hostIpx host IP address of the other VM + * @param vmIpx fixed IP address of the other VM + * @param vmMacx MAC address for the other VM + * @param tunnelPortx x tunnel port number for other VM + */ + public void populateForwardingRuleForOtherCnode(String vni, DeviceId id, Ip4Address hostIp, + Ip4Address vmIp, MacAddress vmMac, PortNumber tunnelPort, + DeviceId idx, Ip4Address hostIpx, + Ip4Address vmIpx, MacAddress vmMacx, PortNumber tunnelPortx) { + setVxLanFlowRule(vni, id, hostIp, vmIp, vmMac, tunnelPort); + setVxLanFlowRule(vni, idx, hostIpx, vmIpx, vmMacx, tunnelPortx); + } + + /** + * Populates the flow rules for DHCP packets from VMs. + * + * @param id device ID to set the rules + */ + private void setFlowRuleForDHCP(DeviceId id) { + TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); + + sBuilder.matchEthType(Ethernet.TYPE_IPV4) + .matchIPProtocol(IPv4.PROTOCOL_UDP) + .matchUdpDst(TpPort.tpPort(OpenstackSwitchingManager.DHCP_PORT)); + tBuilder.setOutput(PortNumber.CONTROLLER); + + ForwardingObjective fo = DefaultForwardingObjective.builder() + .withSelector(sBuilder.build()) + .withTreatment(tBuilder.build()) + .withPriority(5000) + .withFlag(ForwardingObjective.Flag.VERSATILE) + .fromApp(appId) + .add(); + + flowObjectiveService.forward(id, fo); + } + + /** + * Populates the flow rules for ARP packets from VMs. + * + * @param id device ID to put rules. + */ + private void setFlowRuleForArp(DeviceId id) { + TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); + + sBuilder.matchEthType(Ethernet.TYPE_ARP); + tBuilder.setOutput(PortNumber.CONTROLLER); + + ForwardingObjective fo = DefaultForwardingObjective.builder() + .withSelector(sBuilder.build()) + .withTreatment(tBuilder.build()) + .withPriority(5000) + .withFlag(ForwardingObjective.Flag.VERSATILE) + .fromApp(appId) + .add(); + + flowObjectiveService.forward(id, fo); + } + + /** + * Sets the flow rules for traffic between VMs in the same Cnode. + * + * @param ip4Address VM IP address + * @param id device ID to put rules + * @param port VM port + * @param cidr subnet info of the VMs + */ + private void setFlowRuleForVMsInSameCnode(Ip4Address ip4Address, DeviceId id, + Port port, Ip4Prefix cidr) { + TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); + + sBuilder.matchEthType(Ethernet.TYPE_IPV4) + .matchIPDst(ip4Address.toIpPrefix()) + .matchIPSrc(cidr); + tBuilder.setOutput(port.number()); + + ForwardingObjective fo = DefaultForwardingObjective.builder() + .withSelector(sBuilder.build()) + .withTreatment(tBuilder.build()) + .withPriority(5000) + .withFlag(ForwardingObjective.Flag.VERSATILE) + .fromApp(appId) + .add(); + + flowObjectiveService.forward(id, fo); + } + + /** + * Sets the flow rules between traffic from VMs in different Cnode. + * + * @param vni VNI + * @param id device ID + * @param hostIp host IP of the VM + * @param vmIp fixed IP of the VM + * @param vmMac MAC address of the VM + * @param tunnelPort tunnel port to forward traffic to + */ + private void setVxLanFlowRule(String vni, DeviceId id, Ip4Address hostIp, + Ip4Address vmIp, MacAddress vmMac, PortNumber tunnelPort) { + TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); + + sBuilder.matchEthType(Ethernet.TYPE_IPV4) + .matchIPDst(vmIp.toIpPrefix()); + tBuilder.setTunnelId(Long.parseLong(vni)) + //.setTunnelDst() <- for Nicira ext + //.setEthDst(vmMac) + .setOutput(tunnelPort); + + ForwardingObjective fo = DefaultForwardingObjective.builder() + .withSelector(sBuilder.build()) + .withTreatment(tBuilder.build()) + .withPriority(5000) + .withFlag(ForwardingObjective.Flag.VERSATILE) + .fromApp(appId) + .add(); + + flowObjectiveService.forward(id, fo); + } +} diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingService.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingService.java new file mode 100644 index 00000000..d97b39c8 --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingService.java @@ -0,0 +1,49 @@ +/* + * 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.openstackswitching; + +/** + * It handles port management REST API from Openstack for VMs. + */ +public interface OpenstackSwitchingService { + + /** + * Store the port information created by Openstack. + * + * @param openstackPort port information + */ + void createPorts(OpenstackPort openstackPort); + + /** + * Removes flow rules corresponding to the port removed by Openstack. + * + */ + void deletePorts(); + + /** + * Updates flow rules corresponding to the port information updated by Openstack. + * + */ + void updatePorts(); + + /** + * Store the network information created by openstack. + * + * @param openstackNetwork network information + */ + void createNetwork(OpenstackNetwork openstackNetwork); + +} diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/package-info.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/package-info.java new file mode 100644 index 00000000..cd50f912 --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/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. + */ + +/** + * OpenStack switch interface. + */ +package org.onosproject.openstackswitching; diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkCodec.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkCodec.java new file mode 100644 index 00000000..43bd1583 --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkCodec.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.openstackswitching.web; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.onosproject.codec.CodecContext; +import org.onosproject.codec.JsonCodec; +import org.onosproject.openstackswitching.OpenstackNetwork; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Implementation of the OpenstackNetwork Codec. + * + */ +public class OpenstackNetworkCodec extends JsonCodec<OpenstackNetwork> { + + protected static final Logger log = LoggerFactory + .getLogger(OpenstackNetworkCodec.class); + + private static final String NETWORK = "network"; + private static final String NAME = "name"; + private static final String TENANT_ID = "tenant_id"; + private static final String SEGMENTATION_ID = "provider:segmentation_id"; + private static final String NETWORK_TYPE = "provider:network_type"; + private static final String ID = "id"; + + @Override + public OpenstackNetwork decode(ObjectNode json, CodecContext context) { + + JsonNode networkInfo = json.get(NETWORK); + + String name = networkInfo.path(NAME).asText(); + String tenantId = networkInfo.path(TENANT_ID).asText(); + String id = networkInfo.path(ID).asText(); + + OpenstackNetwork.Builder onb = OpenstackNetwork.builder(); + onb.name(name) + .tenantId(tenantId) + .id(id); + + if (!networkInfo.path(NETWORK_TYPE).isMissingNode()) { + onb.name(networkInfo.path(NETWORK_TYPE).asText()); + onb.segmentId(networkInfo.path(SEGMENTATION_ID).asText()); + } + + return onb.build(); + } + +} diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkWebResource.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkWebResource.java new file mode 100644 index 00000000..f4c401fb --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkWebResource.java @@ -0,0 +1,62 @@ +/* + * 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.openstackswitching.web; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.onosproject.openstackswitching.OpenstackNetwork; +import org.onosproject.openstackswitching.OpenstackSwitchingService; +import org.onosproject.rest.AbstractWebResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.InputStream; + +@Path("networks") +public class OpenstackNetworkWebResource extends AbstractWebResource { + + protected static final Logger log = LoggerFactory + .getLogger(OpenstackNetworkWebResource.class); + + private static final OpenstackNetworkCodec NETWORK_CODEC = new OpenstackNetworkCodec(); + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response createNetwork(InputStream input) { + try { + ObjectMapper mapper = new ObjectMapper(); + ObjectNode networkNode = (ObjectNode) mapper.readTree(input); + + OpenstackNetwork openstackNetwork = NETWORK_CODEC.decode(networkNode, this); + + OpenstackSwitchingService switchingService = get(OpenstackSwitchingService.class); + switchingService.createNetwork(openstackNetwork); + return Response.status(Response.Status.OK).build(); + } catch (Exception e) { + log.error("Creates VirtualPort failed because of exception {}", + e.toString()); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString()) + .build(); + } + } +} diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortCodec.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortCodec.java new file mode 100644 index 00000000..765b6901 --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortCodec.java @@ -0,0 +1,104 @@ +/* + * 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.openstackswitching.web; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.MacAddress; +import org.onosproject.codec.CodecContext; +import org.onosproject.codec.JsonCodec; +import org.onosproject.openstackswitching.OpenstackPort; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; + +/** + * It encodes and decodes the OpenstackPort. + */ +public class OpenstackPortCodec extends JsonCodec<OpenstackPort> { + + private static Logger log = LoggerFactory + .getLogger(OpenstackPortCodec.class); + + // JSON field names + private static final String PORT = "port"; + private static final String STATUS = "status"; + private static final String NAME = "name"; + private static final String ADDRESS_PAIR = "allowed_address_pairs"; + private static final String ADMIN_STATUS = "admin_status"; + private static final String NETWORK_ID = "network_id"; + private static final String TENANT_ID = "tenant_id"; + private static final String DEVICE_OWNER = "device_owner"; + private static final String MAC_ADDRESS = "mac_address"; + private static final String FIXED_IPS = "fixed_ips"; + private static final String SUBNET_ID = "subnet_id"; + private static final String IP_ADDRESS = "ip_address"; + private static final String ID = "id"; + private static final String SECURITY_GROUPS = "security_groups"; + private static final String DEVICE_ID = "device_id"; + + @Override + public OpenstackPort decode(ObjectNode json, CodecContext context) { + + HashMap<String, Ip4Address> fixedIpMap = new HashMap<>(); + JsonNode portInfo = json.get(PORT); + + String status = portInfo.path(STATUS).asText(); + String name = portInfo.path(NAME).asText(); + boolean adminStateUp = portInfo.path(ADMIN_STATUS).asBoolean(); + String networkId = portInfo.path(NETWORK_ID).asText(); + String tenantId = portInfo.path(TENANT_ID).asText(); + String deviceOwner = portInfo.path(DEVICE_OWNER).asText(); + String macStr = portInfo.path(MAC_ADDRESS).asText(); + ArrayNode fixedIpList = (ArrayNode) portInfo.path(FIXED_IPS); + for (JsonNode fixedIpInfo: fixedIpList) { + String subnetId = fixedIpInfo.path(SUBNET_ID).asText(); + String ipAddressStr = fixedIpInfo.path(IP_ADDRESS).asText(); + if (ipAddressStr != null) { + Ip4Address ipAddress = Ip4Address.valueOf(ipAddressStr); + fixedIpMap.put(subnetId, ipAddress); + } + } + String id = portInfo.path(ID).asText(); + String securityGroups = portInfo.path(SECURITY_GROUPS).asText(); + String deviceId = portInfo.path(DEVICE_ID).asText(); + + OpenstackPort.Builder openstackPortBuilder = OpenstackPort.builder(); + openstackPortBuilder.portStatus(OpenstackPort.PortStatus.valueOf(status)) + .name(name) + .adminState(adminStateUp) + .netwrokId(networkId) + .tenantId(tenantId) + .deviceOwner(deviceOwner) + .macAddress(MacAddress.valueOf(macStr)) + .fixedIps(fixedIpMap) + .id(id) + .deviceId(deviceId); + + // FIX ME + if (!securityGroups.isEmpty()) { + openstackPortBuilder.securityGroup(securityGroups); + } + + OpenstackPort openstackPort = openstackPortBuilder.build(); + + return openstackPort; + } + +} diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortWebResource.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortWebResource.java new file mode 100644 index 00000000..67a9cebb --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortWebResource.java @@ -0,0 +1,106 @@ +/* + * 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.openstackswitching.web; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.onosproject.openstackswitching.OpenstackPort; +import org.onosproject.openstackswitching.OpenstackSwitchingService; +import org.onosproject.rest.AbstractWebResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.InputStream; + +@Path("ports") +public class OpenstackPortWebResource extends AbstractWebResource { + + protected static final Logger log = LoggerFactory + .getLogger(OpenstackPortWebResource.class); + + private static final OpenstackPortCodec PORT_CODEC = new OpenstackPortCodec(); + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response createPorts(InputStream input) { + try { + ObjectMapper mapper = new ObjectMapper(); + ObjectNode portNode = (ObjectNode) mapper.readTree(input); + + OpenstackPort openstackPort = PORT_CODEC.decode(portNode, this); + + OpenstackSwitchingService switchingService = get(OpenstackSwitchingService.class); + switchingService.createPorts(openstackPort); + log.info("REST API ports is called with {}", portNode.toString()); + return Response.status(Response.Status.OK).build(); + } catch (Exception e) { + log.error("Creates VirtualPort failed because of exception {}", + e.toString()); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString()) + .build(); + } + } + + @DELETE + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response deletesPorts(InputStream input) { + try { + ObjectMapper mapper = new ObjectMapper(); + ObjectNode portNode = (ObjectNode) mapper.readTree(input); + + OpenstackSwitchingService switchingService = get(OpenstackSwitchingService.class); + switchingService.deletePorts(); + log.info("REST API ports is called with {}", portNode.toString()); + return Response.status(Response.Status.OK).build(); + } catch (Exception e) { + log.error("Delete VirtualPort failed because of exception {}", + e.toString()); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString()) + .build(); + } + } + + @PUT + @Path("{id}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response updatePorts(InputStream input) { + try { + ObjectMapper mapper = new ObjectMapper(); + ObjectNode portNode = (ObjectNode) mapper.readTree(input); + + OpenstackSwitchingService switchingService = get(OpenstackSwitchingService.class); + switchingService.updatePorts(); + log.info("REST API ports is called with {}", portNode.toString()); + return Response.status(Response.Status.OK).build(); + } catch (Exception e) { + log.error("Update VirtualPort failed because of exception {}", + e.toString()); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString()) + .build(); + } + } +} diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/package-info.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/package-info.java new file mode 100644 index 00000000..91e19c62 --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/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. + */ + +/** + * OpenStack switching REST API. + */ +package org.onosproject.openstackswitching.web; diff --git a/framework/src/onos/apps/openstackswitching/src/main/webapp/WEB-INF/web.xml b/framework/src/onos/apps/openstackswitching/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000..53b0e2e9 --- /dev/null +++ b/framework/src/onos/apps/openstackswitching/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>Openstack Switching 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.openstackswitching.web.OpenstackPortWebResource, + org.onosproject.openstackswitching.web.OpenstackNetworkWebResource + </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/framework/src/onos/apps/optical/src/main/java/org/onosproject/optical/OpticalPathProvisioner.java b/framework/src/onos/apps/optical/src/main/java/org/onosproject/optical/OpticalPathProvisioner.java index 8466b95e..e0545023 100644 --- a/framework/src/onos/apps/optical/src/main/java/org/onosproject/optical/OpticalPathProvisioner.java +++ b/framework/src/onos/apps/optical/src/main/java/org/onosproject/optical/OpticalPathProvisioner.java @@ -15,6 +15,7 @@ */ package org.onosproject.optical; +import com.google.common.collect.ImmutableList; import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Deactivate; @@ -45,16 +46,16 @@ import org.onosproject.net.intent.IntentState; import org.onosproject.net.intent.OpticalCircuitIntent; import org.onosproject.net.intent.OpticalConnectivityIntent; import org.onosproject.net.intent.PointToPointIntent; +import org.onosproject.net.newresource.ResourceAllocation; import org.onosproject.net.newresource.ResourceService; import org.onosproject.net.resource.device.IntentSetMultimap; -import org.onosproject.net.resource.link.LinkResourceAllocations; -import org.onosproject.net.resource.link.LinkResourceService; import org.onosproject.net.topology.LinkWeight; import org.onosproject.net.topology.PathService; import org.onosproject.net.topology.TopologyEdge; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; @@ -101,9 +102,6 @@ public class OpticalPathProvisioner { protected IntentSetMultimap intentSetMultimap; @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected LinkResourceService linkResourceService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected ResourceService resourceService; private ApplicationId appId; @@ -377,17 +375,17 @@ public class OpticalPathProvisioner { * @param intent the intent */ private void releaseResources(Intent intent) { - LinkResourceAllocations lra = linkResourceService.getAllocations(intent.id()); + Collection<ResourceAllocation> allocations = resourceService.getResourceAllocations(intent.id()); if (intent instanceof OpticalConnectivityIntent) { resourceService.release(intent.id()); - if (lra != null) { - linkResourceService.releaseResources(lra); + if (!allocations.isEmpty()) { + resourceService.release(ImmutableList.copyOf(allocations)); } } else if (intent instanceof OpticalCircuitIntent) { resourceService.release(intent.id()); intentSetMultimap.releaseMapping(intent.id()); - if (lra != null) { - linkResourceService.releaseResources(lra); + if (!allocations.isEmpty()) { + resourceService.release(ImmutableList.copyOf(allocations)); } } } diff --git a/framework/src/onos/apps/pom.xml b/framework/src/onos/apps/pom.xml index 98210736..005052fb 100644 --- a/framework/src/onos/apps/pom.xml +++ b/framework/src/onos/apps/pom.xml @@ -13,10 +13,7 @@ ~ 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. - --> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + --><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> @@ -60,6 +57,7 @@ <module>igmp</module> <module>pim</module> <module>mlb</module> + <module>openstackswitching</module> </modules> <properties> diff --git a/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java b/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java index b2ce0f8a..a27baaf9 100644 --- a/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java +++ b/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java @@ -15,8 +15,6 @@ */ package org.onosproject.sdnip; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; import org.onlab.packet.Ethernet; import org.onlab.packet.IPv4; import org.onlab.packet.IPv6; @@ -27,6 +25,8 @@ import org.onosproject.core.ApplicationId; import org.onosproject.incubator.net.intf.Interface; import org.onosproject.incubator.net.intf.InterfaceService; import org.onosproject.net.ConnectPoint; +import org.onosproject.net.config.NetworkConfigEvent; +import org.onosproject.net.config.NetworkConfigListener; import org.onosproject.net.config.NetworkConfigService; import org.onosproject.net.flow.DefaultTrafficSelector; import org.onosproject.net.flow.DefaultTrafficTreatment; @@ -43,7 +43,9 @@ import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import static com.google.common.base.Preconditions.checkNotNull; @@ -69,9 +71,10 @@ public class PeerConnectivityManager { private final ApplicationId appId; private final ApplicationId routerAppId; - // Just putting something random here for now. Figure out exactly what - // indexes we need when we start making use of them. - private final Multimap<BgpConfig.BgpSpeakerConfig, PointToPointIntent> peerIntents; + private final Map<Key, PointToPointIntent> peerIntents; + + private final InternalNetworkConfigListener configListener + = new InternalNetworkConfigListener(); /** * Creates a new PeerConnectivityManager. @@ -93,13 +96,14 @@ public class PeerConnectivityManager { this.routerAppId = routerAppId; this.interfaceService = interfaceService; - peerIntents = HashMultimap.create(); + peerIntents = new HashMap<>(); } /** * Starts the peer connectivity manager. */ public void start() { + configService.addListener(configListener); setUpConnectivity(); } @@ -107,6 +111,7 @@ public class PeerConnectivityManager { * Stops the peer connectivity manager. */ public void stop() { + configService.removeListener(configListener); } /** @@ -121,16 +126,27 @@ public class PeerConnectivityManager { return; } + Map<Key, PointToPointIntent> existingIntents = new HashMap<>(peerIntents); + for (BgpConfig.BgpSpeakerConfig bgpSpeaker : config.bgpSpeakers()) { log.debug("Start to set up BGP paths for BGP speaker: {}", bgpSpeaker); buildSpeakerIntents(bgpSpeaker).forEach(i -> { - peerIntents.put(bgpSpeaker, i); - intentSynchronizer.submit(i); + PointToPointIntent intent = existingIntents.remove(i.key()); + if (intent == null || !IntentUtils.equals(i, intent)) { + peerIntents.put(i.key(), i); + intentSynchronizer.submit(i); + } }); - } + + // Remove any remaining intents that we used to have that we don't need + // anymore + existingIntents.values().forEach(i -> { + peerIntents.remove(i.key()); + intentSynchronizer.withdraw(i); + }); } private Collection<PointToPointIntent> buildSpeakerIntents(BgpConfig.BgpSpeakerConfig speaker) { @@ -356,7 +372,7 @@ public class PeerConnectivityManager { * @param srcIp source IP address * @param dstIp destination IP address * @param suffix suffix string - * @return + * @return intent key */ private Key buildKey(IpAddress srcIp, IpAddress dstIp, String suffix) { String keyString = new StringBuilder() @@ -370,4 +386,26 @@ public class PeerConnectivityManager { return Key.of(keyString, appId); } + private class InternalNetworkConfigListener implements NetworkConfigListener { + + @Override + public void event(NetworkConfigEvent event) { + switch (event.type()) { + case CONFIG_REGISTERED: + break; + case CONFIG_UNREGISTERED: + break; + case CONFIG_ADDED: + case CONFIG_UPDATED: + case CONFIG_REMOVED: + if (event.configClass() == RoutingService.CONFIG_CLASS) { + setUpConnectivity(); + } + break; + default: + break; + } + } + } + } diff --git a/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java b/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java index c4b2daad..0dcc969d 100644 --- a/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java +++ b/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java @@ -34,6 +34,7 @@ import org.onosproject.incubator.net.intf.InterfaceService; import org.onosproject.net.ConnectPoint; import org.onosproject.net.DeviceId; import org.onosproject.net.PortNumber; +import org.onosproject.net.config.NetworkConfigListener; import org.onosproject.net.config.NetworkConfigService; import org.onosproject.net.flow.DefaultTrafficSelector; import org.onosproject.net.flow.DefaultTrafficTreatment; @@ -60,8 +61,10 @@ import java.util.Map; import java.util.Optional; import java.util.Set; +import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.expectLastCall; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.reset; import static org.easymock.EasyMock.verify; @@ -119,6 +122,8 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { routingConfig = createMock(RoutingConfigurationService.class); interfaceService = createMock(InterfaceService.class); networkConfigService = createMock(NetworkConfigService.class); + networkConfigService.addListener(anyObject(NetworkConfigListener.class)); + expectLastCall().anyTimes(); bgpConfig = createMock(BgpConfig.class); // These will set expectations on routingConfig and interfaceService diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java index f42f84b1..36563f01 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java @@ -35,7 +35,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.nio.ByteBuffer; -import java.util.List; +import java.util.Set; + import static com.google.common.base.Preconditions.checkNotNull; public class ArpHandler { @@ -112,7 +113,7 @@ public class ArpHandler { private boolean isArpReqForRouter(DeviceId deviceId, ARP arpRequest) { - List<Ip4Address> gatewayIpAddresses = config.getSubnetGatewayIps(deviceId); + Set<Ip4Address> gatewayIpAddresses = config.getPortIPs(deviceId); if (gatewayIpAddresses != null) { Ip4Address targetProtocolAddress = Ip4Address.valueOf(arpRequest .getTargetProtocolAddress()); diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java index 40ee55fc..c4a91c75 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java @@ -23,14 +23,12 @@ import org.onlab.packet.IpPrefix; import org.onosproject.net.Device; import org.onosproject.net.DeviceId; import org.onosproject.net.Link; -import org.onosproject.net.MastershipRole; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; -import java.util.List; import java.util.Set; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -97,7 +95,7 @@ public class DefaultRoutingHandler { log.debug("populateAllRoutingRules: populationStatus is STARTED"); for (Device sw : srManager.deviceService.getDevices()) { - if (srManager.mastershipService.getLocalRole(sw.id()) != MastershipRole.MASTER) { + if (!srManager.mastershipService.isLocalMaster(sw.id())) { log.debug("populateAllRoutingRules: skipping device {}...we are not master", sw.id()); continue; @@ -146,8 +144,7 @@ public class DefaultRoutingHandler { // Take the snapshots of the links updatedEcmpSpgMap = new HashMap<>(); for (Device sw : srManager.deviceService.getDevices()) { - if (srManager.mastershipService. - getLocalRole(sw.id()) != MastershipRole.MASTER) { + if (!srManager.mastershipService.isLocalMaster(sw.id())) { continue; } ECMPShortestPathGraph ecmpSpgUpdated = @@ -273,8 +270,7 @@ public class DefaultRoutingHandler { for (Device sw : srManager.deviceService.getDevices()) { log.debug("Computing the impacted routes for device {} due to link fail", sw.id()); - if (srManager.mastershipService. - getLocalRole(sw.id()) != MastershipRole.MASTER) { + if (!srManager.mastershipService.isLocalMaster(sw.id())) { continue; } ECMPShortestPathGraph ecmpSpg = currentEcmpSpgMap.get(sw.id()); @@ -320,8 +316,7 @@ public class DefaultRoutingHandler { for (Device sw : srManager.deviceService.getDevices()) { log.debug("Computing the impacted routes for device {}", sw.id()); - if (srManager.mastershipService. - getLocalRole(sw.id()) != MastershipRole.MASTER) { + if (!srManager.mastershipService.isLocalMaster(sw.id())) { log.debug("No mastership for {} and skip route optimization", sw.id()); continue; @@ -455,7 +450,7 @@ public class DefaultRoutingHandler { // If both target switch and dest switch are edge routers, then set IP // rule for both subnet and router IP. if (config.isEdgeDevice(targetSw) && config.isEdgeDevice(destSw)) { - List<Ip4Prefix> subnets = config.getSubnets(destSw); + Set<Ip4Prefix> subnets = config.getSubnets(destSw); log.debug("* populateEcmpRoutingRulePartial in device {} towards {} for subnets {}", targetSw, destSw, subnets); result = rulePopulator.populateIpRuleForSubnet(targetSw, @@ -499,14 +494,13 @@ public class DefaultRoutingHandler { } /** - * Populates table miss entries for all tables, and pipeline rules for VLAN - * and TCAM tables. XXX rename/rethink + * Populates filtering rules for permitting Router DstMac and VLAN. * * @param deviceId Switch ID to set the rules */ - public void populateTtpRules(DeviceId deviceId) { - rulePopulator.populateTableVlan(deviceId); - rulePopulator.populateTableTMac(deviceId); + public void populatePortAddressingRules(DeviceId deviceId) { + rulePopulator.populateRouterMacVlanFilters(deviceId); + rulePopulator.populateRouterIpPunts(deviceId); } /** diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java index 0bc155b8..828c51ce 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java @@ -15,6 +15,7 @@ */ package org.onosproject.segmentrouting; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import org.onlab.packet.Ip4Address; import org.onlab.packet.Ip4Prefix; @@ -38,20 +39,20 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; /** * Segment Routing configuration component that reads the * segment routing related configuration from Network Configuration Manager * component and organizes in more accessible formats. - * - * TODO: Merge multiple Segment Routing configuration wrapper classes into one. */ public class DeviceConfiguration implements DeviceProperties { private static final Logger log = LoggerFactory .getLogger(DeviceConfiguration.class); private final List<Integer> allSegmentIds = new ArrayList<>(); - private final HashMap<DeviceId, SegmentRouterInfo> deviceConfigMap = new HashMap<>(); + private final ConcurrentHashMap<DeviceId, SegmentRouterInfo> deviceConfigMap + = new ConcurrentHashMap<>(); private class SegmentRouterInfo { int nodeSid; @@ -126,18 +127,17 @@ public class DeviceConfiguration implements DeviceProperties { } /** - * Returns the segment id of a segment router. + * Returns the Node segment id of a segment router. * * @param deviceId device identifier * @return segment id */ @Override public int getSegmentId(DeviceId deviceId) { - if (deviceConfigMap.get(deviceId) != null) { - log.trace("getSegmentId for device{} is {}", - deviceId, - deviceConfigMap.get(deviceId).nodeSid); - return deviceConfigMap.get(deviceId).nodeSid; + SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); + if (srinfo != null) { + log.trace("getSegmentId for device{} is {}", deviceId, srinfo.nodeSid); + return srinfo.nodeSid; } else { log.warn("getSegmentId for device {} " + "throwing IllegalStateException " @@ -147,10 +147,10 @@ public class DeviceConfiguration implements DeviceProperties { } /** - * Returns the segment id of a segment router given its mac address. + * Returns the Node segment id of a segment router given its Router mac address. * * @param routerMac router mac address - * @return segment id + * @return node segment id, or -1 if not found in config */ public int getSegmentId(MacAddress routerMac) { for (Map.Entry<DeviceId, SegmentRouterInfo> entry: @@ -164,10 +164,10 @@ public class DeviceConfiguration implements DeviceProperties { } /** - * Returns the segment id of a segment router given its router ip address. + * Returns the Node segment id of a segment router given its Router ip address. * * @param routerAddress router ip address - * @return segment id + * @return node segment id, or -1 if not found in config */ public int getSegmentId(Ip4Address routerAddress) { for (Map.Entry<DeviceId, SegmentRouterInfo> entry: @@ -188,11 +188,10 @@ public class DeviceConfiguration implements DeviceProperties { */ @Override public MacAddress getDeviceMac(DeviceId deviceId) { - if (deviceConfigMap.get(deviceId) != null) { - log.trace("getDeviceMac for device{} is {}", - deviceId, - deviceConfigMap.get(deviceId).mac); - return deviceConfigMap.get(deviceId).mac; + SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); + if (srinfo != null) { + log.trace("getDeviceMac for device{} is {}", deviceId, srinfo.mac); + return srinfo.mac; } else { log.warn("getDeviceMac for device {} " + "throwing IllegalStateException " @@ -208,11 +207,10 @@ public class DeviceConfiguration implements DeviceProperties { * @return router ip address */ public Ip4Address getRouterIp(DeviceId deviceId) { - if (deviceConfigMap.get(deviceId) != null) { - log.trace("getDeviceIp for device{} is {}", - deviceId, - deviceConfigMap.get(deviceId).ip); - return deviceConfigMap.get(deviceId).ip; + SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); + if (srinfo != null) { + log.trace("getDeviceIp for device{} is {}", deviceId, srinfo.ip); + return srinfo.ip; } else { log.warn("getRouterIp for device {} " + "throwing IllegalStateException " @@ -223,18 +221,17 @@ public class DeviceConfiguration implements DeviceProperties { /** * Indicates if the segment router is a edge router or - * a transit/back bone router. + * a core/backbone router. * * @param deviceId device identifier * @return boolean */ @Override public boolean isEdgeDevice(DeviceId deviceId) { - if (deviceConfigMap.get(deviceId) != null) { - log.trace("isEdgeDevice for device{} is {}", - deviceId, - deviceConfigMap.get(deviceId).isEdge); - return deviceConfigMap.get(deviceId).isEdge; + SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); + if (srinfo != null) { + log.trace("isEdgeDevice for device{} is {}", deviceId, srinfo.isEdge); + return srinfo.isEdge; } else { log.warn("isEdgeDevice for device {} " + "throwing IllegalStateException " @@ -244,15 +241,35 @@ public class DeviceConfiguration implements DeviceProperties { } /** - * Returns the segment ids of all configured segment routers. + * Returns the node segment ids of all configured segment routers. * - * @return list of segment ids + * @return list of node segment ids */ @Override public List<Integer> getAllDeviceSegmentIds() { return allSegmentIds; } + @Override + public Map<Ip4Prefix, List<PortNumber>> getSubnetPortsMap(DeviceId deviceId) { + Map<Ip4Prefix, List<PortNumber>> subnetPortMap = new HashMap<>(); + + // Construct subnet-port mapping from port-subnet mapping + Map<PortNumber, Ip4Prefix> portSubnetMap = + this.deviceConfigMap.get(deviceId).subnets; + portSubnetMap.forEach((port, subnet) -> { + if (subnetPortMap.containsKey(subnet)) { + subnetPortMap.get(subnet).add(port); + } else { + ArrayList<PortNumber> ports = new ArrayList<>(); + ports.add(port); + subnetPortMap.put(subnet, ports); + } + }); + + return subnetPortMap; + } + /** * Returns the device identifier or data plane identifier (dpid) * of a segment router given its segment id. @@ -290,37 +307,68 @@ public class DeviceConfiguration implements DeviceProperties { } /** - * Returns the configured subnet gateway ip addresses for a segment router. + * Returns the configured port ip addresses for a segment router. + * These addresses serve as gateway IP addresses for the subnets configured + * on those ports. * * @param deviceId device identifier - * @return list of ip addresses + * @return immutable set of ip addresses configured on the ports or null if not found */ - public List<Ip4Address> getSubnetGatewayIps(DeviceId deviceId) { - if (deviceConfigMap.get(deviceId) != null) { - log.trace("getSubnetGatewayIps for device{} is {}", - deviceId, - deviceConfigMap.get(deviceId).gatewayIps.values()); - return new ArrayList<>(deviceConfigMap.get(deviceId).gatewayIps.values()); - } else { - return null; + public Set<Ip4Address> getPortIPs(DeviceId deviceId) { + SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); + if (srinfo != null) { + log.trace("getSubnetGatewayIps for device{} is {}", deviceId, + srinfo.gatewayIps.values()); + return ImmutableSet.copyOf(srinfo.gatewayIps.values()); + } + return null; + } + + /** + * Returns the configured IP addresses per port + * for a segment router. + * + * @param deviceId device identifier + * @return map of port to gateway IP addresses or null if not found + */ + public Map<PortNumber, Ip4Address> getPortIPMap(DeviceId deviceId) { + SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); + if (srinfo != null) { + return srinfo.gatewayIps; } + return null; } /** * Returns the configured subnet prefixes for a segment router. * * @param deviceId device identifier - * @return list of ip prefixes + * @return list of ip prefixes or null if not found */ - public List<Ip4Prefix> getSubnets(DeviceId deviceId) { - if (deviceConfigMap.get(deviceId) != null) { - log.trace("getSubnets for device{} is {}", - deviceId, - deviceConfigMap.get(deviceId).subnets.values()); - return new ArrayList<>(deviceConfigMap.get(deviceId).subnets.values()); - } else { - return null; + public Set<Ip4Prefix> getSubnets(DeviceId deviceId) { + SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); + if (srinfo != null) { + log.trace("getSubnets for device{} is {}", deviceId, + srinfo.subnets.values()); + return ImmutableSet.copyOf(srinfo.subnets.values()); } + return null; + } + + /** + * Returns the configured subnet on the given port, or null if no + * subnet has been configured on the port. + * + * @param deviceId device identifier + * @param pnum port identifier + * @return configured subnet on port, or null + */ + public Ip4Prefix getPortSubnet(DeviceId deviceId, PortNumber pnum) { + SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); + if (srinfo != null) { + return srinfo.subnets.get(pnum); + } + return null; } /** @@ -349,7 +397,7 @@ public class DeviceConfiguration implements DeviceProperties { * specified ip address as one of its subnet gateway ip address. * * @param gatewayIpAddress router gateway ip address - * @return router mac address + * @return router mac address or null if not found */ public MacAddress getRouterMacForAGatewayIp(Ip4Address gatewayIpAddress) { for (Map.Entry<DeviceId, SegmentRouterInfo> entry: @@ -377,7 +425,7 @@ public class DeviceConfiguration implements DeviceProperties { */ public boolean inSameSubnet(DeviceId deviceId, Ip4Address hostIp) { - List<Ip4Prefix> subnets = getSubnets(deviceId); + Set<Ip4Prefix> subnets = getSubnets(deviceId); if (subnets == null) { return false; } @@ -399,8 +447,9 @@ public class DeviceConfiguration implements DeviceProperties { * @return list of port numbers */ public List<Integer> getPortsForAdjacencySid(DeviceId deviceId, int sid) { - if (deviceConfigMap.get(deviceId) != null) { - for (AdjacencySid asid : deviceConfigMap.get(deviceId).adjacencySids) { + SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); + if (srinfo != null) { + for (AdjacencySid asid : srinfo.adjacencySids) { if (asid.getAsid() == sid) { return asid.getPorts(); } @@ -419,12 +468,13 @@ public class DeviceConfiguration implements DeviceProperties { * otherwise false */ public boolean isAdjacencySid(DeviceId deviceId, int sid) { - if (deviceConfigMap.get(deviceId) != null) { - if (deviceConfigMap.get(deviceId).adjacencySids.isEmpty()) { + SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); + if (srinfo != null) { + if (srinfo.adjacencySids.isEmpty()) { return false; } else { for (AdjacencySid asid: - deviceConfigMap.get(deviceId).adjacencySids) { + srinfo.adjacencySids) { if (asid.getAsid() == sid) { return true; } diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java index f65f03e0..b3916b06 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java @@ -32,7 +32,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.nio.ByteBuffer; -import java.util.List; +import java.util.Set; import static com.google.common.base.Preconditions.checkNotNull; @@ -70,7 +70,7 @@ public class IcmpHandler { DeviceId deviceId = connectPoint.deviceId(); Ip4Address destinationAddress = Ip4Address.valueOf(ipv4.getDestinationAddress()); - List<Ip4Address> gatewayIpAddresses = config.getSubnetGatewayIps(deviceId); + Set<Ip4Address> gatewayIpAddresses = config.getPortIPs(deviceId); Ip4Address routerIp = config.getRouterIp(deviceId); IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH); Ip4Address routerIpAddress = routerIpPrefix.getIp4Prefix().address(); diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java index 7641571d..d46028e7 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java @@ -25,6 +25,7 @@ import org.onlab.packet.VlanId; import org.onosproject.segmentrouting.grouphandler.NeighborSet; import org.onosproject.net.DeviceId; import org.onosproject.net.Link; +import org.onosproject.net.Port; import org.onosproject.net.PortNumber; import org.onosproject.net.flow.DefaultTrafficSelector; import org.onosproject.net.flow.DefaultTrafficTreatment; @@ -38,11 +39,13 @@ import org.onosproject.net.flowobjective.ForwardingObjective; import org.onosproject.net.flowobjective.Objective; import org.onosproject.net.flowobjective.ObjectiveError; import org.onosproject.net.flowobjective.ForwardingObjective.Builder; +import org.onosproject.net.flowobjective.ForwardingObjective.Flag; import org.onosproject.net.flowobjective.ObjectiveContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicLong; @@ -57,6 +60,11 @@ public class RoutingRulePopulator { private AtomicLong rulePopulationCounter; private SegmentRoutingManager srManager; private DeviceConfiguration config; + + private static final int HIGHEST_PRIORITY = 0xffff; + private static final long OFPP_MAX = 0xffffff00L; + + /** * Creates a RoutingRulePopulator object. * @@ -98,7 +106,7 @@ public class RoutingRulePopulator { TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); - sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, 32)); + sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, IpPrefix.MAX_INET_MASK_LENGTH)); sbuilder.matchEthType(Ethernet.TYPE_IPV4); tbuilder.deferred() @@ -134,7 +142,7 @@ public class RoutingRulePopulator { * @return true if all rules are set successfully, false otherwise */ public boolean populateIpRuleForSubnet(DeviceId deviceId, - List<Ip4Prefix> subnets, + Set<Ip4Prefix> subnets, DeviceId destSw, Set<DeviceId> nextHops) { @@ -350,40 +358,80 @@ public class RoutingRulePopulator { } /** - * Populates VLAN flows rules. All packets are forwarded to TMAC table. + * Creates a filtering objective to permit all untagged packets with a + * dstMac corresponding to the router's MAC address. For those pipelines + * that need to internally assign vlans to untagged packets, this method + * provides per-subnet vlan-ids as metadata. + * <p> + * Note that the vlan assignment is only done by the master-instance for a switch. + * However we send the filtering objective from slave-instances as well, so + * that drivers can obtain other information (like Router MAC and IP). * - * @param deviceId switch ID to set the rules + * @param deviceId the switch dpid for the router */ - public void populateTableVlan(DeviceId deviceId) { - FilteringObjective.Builder fob = DefaultFilteringObjective.builder(); - fob.withKey(Criteria.matchInPort(PortNumber.ALL)) + public void populateRouterMacVlanFilters(DeviceId deviceId) { + log.debug("Installing per-port filtering objective for untagged " + + "packets in device {}", deviceId); + for (Port port : srManager.deviceService.getPorts(deviceId)) { + if (port.number().toLong() > 0 && port.number().toLong() < OFPP_MAX) { + Ip4Prefix portSubnet = config.getPortSubnet(deviceId, port.number()); + VlanId assignedVlan = (portSubnet == null) + ? VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET) + : srManager.getSubnetAssignedVlanId(deviceId, portSubnet); + FilteringObjective.Builder fob = DefaultFilteringObjective.builder(); + fob.withKey(Criteria.matchInPort(port.number())) + .addCondition(Criteria.matchEthDst(config.getDeviceMac(deviceId))) .addCondition(Criteria.matchVlanId(VlanId.NONE)); - fob.permit().fromApp(srManager.appId); - log.debug("populateTableVlan: Installing filtering objective for untagged packets"); - srManager.flowObjectiveService. - filter(deviceId, - fob.add(new SRObjectiveContext(deviceId, - SRObjectiveContext.ObjectiveType.FILTER))); + // vlan assignment is valid only if this instance is master + if (srManager.mastershipService.isLocalMaster(deviceId)) { + TrafficTreatment tt = DefaultTrafficTreatment.builder() + .pushVlan().setVlanId(assignedVlan).build(); + fob.setMeta(tt); + } + fob.permit().fromApp(srManager.appId); + srManager.flowObjectiveService. + filter(deviceId, fob.add(new SRObjectiveContext(deviceId, + SRObjectiveContext.ObjectiveType.FILTER))); + } + } } /** - * Populates TMAC table rules. IP packets are forwarded to IP table. MPLS - * packets are forwarded to MPLS table. + * Creates a forwarding objective to punt all IP packets, destined to the + * router's port IP addresses, to the controller. Note that the input + * port should not be matched on, as these packets can come from any input. + * Furthermore, these are applied only by the master instance. * - * @param deviceId switch ID to set the rules + * @param deviceId the switch dpid for the router */ - public void populateTableTMac(DeviceId deviceId) { - - FilteringObjective.Builder fob = DefaultFilteringObjective.builder(); - fob.withKey(Criteria.matchInPort(PortNumber.ALL)) - .addCondition(Criteria.matchEthDst(config - .getDeviceMac(deviceId))); - fob.permit().fromApp(srManager.appId); - log.debug("populateTableTMac: Installing filtering objective for router mac"); - srManager.flowObjectiveService. - filter(deviceId, - fob.add(new SRObjectiveContext(deviceId, - SRObjectiveContext.ObjectiveType.FILTER))); + public void populateRouterIpPunts(DeviceId deviceId) { + if (!srManager.mastershipService.isLocalMaster(deviceId)) { + log.debug("Not installing port-IP punts - not the master for dev:{} ", + deviceId); + return; + } + ForwardingObjective.Builder puntIp = DefaultForwardingObjective.builder(); + Set<Ip4Address> allIps = new HashSet<Ip4Address>(config.getPortIPs(deviceId)); + allIps.add(config.getRouterIp(deviceId)); + for (Ip4Address ipaddr : allIps) { + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); + selector.matchEthType(Ethernet.TYPE_IPV4); + selector.matchIPDst(IpPrefix.valueOf(ipaddr, + IpPrefix.MAX_INET_MASK_LENGTH)); + treatment.setOutput(PortNumber.CONTROLLER); + puntIp.withSelector(selector.build()); + puntIp.withTreatment(treatment.build()); + puntIp.withFlag(Flag.VERSATILE) + .withPriority(HIGHEST_PRIORITY) + .makePermanent() + .fromApp(srManager.appId); + log.debug("Installing forwarding objective to punt port IP addresses"); + srManager.flowObjectiveService. + forward(deviceId, + puntIp.add(new SRObjectiveContext(deviceId, + SRObjectiveContext.ObjectiveType.FORWARDING))); + } } private PortNumber selectOnePort(DeviceId srcId, Set<DeviceId> destIds) { diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java index eb2cf569..9d60b279 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java @@ -22,11 +22,17 @@ 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.VlanId; import org.onlab.packet.IPv4; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.Ip4Prefix; +import org.onlab.packet.IpAddress; +import org.onlab.packet.IpPrefix; import org.onlab.util.KryoNamespace; import org.onosproject.core.ApplicationId; import org.onosproject.core.CoreService; import org.onosproject.event.Event; +import org.onosproject.net.ConnectPoint; import org.onosproject.net.config.ConfigFactory; import org.onosproject.net.config.NetworkConfigEvent; import org.onosproject.net.config.NetworkConfigRegistry; @@ -45,7 +51,6 @@ import org.onosproject.net.device.DeviceEvent; import org.onosproject.net.device.DeviceListener; import org.onosproject.net.device.DeviceService; import org.onosproject.net.flowobjective.FlowObjectiveService; -import org.onosproject.net.group.GroupKey; import org.onosproject.net.host.HostService; import org.onosproject.net.intent.IntentService; import org.onosproject.net.link.LinkEvent; @@ -56,6 +61,7 @@ import org.onosproject.net.packet.PacketContext; import org.onosproject.net.packet.PacketProcessor; import org.onosproject.net.packet.PacketService; import org.onosproject.net.topology.TopologyService; +import org.onosproject.segmentrouting.grouphandler.SubnetNextObjectiveStoreKey; import org.onosproject.store.service.EventuallyConsistentMap; import org.onosproject.store.service.EventuallyConsistentMapBuilder; import org.onosproject.store.service.StorageService; @@ -64,9 +70,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.URI; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executors; @@ -133,8 +141,13 @@ public class SegmentRoutingManager implements SegmentRoutingService { // Per device next objective ID store with (device id + neighbor set) as key private EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, Integer> nsNextObjStore = null; + private EventuallyConsistentMap<SubnetNextObjectiveStoreKey, Integer> subnetNextObjStore = null; private EventuallyConsistentMap<String, Tunnel> tunnelStore = null; private EventuallyConsistentMap<String, Policy> policyStore = null; + // Per device, per-subnet assigned-vlans store, with (device id + subnet + // IPv4 prefix) as key + private EventuallyConsistentMap<SubnetAssignedVidStoreKey, VlanId> + subnetVidStore = null; @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected StorageService storageService; @@ -163,6 +176,9 @@ public class SegmentRoutingManager implements SegmentRoutingService { private KryoNamespace.Builder kryoBuilder = null; + private static final short ASSIGNED_VLAN_START = 4093; + public static final short ASSIGNED_VLAN_NO_SUBNET = 4094; + @Activate protected void activate() { appId = coreService @@ -170,6 +186,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { kryoBuilder = new KryoNamespace.Builder() .register(NeighborSetNextObjectiveStoreKey.class, + SubnetNextObjectiveStoreKey.class, + SubnetAssignedVidStoreKey.class, NeighborSet.class, DeviceId.class, URI.class, @@ -180,7 +198,12 @@ public class SegmentRoutingManager implements SegmentRoutingService { DefaultTunnel.class, Policy.class, TunnelPolicy.class, - Policy.Type.class + Policy.Type.class, + VlanId.class, + Ip4Address.class, + Ip4Prefix.class, + IpAddress.Version.class, + ConnectPoint.class ); log.debug("Creating EC map nsnextobjectivestore"); @@ -194,6 +217,16 @@ public class SegmentRoutingManager implements SegmentRoutingService { .build(); log.trace("Current size {}", nsNextObjStore.size()); + log.debug("Creating EC map subnetnextobjectivestore"); + EventuallyConsistentMapBuilder<SubnetNextObjectiveStoreKey, Integer> + subnetNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder(); + + subnetNextObjStore = subnetNextObjMapBuilder + .withName("subnetnextobjectivestore") + .withSerializer(kryoBuilder) + .withTimestampProvider((k, v) -> new WallClockTimestamp()) + .build(); + EventuallyConsistentMapBuilder<String, Tunnel> tunnelMapBuilder = storageService.eventuallyConsistentMapBuilder(); @@ -212,6 +245,15 @@ public class SegmentRoutingManager implements SegmentRoutingService { .withTimestampProvider((k, v) -> new WallClockTimestamp()) .build(); + EventuallyConsistentMapBuilder<SubnetAssignedVidStoreKey, VlanId> + subnetVidStoreMapBuilder = storageService.eventuallyConsistentMapBuilder(); + + subnetVidStore = subnetVidStoreMapBuilder + .withName("subnetvidstore") + .withSerializer(kryoBuilder) + .withTimestampProvider((k, v) -> new WallClockTimestamp()) + .build(); + cfgService.addListener(cfgListener); cfgService.registerConfigFactory(cfgFactory); @@ -296,23 +338,72 @@ public class SegmentRoutingManager implements SegmentRoutingService { } /** - * Returns the GroupKey object for the device and the NeighborSet given. - * XXX is this called + * Returns the vlan-id assigned to the subnet configured for a device. + * If no vlan-id has been assigned, a new one is assigned out of a pool of ids, + * if and only if this controller instance is the master for the device. + * <p> + * USAGE: The assigned vlans are meant to be applied to untagged packets on those + * switches/pipelines that need this functionality. These vids are meant + * to be used internally within a switch, and thus need to be unique only + * on a switch level. Note that packets never go out on the wire with these + * vlans. Currently, vlan ids are assigned from value 4093 down. + * Vlan id 4094 expected to be used for all ports that are not assigned subnets. + * Vlan id 4095 is reserved and unused. Only a single vlan id is assigned + * per subnet. + * XXX This method should avoid any vlans configured on the ports, but + * currently the app works only on untagged packets and as a result + * ignores any vlan configuration. * - * @param ns NeightborSet object for the GroupKey - * @return GroupKey object for the NeighborSet + * @param deviceId switch dpid + * @param subnet IPv4 prefix for which assigned vlan is desired + * @return VlanId assigned for the subnet on the device, or + * null if no vlan assignment was found and this instance is not + * the master for the device. */ - public GroupKey getGroupKey(NeighborSet ns) { - for (DefaultGroupHandler groupHandler : groupHandlerMap.values()) { - return groupHandler.getGroupKey(ns); + public VlanId getSubnetAssignedVlanId(DeviceId deviceId, Ip4Prefix subnet) { + VlanId assignedVid = subnetVidStore.get(new SubnetAssignedVidStoreKey( + deviceId, subnet)); + if (assignedVid != null) { + log.debug("Query for subnet:{} on device:{} returned assigned-vlan " + + "{}", subnet, deviceId, assignedVid); + return assignedVid; + } + //check mastership for the right to assign a vlan + if (!mastershipService.isLocalMaster(deviceId)) { + log.warn("This controller instance is not the master for device {}. " + + "Cannot assign vlan-id for subnet {}", deviceId, subnet); + return null; + } + // vlan assignment is expensive but done only once + Set<Ip4Prefix> configuredSubnets = deviceConfiguration.getSubnets(deviceId); + Set<Short> assignedVlans = new HashSet<>(); + Set<Ip4Prefix> unassignedSubnets = new HashSet<>(); + for (Ip4Prefix sub : configuredSubnets) { + VlanId v = subnetVidStore.get(new SubnetAssignedVidStoreKey(deviceId, + sub)); + if (v != null) { + assignedVlans.add(v.toShort()); + } else { + unassignedSubnets.add(sub); + } + } + short nextAssignedVlan = ASSIGNED_VLAN_START; + if (!assignedVlans.isEmpty()) { + nextAssignedVlan = (short) (Collections.min(assignedVlans) - 1); + } + for (Ip4Prefix unsub : unassignedSubnets) { + subnetVidStore.put(new SubnetAssignedVidStoreKey(deviceId, unsub), + VlanId.vlanId(nextAssignedVlan--)); + log.info("Assigned vlan: {} to subnet: {} on device: {}", + nextAssignedVlan + 1, unsub, deviceId); } - return null; + return subnetVidStore.get(new SubnetAssignedVidStoreKey(deviceId, subnet)); } /** - * Returns the next objective ID for the NeighborSet given. If the nextObjectiveID does not exist, - * a new one is created and returned. + * Returns the next objective ID for the given NeighborSet. + * If the nextObjectiveID does not exist, a new one is created and returned. * * @param deviceId Device ID * @param ns NegighborSet @@ -329,6 +420,25 @@ public class SegmentRoutingManager implements SegmentRoutingService { } } + /** + * Returns the next objective ID for the Subnet given. If the nextObjectiveID does not exist, + * a new one is created and returned. + * + * @param deviceId Device ID + * @param prefix Subnet + * @return next objective ID + */ + public int getSubnetNextObjectiveId(DeviceId deviceId, IpPrefix prefix) { + if (groupHandlerMap.get(deviceId) != null) { + log.trace("getSubnetNextObjectiveId query in device {}", deviceId); + return groupHandlerMap + .get(deviceId).getSubnetNextObjectiveId(prefix); + } else { + log.warn("getSubnetNextObjectiveId query in device {} not found", deviceId); + return -1; + } + } + private class InternalPacketProcessor implements PacketProcessor { @Override public void process(PacketContext context) { @@ -423,6 +533,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED || event.type() == DeviceEvent.Type.DEVICE_UPDATED) { if (deviceService.isAvailable(((Device) event.subject()).id())) { + log.info("Processing device event {} for available device {}", + event.type(), ((Device) event.subject()).id()); processDeviceAdded((Device) event.subject()); } } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) { @@ -484,20 +596,31 @@ public class SegmentRoutingManager implements SegmentRoutingService { private void processDeviceAdded(Device device) { log.debug("A new device with ID {} was added", device.id()); - //Irrespective whether the local is a MASTER or not for this device, - //create group handler instance and push default TTP flow rules. - //Because in a multi-instance setup, instances can initiate - //groups for any devices. Also the default TTP rules are needed - //to be pushed before inserting any IP table entries for any device - DefaultGroupHandler dgh = DefaultGroupHandler. + // Irrespective of whether the local is a MASTER or not for this device, + // we need to create a SR-group-handler instance. This is because in a + // multi-instance setup, any instance can initiate forwarding/next-objectives + // for any switch (even if this instance is a SLAVE or not even connected + // to the switch). To handle this, a default-group-handler instance is necessary + // per switch. + DefaultGroupHandler groupHandler = DefaultGroupHandler. createGroupHandler(device.id(), appId, deviceConfiguration, linkService, flowObjectiveService, - nsNextObjStore); - groupHandlerMap.put(device.id(), dgh); - defaultRoutingHandler.populateTtpRules(device.id()); + nsNextObjStore, + subnetNextObjStore); + groupHandlerMap.put(device.id(), groupHandler); + + // Also, in some cases, drivers may need extra + // information to process rules (eg. Router IP/MAC); and so, we send + // port addressing rules to the driver as well irrespective of whether + // this instance is the master or not. + defaultRoutingHandler.populatePortAddressingRules(device.id()); + + if (mastershipService.isLocalMaster(device.id())) { + groupHandler.createGroupsFromSubnetConfig(); + } } private void processPortRemoved(Device device, Port port) { @@ -531,18 +654,29 @@ public class SegmentRoutingManager implements SegmentRoutingService { tunnelHandler, policyStore); for (Device device : deviceService.getDevices()) { - //Irrespective whether the local is a MASTER or not for this device, - //create group handler instance and push default TTP flow rules. - //Because in a multi-instance setup, instances can initiate - //groups for any devices. Also the default TTP rules are needed - //to be pushed before inserting any IP table entries for any device + // Irrespective of whether the local is a MASTER or not for this device, + // we need to create a SR-group-handler instance. This is because in a + // multi-instance setup, any instance can initiate forwarding/next-objectives + // for any switch (even if this instance is a SLAVE or not even connected + // to the switch). To handle this, a default-group-handler instance is necessary + // per switch. DefaultGroupHandler groupHandler = DefaultGroupHandler .createGroupHandler(device.id(), appId, deviceConfiguration, linkService, flowObjectiveService, - nsNextObjStore); + nsNextObjStore, + subnetNextObjStore); groupHandlerMap.put(device.id(), groupHandler); - defaultRoutingHandler.populateTtpRules(device.id()); + + // Also, in some cases, drivers may need extra + // information to process rules (eg. Router IP/MAC); and so, we send + // port addressing rules to the driver as well, irrespective of whether + // this instance is the master or not. + defaultRoutingHandler.populatePortAddressingRules(device.id()); + + if (mastershipService.isLocalMaster(device.id())) { + groupHandler.createGroupsFromSubnetConfig(); + } } defaultRoutingHandler.startPopulationProcess(); diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SubnetAssignedVidStoreKey.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SubnetAssignedVidStoreKey.java new file mode 100644 index 00000000..84b44c97 --- /dev/null +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SubnetAssignedVidStoreKey.java @@ -0,0 +1,66 @@ +package org.onosproject.segmentrouting; + +import java.util.Objects; + +import org.onlab.packet.Ip4Prefix; +import org.onosproject.net.DeviceId; + +/** + * Class definition for key used to map per device subnets to assigned Vlan ids. + * + */ +public class SubnetAssignedVidStoreKey { + private final DeviceId deviceId; + private final Ip4Prefix subnet; + + public SubnetAssignedVidStoreKey(DeviceId deviceId, Ip4Prefix subnet) { + this.deviceId = deviceId; + this.subnet = subnet; + } + + /** + * Returns the device identification used to create this key. + * + * @return the device identifier + */ + public DeviceId deviceId() { + return deviceId; + } + + /** + * Returns the subnet information used to create this key. + * + * @return the subnet + */ + public Ip4Prefix subnet() { + return subnet; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof SubnetAssignedVidStoreKey)) { + return false; + } + SubnetAssignedVidStoreKey that = + (SubnetAssignedVidStoreKey) o; + return (Objects.equals(this.deviceId, that.deviceId) && + Objects.equals(this.subnet, that.subnet)); + } + + @Override + public int hashCode() { + int result = 17; + result = 31 * result + Objects.hashCode(deviceId) + + Objects.hashCode(subnet); + return result; + } + + @Override + public String toString() { + return "Device: " + deviceId + " Subnet: " + subnet; + } + +} diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java index c960adca..a5c1090f 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java @@ -52,9 +52,12 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { LinkService linkService, FlowObjectiveService flowObjService, EventuallyConsistentMap< - NeighborSetNextObjectiveStoreKey, - Integer> nsNextObjStore) { - super(deviceId, appId, config, linkService, flowObjService, nsNextObjStore); + NeighborSetNextObjectiveStoreKey, + Integer> nsNextObjStore, + EventuallyConsistentMap<SubnetNextObjectiveStoreKey, + Integer> subnetNextObjStore) { + super(deviceId, appId, config, linkService, flowObjService, + nsNextObjStore, subnetNextObjStore); } @Override diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java index 9bbde2f3..69a0d86f 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java @@ -25,10 +25,11 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Random; import java.util.Set; import java.util.stream.Collectors; +import org.onlab.packet.Ip4Prefix; +import org.onlab.packet.IpPrefix; import org.onlab.packet.MacAddress; import org.onlab.packet.MplsLabel; import org.onlab.util.KryoNamespace; @@ -74,7 +75,8 @@ public class DefaultGroupHandler { // new HashMap<NeighborSet, Integer>(); protected EventuallyConsistentMap< NeighborSetNextObjectiveStoreKey, Integer> nsNextObjStore = null; - protected Random rand = new Random(); + protected EventuallyConsistentMap< + SubnetNextObjectiveStoreKey, Integer> subnetNextObjStore = null; protected KryoNamespace.Builder kryo = new KryoNamespace.Builder() .register(URI.class).register(HashSet.class) @@ -89,8 +91,10 @@ public class DefaultGroupHandler { LinkService linkService, FlowObjectiveService flowObjService, EventuallyConsistentMap< - NeighborSetNextObjectiveStoreKey, - Integer> nsNextObjStore) { + NeighborSetNextObjectiveStoreKey, + Integer> nsNextObjStore, + EventuallyConsistentMap<SubnetNextObjectiveStoreKey, + Integer> subnetNextObjStore) { this.deviceId = checkNotNull(deviceId); this.appId = checkNotNull(appId); this.deviceConfig = checkNotNull(config); @@ -101,6 +105,7 @@ public class DefaultGroupHandler { nodeMacAddr = checkNotNull(config.getDeviceMac(deviceId)); this.flowObjectiveService = flowObjService; this.nsNextObjStore = nsNextObjStore; + this.subnetNextObjStore = subnetNextObjStore; populateNeighborMaps(); } @@ -115,7 +120,8 @@ public class DefaultGroupHandler { * @param config interface to retrieve the device properties * @param linkService link service object * @param flowObjService flow objective service object - * @param nsNextObjStore next objective store map + * @param nsNextObjStore NeighborSet next objective store map + * @param subnetNextObjStore subnet next objective store map * @return default group handler type */ public static DefaultGroupHandler createGroupHandler(DeviceId deviceId, @@ -123,18 +129,23 @@ public class DefaultGroupHandler { DeviceProperties config, LinkService linkService, FlowObjectiveService flowObjService, - EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, - Integer> nsNextObjStore) { + EventuallyConsistentMap< + NeighborSetNextObjectiveStoreKey, + Integer> nsNextObjStore, + EventuallyConsistentMap<SubnetNextObjectiveStoreKey, + Integer> subnetNextObjStore) { if (config.isEdgeDevice(deviceId)) { return new DefaultEdgeGroupHandler(deviceId, appId, config, linkService, flowObjService, - nsNextObjStore); + nsNextObjStore, + subnetNextObjStore); } else { return new DefaultTransitGroupHandler(deviceId, appId, config, linkService, flowObjService, - nsNextObjStore); + nsNextObjStore, + subnetNextObjStore); } } @@ -323,6 +334,21 @@ public class DefaultGroupHandler { } /** + * Returns the next objective associated with the subnet. + * If there is no next objective for this subnet, this API + * would create a next objective and return. + * + * @param prefix subnet information + * @return int if found or -1 + */ + public int getSubnetNextObjectiveId(IpPrefix prefix) { + Integer nextId = subnetNextObjStore. + get(new SubnetNextObjectiveStoreKey(deviceId, prefix)); + + return (nextId != null) ? nextId : -1; + } + + /** * Checks if the next objective ID (group) for the neighbor set exists or not. * * @param ns neighbor set to check @@ -486,6 +512,43 @@ public class DefaultGroupHandler { } } + public void createGroupsFromSubnetConfig() { + Map<Ip4Prefix, List<PortNumber>> subnetPortMap = + this.deviceConfig.getSubnetPortsMap(this.deviceId); + + // Construct a broadcast group for each subnet + subnetPortMap.forEach((subnet, ports) -> { + SubnetNextObjectiveStoreKey key = + new SubnetNextObjectiveStoreKey(deviceId, subnet); + + if (subnetNextObjStore.containsKey(key)) { + log.debug("Broadcast group for device {} and subnet {} exists", + deviceId, subnet); + return; + } + + int nextId = flowObjectiveService.allocateNextId(); + + NextObjective.Builder nextObjBuilder = DefaultNextObjective + .builder().withId(nextId) + .withType(NextObjective.Type.BROADCAST).fromApp(appId); + + ports.forEach(port -> { + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); + tBuilder.setOutput(port); + nextObjBuilder.addTreatment(tBuilder.build()); + }); + + NextObjective nextObj = nextObjBuilder.add(); + flowObjectiveService.next(deviceId, nextObj); + log.debug("createGroupFromSubnetConfig: Submited " + + "next objective {} in device {}", + nextId, deviceId); + + subnetNextObjStore.put(key, nextId); + }); + } + public GroupKey getGroupKey(Object obj) { return new DefaultGroupKey(kryo.build().serialize(obj)); } diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java index 3cb73aba..b009e869 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java @@ -45,9 +45,12 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { LinkService linkService, FlowObjectiveService flowObjService, EventuallyConsistentMap< - NeighborSetNextObjectiveStoreKey, - Integer> nsNextObjStore) { - super(deviceId, appId, config, linkService, flowObjService, nsNextObjStore); + NeighborSetNextObjectiveStoreKey, + Integer> nsNextObjStore, + EventuallyConsistentMap<SubnetNextObjectiveStoreKey, + Integer> subnetNextObjStore) { + super(deviceId, appId, config, linkService, flowObjService, + nsNextObjStore, subnetNextObjStore); } @Override diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DeviceProperties.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DeviceProperties.java index 497f5256..d28d38d5 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DeviceProperties.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DeviceProperties.java @@ -16,9 +16,12 @@ package org.onosproject.segmentrouting.grouphandler; import java.util.List; +import java.util.Map; +import org.onlab.packet.Ip4Prefix; import org.onlab.packet.MacAddress; import org.onosproject.net.DeviceId; +import org.onosproject.net.PortNumber; /** * Mechanism through which group handler module retrieves @@ -33,6 +36,7 @@ public interface DeviceProperties { * @return segment id of a device */ int getSegmentId(DeviceId deviceId); + /** * Returns the Mac address of a device to be used in group creation. * @@ -40,6 +44,7 @@ public interface DeviceProperties { * @return mac address of a device */ MacAddress getDeviceMac(DeviceId deviceId); + /** * Indicates whether a device is edge device or transit/core device. * @@ -47,6 +52,7 @@ public interface DeviceProperties { * @return boolean */ boolean isEdgeDevice(DeviceId deviceId); + /** * Returns all segment IDs to be considered in building auto * @@ -54,4 +60,16 @@ public interface DeviceProperties { * @return list of segment IDs */ List<Integer> getAllDeviceSegmentIds(); + + /** + * Returns subnet-to-ports mapping of given device. + * + * For each entry of the map + * Key: a subnet + * Value: a list of ports, which are bound to the subnet + * + * @param deviceId device identifier + * @return a map that contains all subnet-to-ports mapping of given device + */ + Map<Ip4Prefix, List<PortNumber>> getSubnetPortsMap(DeviceId deviceId); } diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java index e7e87839..e47a6625 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java @@ -54,7 +54,8 @@ public class PolicyGroupHandler extends DefaultGroupHandler { * @param config interface to retrieve the device properties * @param linkService link service object * @param flowObjService flow objective service object - * @param nsNextObjStore next objective store map + * @param nsNextObjStore NeighborSet next objective store map + * @param subnetNextObjStore subnet next objective store map */ public PolicyGroupHandler(DeviceId deviceId, ApplicationId appId, @@ -62,8 +63,11 @@ public class PolicyGroupHandler extends DefaultGroupHandler { LinkService linkService, FlowObjectiveService flowObjService, EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, - Integer> nsNextObjStore) { - super(deviceId, appId, config, linkService, flowObjService, nsNextObjStore); + Integer> nsNextObjStore, + EventuallyConsistentMap<SubnetNextObjectiveStoreKey, + Integer> subnetNextObjStore) { + super(deviceId, appId, config, linkService, flowObjService, + nsNextObjStore, subnetNextObjStore); } public PolicyGroupIdentifier createPolicyGroupChain(String id, diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/SubnetNextObjectiveStoreKey.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/SubnetNextObjectiveStoreKey.java new file mode 100644 index 00000000..d6b16c7a --- /dev/null +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/SubnetNextObjectiveStoreKey.java @@ -0,0 +1,78 @@ +/* + * Copyright 2014-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.segmentrouting.grouphandler; + +import org.onlab.packet.IpPrefix; +import org.onosproject.net.DeviceId; + +import java.util.Objects; + +/** + * Class definition of Key for Subnet to NextObjective store. + */ +public class SubnetNextObjectiveStoreKey { + private final DeviceId deviceId; + private final IpPrefix prefix; + + public SubnetNextObjectiveStoreKey(DeviceId deviceId, + IpPrefix prefix) { + this.deviceId = deviceId; + this.prefix = prefix; + } + + /** + * Gets device id in this SubnetNextObjectiveStoreKey. + * + * @return device id + */ + public DeviceId deviceId() { + return this.deviceId; + } + + /** + * Gets subnet information in this SubnetNextObjectiveStoreKey. + * + * @return subnet information + */ + public IpPrefix prefix() { + return this.prefix; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof SubnetNextObjectiveStoreKey)) { + return false; + } + SubnetNextObjectiveStoreKey that = + (SubnetNextObjectiveStoreKey) o; + return (Objects.equals(this.deviceId, that.deviceId) && + Objects.equals(this.prefix, that.prefix)); + } + + @Override + public int hashCode() { + return Objects.hash(deviceId, prefix); + } + + @Override + public String toString() { + return "Device: " + deviceId + " Subnet: " + prefix; + } +} diff --git a/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestAddCommand.java b/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestAddCommand.java index 204471c2..2d1aa0b8 100644 --- a/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestAddCommand.java +++ b/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestAddCommand.java @@ -23,7 +23,7 @@ import org.onosproject.store.serializers.KryoNamespaces; import org.onosproject.store.service.Serializer; import org.onosproject.store.service.StorageService; -import java.util.HashSet; +import java.util.Arrays; import java.util.Set; /** @@ -44,7 +44,6 @@ public class SetTestAddCommand extends AbstractShellCommand { String[] values = null; Set<String> set; - Set<String> toAdd = new HashSet<>(); Serializer serializer = Serializer.using( @@ -68,13 +67,10 @@ public class SetTestAddCommand extends AbstractShellCommand { } } else if (values.length >= 1) { // Add multiple elements to a set - for (String value : values) { - toAdd.add(value); - } - if (set.addAll(toAdd)) { - print("%s was added to the set %s", toAdd, setName); + if (set.addAll(Arrays.asList(values))) { + print("%s was added to the set %s", Arrays.asList(values), setName); } else { - print("%s was already in set %s", toAdd, setName); + print("%s was already in set %s", Arrays.asList(values), setName); } } } diff --git a/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestGetCommand.java b/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestGetCommand.java index fb36a06a..74c52c16 100644 --- a/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestGetCommand.java +++ b/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestGetCommand.java @@ -24,7 +24,7 @@ import org.onosproject.store.serializers.KryoNamespaces; import org.onosproject.store.service.Serializer; import org.onosproject.store.service.StorageService; -import java.util.HashSet; +import java.util.Arrays; import java.util.Set; /** @@ -49,7 +49,6 @@ public class SetTestGetCommand extends AbstractShellCommand { String[] values = null; Set<String> set; - Set<String> toCheck = new HashSet<>(); String output = ""; Serializer serializer = Serializer.using( @@ -95,13 +94,10 @@ public class SetTestGetCommand extends AbstractShellCommand { } } else if (values.length > 1) { //containsAll - for (String value : values) { - toCheck.add(value); - } - if (set.containsAll(toCheck)) { - print("Set %s contains the the subset %s", setName, toCheck); + if (set.containsAll(Arrays.asList(values))) { + print("Set %s contains the the subset %s", setName, Arrays.asList(values)); } else { - print("Set %s did not contain the the subset %s", setName, toCheck); + print("Set %s did not contain the the subset %s", setName, Arrays.asList(values)); } } } diff --git a/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestRemoveCommand.java b/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestRemoveCommand.java index d1f81e42..1fa073f3 100644 --- a/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestRemoveCommand.java +++ b/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestRemoveCommand.java @@ -24,7 +24,7 @@ import org.onosproject.store.serializers.KryoNamespaces; import org.onosproject.store.service.Serializer; import org.onosproject.store.service.StorageService; -import java.util.HashSet; +import java.util.Arrays; import java.util.Set; /** @@ -54,7 +54,6 @@ public class SetTestRemoveCommand extends AbstractShellCommand { String[] values = null; Set<String> set; - Set<String> givenValues = new HashSet<>(); Serializer serializer = Serializer.using( new KryoNamespace.Builder().register(KryoNamespaces.BASIC).build()); @@ -79,13 +78,10 @@ public class SetTestRemoveCommand extends AbstractShellCommand { } if (retain) { // Keep only the given values - for (String value : values) { - givenValues.add(value); - } - if (set.retainAll(givenValues)) { - print("%s was pruned to contain only elements of set %s", setName, givenValues); + if (set.retainAll(Arrays.asList(values))) { + print("%s was pruned to contain only elements of set %s", setName, Arrays.asList(values)); } else { - print("%s was not changed by retaining only elements of the set %s", setName, givenValues); + print("%s was not changed by retaining only elements of the set %s", setName, Arrays.asList(values)); } } else if (values.length == 1) { // Remove a single element from the set @@ -94,15 +90,12 @@ public class SetTestRemoveCommand extends AbstractShellCommand { } else { print("[%s] was not in set %s", values[0], setName); } - } else if (values.length >= 1) { + } else if (values.length > 1) { // Remove multiple elements from a set - for (String value : values) { - givenValues.add(value); - } - if (set.removeAll(givenValues)) { - print("%s was removed from the set %s", givenValues, setName); + if (set.removeAll(Arrays.asList(values))) { + print("%s was removed from the set %s", Arrays.asList(values), setName); } else { - print("No element of %s was in set %s", givenValues, setName); + print("No element of %s was in set %s", Arrays.asList(values), setName); } } } diff --git a/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/ConnectPointConfiguration.java b/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/ConnectPointConfiguration.java new file mode 100644 index 00000000..ff516d71 --- /dev/null +++ b/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/ConnectPointConfiguration.java @@ -0,0 +1,55 @@ +/* + * 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.virtualbng; + +import org.onosproject.net.ConnectPoint; + +/** + * Configuration for a connect point. + */ +public class ConnectPointConfiguration { + + private ConnectPoint connectPoint; + + /** + * Creats a new connect point from a string representation. + * + * @param string connect point string + */ + public ConnectPointConfiguration(String string) { + connectPoint = ConnectPoint.deviceConnectPoint(string); + } + + /** + * Creates a new connect point from a string representation. + * + * @param string connect point string + * @return new connect point configuration + */ + public static ConnectPointConfiguration of(String string) { + return new ConnectPointConfiguration(string); + } + + /** + * Gets the connect point. + * + * @return connect point + */ + public ConnectPoint connectPoint() { + return connectPoint; + } +} diff --git a/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfiguration.java b/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfiguration.java index ee2cbeaa..1841675f 100644 --- a/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfiguration.java +++ b/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfiguration.java @@ -17,13 +17,15 @@ package org.onosproject.virtualbng; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.Collections; -import java.util.List; - import org.onlab.packet.IpAddress; import org.onlab.packet.IpPrefix; import org.onlab.packet.MacAddress; +import org.onosproject.net.ConnectPoint; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; /** * Contains the configuration data for virtual BNG that has been read from a @@ -36,6 +38,7 @@ public final class VbngConfiguration { private final MacAddress publicFacingMac; private final IpAddress xosIpAddress; private final int xosRestPort; + private final Map<String, ConnectPointConfiguration> hosts; /** * Default constructor. @@ -46,6 +49,7 @@ public final class VbngConfiguration { publicFacingMac = null; xosIpAddress = null; xosRestPort = 0; + hosts = null; } /** @@ -57,6 +61,7 @@ public final class VbngConfiguration { * public IP addresses * @param xosIpAddress the XOS server IP address * @param xosRestPort the port of the XOS server for REST + * @param hosts map of hosts */ @JsonCreator public VbngConfiguration(@JsonProperty("localPublicIpPrefixes") @@ -68,12 +73,15 @@ public final class VbngConfiguration { @JsonProperty("xosIpAddress") IpAddress xosIpAddress, @JsonProperty("xosRestPort") - int xosRestPort) { + int xosRestPort, + @JsonProperty("hosts") + Map<String, ConnectPointConfiguration> hosts) { localPublicIpPrefixes = prefixes; this.nextHopIpAddress = nextHopIpAddress; this.publicFacingMac = publicFacingMac; this.xosIpAddress = xosIpAddress; this.xosRestPort = xosRestPort; + this.hosts = hosts; } /** @@ -120,4 +128,13 @@ public final class VbngConfiguration { public int getXosRestPort() { return xosRestPort; } + + public Map<String, ConnectPoint> getHosts() { + return hosts.entrySet() + .stream() + .collect(Collectors.toMap( + e -> e.getKey(), + e -> e.getValue().connectPoint() + )); + } } diff --git a/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfigurationManager.java b/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfigurationManager.java index d27d6904..eb83e06c 100644 --- a/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfigurationManager.java +++ b/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfigurationManager.java @@ -16,16 +16,6 @@ package org.onosproject.virtualbng; import com.fasterxml.jackson.databind.ObjectMapper; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.Collections; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.concurrent.ConcurrentHashMap; - import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Deactivate; @@ -33,9 +23,19 @@ import org.apache.felix.scr.annotations.Service; import org.onlab.packet.IpAddress; import org.onlab.packet.IpPrefix; import org.onlab.packet.MacAddress; +import org.onosproject.net.ConnectPoint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; + /** * Implementation of ConfigurationService which reads virtual BNG * configuration from a file. @@ -63,6 +63,7 @@ public class VbngConfigurationManager implements VbngConfigurationService { private MacAddress macOfPublicIpAddresses; private IpAddress xosIpAddress; private int xosRestPort; + private Map<String, ConnectPoint> nodeToPort; @Activate public void activate() { @@ -104,6 +105,8 @@ public class VbngConfigurationManager implements VbngConfigurationService { macOfPublicIpAddresses = config.getPublicFacingMac(); xosIpAddress = config.getXosIpAddress(); xosRestPort = config.getXosRestPort(); + nodeToPort = config.getHosts(); + } catch (FileNotFoundException e) { log.warn("Configuration file not found: {}", configFileName); @@ -132,6 +135,11 @@ public class VbngConfigurationManager implements VbngConfigurationService { return xosRestPort; } + @Override + public Map<String, ConnectPoint> getNodeToPort() { + return nodeToPort; + } + // TODO handle the case: the number of public IP addresses is not enough // for 1:1 mapping from public IP to private IP. @Override diff --git a/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfigurationService.java b/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfigurationService.java index ef8698a0..68c048f4 100644 --- a/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfigurationService.java +++ b/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfigurationService.java @@ -15,10 +15,11 @@ */ package org.onosproject.virtualbng; -import java.util.Map; - import org.onlab.packet.IpAddress; import org.onlab.packet.MacAddress; +import org.onosproject.net.ConnectPoint; + +import java.util.Map; /** * Provides information about the virtual BNG configuration. @@ -54,6 +55,13 @@ public interface VbngConfigurationService { int getXosRestPort(); /** + * Gets the host to port map. + * + * @return host to port map + */ + Map<String, ConnectPoint> getNodeToPort(); + + /** * Evaluates whether an IP address is an assigned public IP address. * * @param ipAddress the IP address to evaluate diff --git a/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngManager.java b/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngManager.java index 5e82b7e8..e03b25e8 100644 --- a/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngManager.java +++ b/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngManager.java @@ -15,18 +15,9 @@ */ package org.onosproject.virtualbng; -import static com.google.common.base.Preconditions.checkNotNull; - import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; -import com.google.common.collect.Maps; - -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.concurrent.ConcurrentHashMap; - import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Deactivate; @@ -42,7 +33,6 @@ import org.onosproject.core.CoreService; import org.onosproject.net.ConnectPoint; import org.onosproject.net.DeviceId; import org.onosproject.net.Host; -import org.onosproject.net.PortNumber; import org.onosproject.net.flow.DefaultTrafficSelector; import org.onosproject.net.flow.DefaultTrafficTreatment; import org.onosproject.net.flow.TrafficSelector; @@ -56,6 +46,13 @@ import org.onosproject.net.intent.PointToPointIntent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; + +import static com.google.common.base.Preconditions.checkNotNull; + /** * This is a virtual Broadband Network Gateway (BNG) application. It mainly * has 3 functions: @@ -111,9 +108,8 @@ public class VbngManager implements VbngService { p2pIntentsToHost = new ConcurrentHashMap<>(); privateIpAddressMap = new ConcurrentHashMap<>(); - setupMap(); - nextHopIpAddress = vbngConfigurationService.getNextHopIpAddress(); + nodeToPort = vbngConfigurationService.getNodeToPort(); hostListener = new InternalHostListener(); hostService.addListener(hostListener); @@ -136,10 +132,16 @@ public class VbngManager implements VbngService { */ private void statusRecovery() { log.info("vBNG starts to recover from XOS record......"); - RestClient restClient = - new RestClient(vbngConfigurationService.getXosIpAddress(), - vbngConfigurationService.getXosRestPort()); - ObjectNode map = restClient.getRest(); + ObjectNode map; + try { + RestClient restClient = + new RestClient(vbngConfigurationService.getXosIpAddress(), + vbngConfigurationService.getXosRestPort()); + map = restClient.getRest(); + } catch (Exception e) { + log.error("Could not contact XOS", e); + return; + } if (map == null) { log.info("Stop to recover vBNG status due to the vBNG map " + "is null!"); @@ -168,21 +170,6 @@ public class VbngManager implements VbngService { } /** - * Sets up mapping from hostname to connect point. - */ - private void setupMap() { - nodeToPort = Maps.newHashMap(); - - nodeToPort.put("cordcompute01.onlab.us", - new ConnectPoint(FABRIC_DEVICE_ID, - PortNumber.portNumber(48))); - - nodeToPort.put("cordcompute02.onlab.us", - new ConnectPoint(FABRIC_DEVICE_ID, - PortNumber.portNumber(47))); - } - - /** * Creates a new vBNG. * * @param privateIpAddress a private IP address diff --git a/framework/src/onos/apps/vtn/pom.xml b/framework/src/onos/apps/vtn/pom.xml index c2cfe2be..e91b0c9b 100644 --- a/framework/src/onos/apps/vtn/pom.xml +++ b/framework/src/onos/apps/vtn/pom.xml @@ -37,4 +37,21 @@ <module>vtnweb</module> <module>app</module> </modules> + <dependencies> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onlab-junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava-testlib</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.easymock</groupId> + <artifactId>easymock</artifactId> + <scope>test</scope> + </dependency> + </dependencies> </project> diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/SfcService.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/SfcService.java new file mode 100644 index 00000000..a2748f5e --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/SfcService.java @@ -0,0 +1,52 @@ +/* + * 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.sfc; + +import org.onosproject.vtnrsc.PortChain; + +/** + * SFC application that applies flows to the device. + */ +public interface SfcService { + /** + * Applies flow classification to OVS. + * + * @param portChain Port-Chain. + */ + void InstallFlowClassification(PortChain portChain); + + + /** + * Remove flow classification from OVS. + * + * @param portChain Port-Chain. + */ + void UnInstallFlowClassification(PortChain portChain); + + /** + * Applies Service Function chain to OVS. + * + * @param portChain Port-Chain. + */ + void InstallServiceFunctionChain(PortChain portChain); + + /** + * Remove Service Function chain from OVS. + * + * @param portChain Port-Chain. + */ + void UnInstallServiceFunctionChain(PortChain portChain); +} diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/impl/SfcManager.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/impl/SfcManager.java new file mode 100644 index 00000000..1872295f --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/impl/SfcManager.java @@ -0,0 +1,69 @@ +/* + * 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.sfc.impl; + +import static org.slf4j.LoggerFactory.getLogger; + +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.Service; +import org.onosproject.vtnrsc.sfc.PortChain; +import org.slf4j.Logger; + +/** + * Provides implementation of SFC Service. + */ +@Component(immediate = true) +@Service +public class SfcManager implements SfcService { + + private final Logger log = getLogger(SfcManager.class); + + @Activate + public void activate() { + log.info("Started"); + } + + @Deactivate + public void deactivate() { + log.info("Stopped"); + } + + @Override + public void InstallFlowClassification(PortChain portChain) { + log.debug("InstallFlowClassification"); + //TODO: Installation of flow classification into OVS. + } + + @Override + public void UnInstallFlowClassification(PortChain portChain) { + log.debug("UnInstallFlowClassification"); + //TODO: Un-installation flow classification from OVS + } + + @Override + public void InstallServiceFunctionChain(PortChain portChain) { + log.debug("InstallServiceFunctionChain"); + //TODO: Installation of Service Function chain into OVS. + } + + @Override + public void UnInstallServiceFunctionChain(PortChain portChain) { + log.debug("UnInstallServiceFunctionChain"); + //TODO: Un-installation of Service Function chain from OVS. + } +} diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/impl/package-info.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/impl/package-info.java new file mode 100644 index 00000000..0dba868c --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/impl/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. + */ + +/** + * SFC Service manager for interacting with SFC. + */ +package org.onosproject.sfc.impl; diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/package-info.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/package-info.java new file mode 100644 index 00000000..1dcb9929 --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/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 interacting with SFC. + */ +package org.onosproject.sfc; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultFlowClassifier.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultFlowClassifier.java new file mode 100644 index 00000000..39df2cff --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultFlowClassifier.java @@ -0,0 +1,413 @@ +/* + * 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.vtnrsc; + +import java.util.Objects; +import org.onlab.packet.IpPrefix; + +import com.google.common.base.MoreObjects; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Provides Default flow classifier. + */ +public final class DefaultFlowClassifier implements FlowClassifier { + + private final FlowClassifierId flowClassifierId; + private final TenantId tenantId; + private final String name; + private final String description; + private final String etherType; + private final String protocol; + private final int minSrcPortRange; + private final int maxSrcPortRange; + private final int minDstPortRange; + private final int maxDstPortRange; + private final IpPrefix srcIpPrefix; + private final IpPrefix dstIpPrefix; + private final VirtualPortId srcPort; + private final VirtualPortId dstPort; + private static final int NULL_PORT = 0; + private static final String FLOW_CLASSIFIER_ID_NOT_NULL = "FlowClassifier id can not be null."; + private static final String TENANT_ID_NOT_NULL = "Tenant id can not be null."; + + /** + * Constructor to create default flow classifier. + * + * @param flowClassifierId flow classifier Id + * @param tenantId Tenant ID + * @param name flow classifier name + * @param description flow classifier description + * @param etherType etherType + * @param protocol IP protocol + * @param minSrcPortRange Minimum Source port range + * @param maxSrcPortRange Maximum Source port range + * @param minDstPortRange Minimum destination port range + * @param maxDstPortRange Maximum destination port range + * @param srcIpPrefix Source IP prefix + * @param dstIpPrefix destination IP prefix + * @param srcPort Source VirtualPort + * @param dstPort destination VirtualPort + */ + private DefaultFlowClassifier(FlowClassifierId flowClassifierId, TenantId tenantId, String name, + String description, String etherType, String protocol, int minSrcPortRange, int maxSrcPortRange, + int minDstPortRange, int maxDstPortRange, IpPrefix srcIpPrefix, IpPrefix dstIpPrefix, + VirtualPortId srcPort, VirtualPortId dstPort) { + this.flowClassifierId = flowClassifierId; + this.tenantId = tenantId; + this.name = name; + this.description = description; + this.etherType = etherType; + this.protocol = protocol; + this.minSrcPortRange = minSrcPortRange; + this.maxSrcPortRange = maxSrcPortRange; + this.minDstPortRange = minDstPortRange; + this.maxDstPortRange = maxDstPortRange; + this.srcIpPrefix = srcIpPrefix; + this.dstIpPrefix = dstIpPrefix; + this.srcPort = srcPort; + this.dstPort = dstPort; + } + + @Override + public FlowClassifierId flowClassifierId() { + return flowClassifierId; + } + + @Override + public TenantId tenantId() { + return tenantId; + } + + @Override + public String name() { + return name; + } + + @Override + public String description() { + return description; + } + + @Override + public String etherType() { + return etherType; + } + + @Override + public String protocol() { + return protocol; + } + + @Override + public int minSrcPortRange() { + return minSrcPortRange; + } + + @Override + public int maxSrcPortRange() { + return maxSrcPortRange; + } + + @Override + public int minDstPortRange() { + return minDstPortRange; + } + + @Override + public int maxDstPortRange() { + return maxDstPortRange; + } + + @Override + public IpPrefix srcIpPrefix() { + return srcIpPrefix; + } + + @Override + public IpPrefix dstIpPrefix() { + return dstIpPrefix; + } + + @Override + public VirtualPortId srcPort() { + return srcPort; + } + + @Override + public VirtualPortId dstPort() { + return dstPort; + } + + /** + * Builder class for constructing Flow classifier. + */ + public static class Builder implements FlowClassifier.Builder { + + private FlowClassifierId flowClassifierId; + private TenantId tenantId; + private String name; + private boolean isFlowClassifierNameSet = false; + private String description; + private boolean isFlowClassifierDescriptionSet = false; + private String etherType; + private boolean isEtherTypeSet = false; + private String protocol; + private boolean isProtocolSet = false; + private int minSrcPortRange; + private boolean isMinSrcPortRangeSet = false; + private int maxSrcPortRange; + private boolean isMaxSrcPortRangeSet = false; + private int minDstPortRange; + private boolean isMinDstPortRangeSet = false; + private int maxDstPortRange; + private boolean isMaxDstPortRangeSet = false; + private IpPrefix srcIpPrefix; + private boolean isSrcIpPrefixSet = false; + private IpPrefix dstIpPrefix; + private boolean isDstIpPrefixSet = false; + private VirtualPortId srcPort; + private boolean isSrcPortSet = false; + private VirtualPortId dstPort; + private boolean isDstPortSet = false; + + @Override + public FlowClassifier build() { + + checkNotNull(flowClassifierId, FLOW_CLASSIFIER_ID_NOT_NULL); + checkNotNull(tenantId, TENANT_ID_NOT_NULL); + String name = null; + String description = null; + String etherType = null; + String protocol = null; + int minSrcPortRange = NULL_PORT; + int maxSrcPortRange = NULL_PORT; + int minDstPortRange = NULL_PORT; + int maxDstPortRange = NULL_PORT; + IpPrefix srcIpPrefix = null; + IpPrefix dstIpPrefix = null; + VirtualPortId srcPort = null; + VirtualPortId dstPort = null; + + if (isFlowClassifierNameSet) { + name = this.name; + } + if (isFlowClassifierDescriptionSet) { + description = this.description; + } + if (isEtherTypeSet) { + etherType = this.etherType; + } + if (isProtocolSet) { + protocol = this.protocol; + } + if (isMinSrcPortRangeSet) { + minSrcPortRange = this.minSrcPortRange; + } + if (isMaxSrcPortRangeSet) { + maxSrcPortRange = this.maxSrcPortRange; + } + if (isMinDstPortRangeSet) { + minDstPortRange = this.minDstPortRange; + } + if (isMaxDstPortRangeSet) { + maxDstPortRange = this.maxDstPortRange; + } + if (isSrcIpPrefixSet) { + srcIpPrefix = this.srcIpPrefix; + } + if (isDstIpPrefixSet) { + dstIpPrefix = this.dstIpPrefix; + } + if (isSrcPortSet) { + srcPort = this.srcPort; + } + if (isDstPortSet) { + dstPort = this.dstPort; + } + + return new DefaultFlowClassifier(flowClassifierId, tenantId, name, description, etherType, protocol, + minSrcPortRange, maxSrcPortRange, minDstPortRange, maxDstPortRange, srcIpPrefix, dstIpPrefix, + srcPort, dstPort); + } + + @Override + public Builder setFlowClassifierId(FlowClassifierId flowClassifierId) { + this.flowClassifierId = flowClassifierId; + return this; + } + + @Override + public Builder setTenantId(TenantId tenantId) { + this.tenantId = tenantId; + return this; + } + + @Override + public Builder setName(String name) { + this.name = name; + this.isFlowClassifierNameSet = true; + return this; + } + + @Override + public Builder setDescription(String description) { + this.description = description; + this.isFlowClassifierDescriptionSet = true; + return this; + } + + @Override + public Builder setEtherType(String etherType) { + this.etherType = etherType; + this.isEtherTypeSet = true; + return this; + } + + @Override + public Builder setProtocol(String protocol) { + this.protocol = protocol; + this.isProtocolSet = true; + return this; + } + + @Override + public Builder setMinSrcPortRange(int minSrcPortRange) { + this.minSrcPortRange = minSrcPortRange; + this.isMinSrcPortRangeSet = true; + return this; + } + + @Override + public Builder setMaxSrcPortRange(int maxSrcPortRange) { + this.maxSrcPortRange = maxSrcPortRange; + this.isMaxSrcPortRangeSet = true; + return this; + } + + @Override + public Builder setMinDstPortRange(int minDstPortRange) { + this.minDstPortRange = minDstPortRange; + this.isMinDstPortRangeSet = true; + return this; + } + + @Override + public Builder setMaxDstPortRange(int maxDstPortRange) { + this.maxDstPortRange = maxDstPortRange; + this.isMaxDstPortRangeSet = true; + return this; + } + + @Override + public Builder setSrcIpPrefix(IpPrefix srcIpPrefix) { + this.srcIpPrefix = srcIpPrefix; + this.isSrcIpPrefixSet = true; + return this; + } + + @Override + public Builder setDstIpPrefix(IpPrefix dstIpPrefix) { + this.dstIpPrefix = dstIpPrefix; + this.isDstIpPrefixSet = true; + return this; + } + + @Override + public Builder setSrcPort(VirtualPortId srcPort) { + this.srcPort = srcPort; + this.isSrcPortSet = true; + return this; + } + + @Override + public Builder setDstPort(VirtualPortId dstPort) { + this.dstPort = dstPort; + this.isDstPortSet = true; + return this; + } + } + + @Override + public int hashCode() { + return Objects.hash(flowClassifierId, tenantId, name, description, etherType, protocol, minSrcPortRange, + maxSrcPortRange, minDstPortRange, maxDstPortRange, srcIpPrefix, dstIpPrefix, srcPort, dstPort); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultFlowClassifier) { + DefaultFlowClassifier other = (DefaultFlowClassifier) obj; + return Objects.equals(this.flowClassifierId, other.flowClassifierId) + && Objects.equals(this.tenantId, other.tenantId) + && Objects.equals(this.name, other.name) + && Objects.equals(this.description, other.description) + && Objects.equals(this.etherType, other.etherType) + && Objects.equals(this.protocol, other.protocol) + && Objects.equals(this.minSrcPortRange, other.minSrcPortRange) + && Objects.equals(this.maxSrcPortRange, other.maxSrcPortRange) + && Objects.equals(this.minDstPortRange, other.minDstPortRange) + && Objects.equals(this.maxDstPortRange, other.maxDstPortRange) + && Objects.equals(this.srcIpPrefix, other.srcIpPrefix) + && Objects.equals(this.dstIpPrefix, other.dstIpPrefix) + && Objects.equals(this.srcPort, other.srcPort) + && Objects.equals(this.dstPort, other.dstPort); + } + return false; + } + + @Override + public boolean exactMatch(FlowClassifier flowClassifier) { + return this.equals(flowClassifier) + && Objects.equals(this.flowClassifierId, flowClassifier.flowClassifierId()) + && Objects.equals(this.tenantId, flowClassifier.tenantId()) + && Objects.equals(this.name, flowClassifier.name()) + && Objects.equals(this.description, flowClassifier.description()) + && Objects.equals(this.etherType, flowClassifier.etherType()) + && Objects.equals(this.protocol, flowClassifier.protocol()) + && Objects.equals(this.minSrcPortRange, flowClassifier.minSrcPortRange()) + && Objects.equals(this.maxSrcPortRange, flowClassifier.maxSrcPortRange()) + && Objects.equals(this.minDstPortRange, flowClassifier.minDstPortRange()) + && Objects.equals(this.maxDstPortRange, flowClassifier.maxDstPortRange()) + && Objects.equals(this.srcIpPrefix, flowClassifier.srcIpPrefix()) + && Objects.equals(this.dstIpPrefix, flowClassifier.dstIpPrefix()) + && Objects.equals(this.srcPort, flowClassifier.srcPort()) + && Objects.equals(this.dstPort, flowClassifier.dstPort()); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("FlowClassifierId", flowClassifierId) + .add("TenantId", tenantId) + .add("Name", name) + .add("Description", description) + .add("String", etherType) + .add("Protocol", protocol) + .add("MinSrcPortRange", minSrcPortRange) + .add("MaxSrcPortRange", maxSrcPortRange) + .add("MinDstPortRange", minDstPortRange) + .add("MaxDstPortRange", maxDstPortRange) + .add("SrcIpPrefix", srcIpPrefix) + .add("DstIpPrefix", dstIpPrefix) + .add("SrcPort", srcPort) + .add("DstPort", dstPort) + .toString(); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortChain.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortChain.java new file mode 100644 index 00000000..89b94b3e --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortChain.java @@ -0,0 +1,201 @@ +/* + * 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.vtnrsc; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.List; +import java.util.Objects; + +import com.google.common.collect.ImmutableList; + +/** + * Implementation of port chain. + */ +public final class DefaultPortChain implements PortChain { + + private final PortChainId portChainId; + private final TenantId tenantId; + private final String name; + private final String description; + private final List<PortPairGroupId> portPairGroupList; + private final List<FlowClassifierId> flowClassifierList; + + /** + * Default constructor to create port chain. + * + * @param portChainId port chain id + * @param tenantId tenant id + * @param name name of port chain + * @param description description of port chain + * @param portPairGroupList port pair group list + * @param flowClassifierList flow classifier list + */ + private DefaultPortChain(PortChainId portChainId, TenantId tenantId, + String name, String description, + List<PortPairGroupId> portPairGroupList, + List<FlowClassifierId> flowClassifierList) { + + this.portChainId = portChainId; + this.tenantId = tenantId; + this.name = name; + this.description = description; + this.portPairGroupList = portPairGroupList; + this.flowClassifierList = flowClassifierList; + } + + @Override + public PortChainId portChainId() { + return portChainId; + } + + @Override + public TenantId tenantId() { + return tenantId; + } + + @Override + public String name() { + return name; + } + + @Override + public String description() { + return description; + } + + @Override + public List<PortPairGroupId> portPairGroups() { + return ImmutableList.copyOf(portPairGroupList); + } + + @Override + public List<FlowClassifierId> flowClassifiers() { + return ImmutableList.copyOf(flowClassifierList); + } + + @Override + public int hashCode() { + return Objects.hash(portChainId, tenantId, name, description, + portPairGroupList, flowClassifierList); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultPortChain) { + DefaultPortChain that = (DefaultPortChain) obj; + return Objects.equals(portChainId, that.portChainId) && + Objects.equals(tenantId, that.tenantId) && + Objects.equals(name, that.name) && + Objects.equals(description, that.description) && + Objects.equals(portPairGroupList, that.portPairGroupList) && + Objects.equals(flowClassifierList, that.flowClassifierList); + } + return false; + } + + @Override + public boolean exactMatch(PortChain portChain) { + return this.equals(portChain) && + Objects.equals(this.portChainId, portChain.portChainId()) && + Objects.equals(this.tenantId, portChain.tenantId()); + } + + @Override + public String toString() { + return toStringHelper(this) + .add("id", portChainId.toString()) + .add("tenantId", tenantId.toString()) + .add("name", name) + .add("description", description) + .add("portPairGroupList", portPairGroupList) + .add("flowClassifier", flowClassifierList) + .toString(); + } + + /** + * To create an instance of the builder. + * + * @return instance of builder + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Builder class for Port chain. + */ + public static final class Builder implements PortChain.Builder { + + private PortChainId portChainId; + private TenantId tenantId; + private String name; + private String description; + private List<PortPairGroupId> portPairGroupList; + private List<FlowClassifierId> flowClassifierList; + + @Override + public Builder setId(PortChainId portChainId) { + this.portChainId = portChainId; + return this; + } + + @Override + public Builder setTenantId(TenantId tenantId) { + this.tenantId = tenantId; + return this; + } + + @Override + public Builder setName(String name) { + this.name = name; + return this; + } + + @Override + public Builder setDescription(String description) { + this.description = description; + return this; + } + + @Override + public Builder setPortPairGroups(List<PortPairGroupId> portPairGroups) { + this.portPairGroupList = portPairGroups; + return this; + } + + @Override + public Builder setFlowClassifiers(List<FlowClassifierId> flowClassifiers) { + this.flowClassifierList = flowClassifiers; + return this; + } + + @Override + public PortChain build() { + + checkNotNull(portChainId, "Port chain id cannot be null"); + checkNotNull(tenantId, "Tenant id cannot be null"); + checkNotNull(portPairGroupList, "Port pair groups cannot be null"); + + return new DefaultPortChain(portChainId, tenantId, name, description, + portPairGroupList, flowClassifierList); + } + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortPair.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortPair.java new file mode 100644 index 00000000..4b3b7cf3 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortPair.java @@ -0,0 +1,198 @@ +/* + * 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.vtnrsc; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Objects; + +/** + * Implementation of port pair. + */ +public final class DefaultPortPair implements PortPair { + + private final PortPairId portPairId; + private final TenantId tenantId; + private final String name; + private final String description; + private final String ingress; + private final String egress; + + /** + * Default constructor to create Port Pair. + * + * @param portPairId port pair id + * @param tenantId tenant id + * @param name name of port pair + * @param description description of port pair + * @param ingress ingress port + * @param egress egress port + */ + private DefaultPortPair(PortPairId portPairId, TenantId tenantId, + String name, String description, + String ingress, String egress) { + + this.portPairId = portPairId; + this.tenantId = tenantId; + this.name = name; + this.description = description; + this.ingress = ingress; + this.egress = egress; + } + + @Override + public PortPairId portPairId() { + return portPairId; + } + + @Override + public TenantId tenantId() { + return tenantId; + } + + @Override + public String name() { + return name; + } + + @Override + public String description() { + return description; + } + + @Override + public String ingress() { + return ingress; + } + + @Override + public String egress() { + return egress; + } + + @Override + public int hashCode() { + return Objects.hash(portPairId, tenantId, name, description, + ingress, egress); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultPortPair) { + DefaultPortPair that = (DefaultPortPair) obj; + return Objects.equals(portPairId, that.portPairId) && + Objects.equals(tenantId, that.tenantId) && + Objects.equals(name, that.name) && + Objects.equals(description, that.description) && + Objects.equals(ingress, that.ingress) && + Objects.equals(egress, that.egress); + } + return false; + } + + @Override + public boolean exactMatch(PortPair portPair) { + return this.equals(portPair) && + Objects.equals(this.portPairId, portPair.portPairId()) && + Objects.equals(this.tenantId, portPair.tenantId()); + } + + @Override + public String toString() { + return toStringHelper(this) + .add("id", portPairId.toString()) + .add("tenantId", tenantId.tenantId()) + .add("name", name) + .add("description", description) + .add("ingress", ingress) + .add("egress", egress) + .toString(); + } + + /** + * To create an instance of the builder. + * + * @return instance of builder + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Builder class for Port pair. + */ + public static final class Builder implements PortPair.Builder { + + private PortPairId portPairId; + private TenantId tenantId; + private String name; + private String description; + private String ingress; + private String egress; + + @Override + public Builder setId(PortPairId portPairId) { + this.portPairId = portPairId; + return this; + } + + @Override + public Builder setTenantId(TenantId tenantId) { + this.tenantId = tenantId; + return this; + } + + @Override + public Builder setName(String name) { + this.name = name; + return this; + } + + @Override + public Builder setDescription(String description) { + this.description = description; + return this; + } + + @Override + public Builder setIngress(String ingress) { + this.ingress = ingress; + return this; + } + + @Override + public Builder setEgress(String egress) { + this.egress = egress; + return this; + } + + @Override + public PortPair build() { + + checkNotNull(portPairId, "Port pair id cannot be null"); + checkNotNull(tenantId, "Tenant id cannot be null"); + checkNotNull(ingress, "Ingress of a port pair cannot be null"); + checkNotNull(egress, "Egress of a port pair cannot be null"); + + return new DefaultPortPair(portPairId, tenantId, name, description, + ingress, egress); + } + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortPairGroup.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortPairGroup.java new file mode 100644 index 00000000..877cc6c9 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortPairGroup.java @@ -0,0 +1,183 @@ +/* + * 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.vtnrsc; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.List; +import java.util.Objects; + +import com.google.common.collect.ImmutableList; + +/** + * Implementation of port pair group. + */ +public final class DefaultPortPairGroup implements PortPairGroup { + + private final PortPairGroupId portPairGroupId; + private final TenantId tenantId; + private final String name; + private final String description; + private final List<PortPairId> portPairList; + + /** + * Default constructor to create Port Pair Group. + * + * @param portPairGroupId port pair group id + * @param tenantId tenant id + * @param name name of port pair group + * @param description description of port pair group + * @param portPairList list of port pairs + */ + private DefaultPortPairGroup(PortPairGroupId portPairGroupId, TenantId tenantId, + String name, String description, + List<PortPairId> portPairList) { + + this.portPairGroupId = portPairGroupId; + this.tenantId = tenantId; + this.name = name; + this.description = description; + this.portPairList = portPairList; + } + + @Override + public PortPairGroupId portPairGroupId() { + return portPairGroupId; + } + + @Override + public TenantId tenantId() { + return tenantId; + } + + @Override + public String name() { + return name; + } + + @Override + public String description() { + return description; + } + + @Override + public List<PortPairId> portPairs() { + return ImmutableList.copyOf(portPairList); + } + + @Override + public int hashCode() { + return Objects.hash(portPairGroupId, tenantId, name, description, + portPairList); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultPortPairGroup) { + DefaultPortPairGroup that = (DefaultPortPairGroup) obj; + return Objects.equals(portPairGroupId, that.portPairGroupId) && + Objects.equals(tenantId, that.tenantId) && + Objects.equals(name, that.name) && + Objects.equals(description, that.description) && + Objects.equals(portPairList, that.portPairList); + } + return false; + } + + @Override + public boolean exactMatch(PortPairGroup portPairGroup) { + return this.equals(portPairGroup) && + Objects.equals(this.portPairGroupId, portPairGroup.portPairGroupId()) && + Objects.equals(this.tenantId, portPairGroup.tenantId()); + } + + @Override + public String toString() { + return toStringHelper(this) + .add("id", portPairGroupId.toString()) + .add("tenantId", tenantId.toString()) + .add("name", name) + .add("description", description) + .add("portPairGroupList", portPairList) + .toString(); + } + + /** + * To create an instance of the builder. + * + * @return instance of builder + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Builder class for Port pair group. + */ + public static final class Builder implements PortPairGroup.Builder { + + private PortPairGroupId portPairGroupId; + private TenantId tenantId; + private String name; + private String description; + private List<PortPairId> portPairList; + + @Override + public Builder setId(PortPairGroupId portPairGroupId) { + this.portPairGroupId = portPairGroupId; + return this; + } + + @Override + public Builder setTenantId(TenantId tenantId) { + this.tenantId = tenantId; + return this; + } + + @Override + public Builder setName(String name) { + this.name = name; + return this; + } + + @Override + public Builder setDescription(String description) { + this.description = description; + return this; + } + + @Override + public Builder setPortPairs(List<PortPairId> portPairs) { + this.portPairList = portPairs; + return this; + } + + @Override + public PortPairGroup build() { + + checkNotNull(portPairGroupId, "Port pair group id cannot be null"); + checkNotNull(tenantId, "Tenant id cannot be null"); + checkNotNull(portPairList, "Port pairs cannot be null"); + + return new DefaultPortPairGroup(portPairGroupId, tenantId, name, description, + portPairList); + } + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FlowClassifier.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FlowClassifier.java new file mode 100644 index 00000000..7b4108dc --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FlowClassifier.java @@ -0,0 +1,259 @@ +/* + * 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.vtnrsc; + +import org.onlab.packet.IpPrefix; + +/** + * Abstraction of an entity which provides flow classifier for service function chain. + * FlowClassifier classify the traffic based on the criteria defined in the request. + * The classification can be based on port range or source and destination IP address or + * other flow classifier elements. + */ +public interface FlowClassifier { + + /** + * Returns flow classifier ID. + * + * @return flow classifier id + */ + FlowClassifierId flowClassifierId(); + + /** + * Returns Tenant ID. + * + * @return tenant Id + */ + TenantId tenantId(); + + /** + * Returns flow classifier name. + * + * @return flow classifier name + */ + String name(); + + /** + * Returns flow classifier description. + * + * @return flow classifier description + */ + String description(); + + /** + * Returns EtherType. + * + * @return EtherType + */ + String etherType(); + + /** + * Returns IP Protocol. + * + * @return IP protocol + */ + String protocol(); + + /** + * Returns minimum source port range. + * + * @return minimum source port range + */ + int minSrcPortRange(); + + /** + * Returns maximum source port range. + * + * @return maximum source port range + */ + int maxSrcPortRange(); + + /** + * Returns minimum destination port range. + * + * @return minimum destination port range + */ + int minDstPortRange(); + + /** + * Returns maximum destination port range. + * + * @return maximum destination port range. + */ + int maxDstPortRange(); + + /** + * Returns Source IP prefix. + * + * @return Source IP prefix + */ + IpPrefix srcIpPrefix(); + + /** + * Returns Destination IP prefix. + * + * @return Destination IP prefix + */ + IpPrefix dstIpPrefix(); + + /** + * Returns Source virtual port. + * + * @return Source virtual port + */ + VirtualPortId srcPort(); + + /** + * Returns Destination virtual port. + * + * @return Destination virtual port + */ + VirtualPortId dstPort(); + + /** + * Returns whether this Flow classifier is an exact match to the + * Flow classifier given in the argument. + * + * @param flowClassifier other flowClassifier to match against + * @return true if the flowClassifiers are an exact match, otherwise false + */ + boolean exactMatch(FlowClassifier flowClassifier); + + /** + * Builder for flow Classifier. + */ + interface Builder { + + /** + * Returns Flow Classifier. + * + * @return flow classifier. + */ + FlowClassifier build(); + + /** + * Sets Flow Classifier ID. + * + * @param flowClassifierId flow classifier id. + * @return Builder object by setting flow classifier Id. + */ + Builder setFlowClassifierId(FlowClassifierId flowClassifierId); + + /** + * Sets Tenant ID. + * + * @param tenantId tenant id. + * @return Builder object by setting Tenant ID. + */ + Builder setTenantId(TenantId tenantId); + + /** + * Sets Flow classifier name. + * + * @param name flow classifier name + * @return builder object by setting flow classifier name + */ + Builder setName(String name); + + /** + * Sets flow classifier description. + * + * @param description flow classifier description + * @return flow classifier description + */ + Builder setDescription(String description); + + /** + * Sets EtherType. + * + * @param etherType EtherType + * @return EtherType + */ + Builder setEtherType(String etherType); + + /** + * Sets IP protocol. + * + * @param protocol IP protocol + * @return builder object by setting IP protocol + */ + Builder setProtocol(String protocol); + + /** + * Set minimum source port range. + * + * @param minRange minimum source port range + * @return builder object by setting minimum source port range + */ + Builder setMinSrcPortRange(int minRange); + + /** + * Sets maximum source port range. + * + * @param maxRange maximum source port range + * @return builder object by setting maximum source port range + */ + Builder setMaxSrcPortRange(int maxRange); + + /** + * Sets minimum destination port range. + * + * @param minRange minimum destination port range + * @return builder object by setting minimum destination port range + */ + Builder setMinDstPortRange(int minRange); + + /** + * Sets maximum destination port range. + * + * @param maxRange maximum destination port range. + * @return builder object by setting maximum destination port range. + */ + Builder setMaxDstPortRange(int maxRange); + + /** + * Sets Source IP prefix. + * + * @param srcIpPrefix Source IP prefix + * @return builder object by setting Source IP prefix + */ + Builder setSrcIpPrefix(IpPrefix srcIpPrefix); + + /** + * Sets Destination IP prefix. + * + * @param dstIpPrefix Destination IP prefix + * @return builder object by setting Destination IP prefix + */ + Builder setDstIpPrefix(IpPrefix dstIpPrefix); + + /** + * Sets Source virtual port. + * + * @param srcPort Source virtual port + * @return builder object by setting Source virtual port + */ + Builder setSrcPort(VirtualPortId srcPort); + + /** + * Sets Destination virtual port. + * + * @param dstPort Destination virtual port + * @return builder object by setting Destination virtual port + */ + Builder setDstPort(VirtualPortId dstPort); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FlowClassifierId.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FlowClassifierId.java new file mode 100644 index 00000000..b789abe3 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FlowClassifierId.java @@ -0,0 +1,91 @@ +/* + * 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.vtnrsc; + +import com.google.common.base.MoreObjects; + +import java.util.UUID; +import java.util.Objects; + +/** + * Flow classification identifier. + */ +public final class FlowClassifierId { + + private final UUID flowClassifierId; + + /** + * Constructor to create flow classifier id. + * + * @param flowClassifierId flow classifier id. + */ + private FlowClassifierId(final UUID flowClassifierId) { + this.flowClassifierId = flowClassifierId; + } + + /** + * Returns new flow classifier id. + * + * @param flowClassifierId flow classifier id + * @return new flow classifier id + */ + public static FlowClassifierId flowClassifierId(final UUID flowClassifierId) { + return new FlowClassifierId(flowClassifierId); + } + + /** + * Returns new flow classifier id. + * + * @param flowClassifierId flow classifier id + * @return new flow classifier id + */ + public static FlowClassifierId flowClassifierId(final String flowClassifierId) { + return new FlowClassifierId(UUID.fromString(flowClassifierId)); + } + + /** + * Returns the value of flow classifier id. + * + * @return flow classifier id. + */ + public UUID value() { + return flowClassifierId; + } + + @Override + public int hashCode() { + return Objects.hashCode(this.flowClassifierId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof FlowClassifierId) { + final FlowClassifierId other = (FlowClassifierId) obj; + return Objects.equals(this.flowClassifierId, other.flowClassifierId); + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("FlowClassifierId", flowClassifierId) + .toString(); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortChain.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortChain.java new file mode 100644 index 00000000..d147eaaa --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortChain.java @@ -0,0 +1,148 @@ +/* + * 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.vtnrsc; + +import java.util.List; + +/** + * Abstraction of an entity providing Port Chain information. + * A Port Chain (Service Function Path) consists of + * a set of Neutron ports, to define the sequence of service functions + * a set of flow classifiers, to specify the classified traffic flows to enter the chain + */ +public interface PortChain { + + /** + * Returns the ID of this port chain. + * + * @return the port chain id + */ + PortChainId portChainId(); + + /** + * Returns the tenant id of this port chain. + * + * @return the tenant id + */ + TenantId tenantId(); + + /** + * Returns the name of this port chain. + * + * @return name of port chain + */ + String name(); + + /** + * Returns the description of this port chain. + * + * @return description of port chain + */ + String description(); + + /** + * Returns the list of port pair groups associated with + * this port chain. + * + * @return list of port pair groups + */ + List<PortPairGroupId> portPairGroups(); + + /** + * Returns the list of flow classifiers associated with + * this port chain. + * + * @return list of flow classifiers + */ + List<FlowClassifierId> flowClassifiers(); + + /** + * Returns whether this port chain is an exact match to the port chain given + * in the argument. + * <p> + * Exact match means the port pair groups and flow classifiers match + * with the given port chain. It does not consider the port chain id, name + * and description. + * </p> + * + * @param portChain other port chain to match against + * @return true if the port chains are an exact match, otherwise false + */ + boolean exactMatch(PortChain portChain); + + /** + * A port chain builder.. + */ + interface Builder { + + /** + * Assigns the port chain id to this object. + * + * @param portChainId the port chain id + * @return this the builder object + */ + Builder setId(PortChainId portChainId); + + /** + * Assigns tenant id to this object. + * + * @param tenantId tenant id of the port chain + * @return this the builder object + */ + Builder setTenantId(TenantId tenantId); + + /** + * Assigns the name to this object. + * + * @param name name of the port chain + * @return this the builder object + */ + Builder setName(String name); + + /** + * Assigns the description to this object. + * + * @param description description of the port chain + * @return this the builder object + */ + Builder setDescription(String description); + + /** + * Assigns the port pair groups associated with the port chain + * to this object. + * + * @param portPairGroups list of port pair groups + * @return this the builder object + */ + Builder setPortPairGroups(List<PortPairGroupId> portPairGroups); + + /** + * Assigns the flow classifiers associated with the port chain + * to this object. + * + * @param flowClassifiers list of flow classifiers + * @return this the builder object + */ + Builder setFlowClassifiers(List<FlowClassifierId> flowClassifiers); + + /** + * Builds a port chain object. + * + * @return a port chain. + */ + PortChain build(); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortChainId.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortChainId.java new file mode 100644 index 00000000..66edbdcc --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortChainId.java @@ -0,0 +1,95 @@ +/* + * 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.vtnrsc; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.UUID; + +import com.google.common.base.Objects; + +/** + * Representation of a Port Chain ID. + */ +public final class PortChainId { + + private final UUID portChainId; + + /** + * Private constructor for port chain id. + * + * @param id UUID id of port chain + */ + private PortChainId(UUID id) { + checkNotNull(id, "Port chain id can not be null"); + this.portChainId = id; + } + + /** + * Constructor to create port chain id from UUID. + * + * @param id UUID of port chain + * @return object of port chain id + */ + public static PortChainId portChainId(UUID id) { + return new PortChainId(id); + } + + /** + * Constructor to create port chain id from string. + * + * @param id port chain id in string + * @return object of port chain id + */ + public static PortChainId portChainId(String id) { + return new PortChainId(UUID.fromString(id)); + } + + /** + * Returns the value of port chain id. + * + * @return port chain id + */ + public UUID value() { + return portChainId; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj.getClass() == this.getClass()) { + PortChainId that = (PortChainId) obj; + return Objects.equal(this.portChainId, that.portChainId); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hashCode(this.portChainId); + } + + @Override + public String toString() { + return toStringHelper(this) + .add("portChainId", portChainId.toString()) + .toString(); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPair.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPair.java new file mode 100644 index 00000000..f6285e61 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPair.java @@ -0,0 +1,139 @@ +/* + * 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.vtnrsc; + + +/** + * Abstraction of an entity providing Port Pair information. + * A port pair represents a service function instance. + */ +public interface PortPair { + + /** + * Returns the ID of this port Pair. + * + * @return the port pair id + */ + PortPairId portPairId(); + + /** + * Returns the tenant id of this port pair. + * + * @return an tenant id + */ + TenantId tenantId(); + + /** + * Returns the description of this port pair. + * + * @return description of port pair + */ + String name(); + + /** + * Returns the description of this port pair. + * + * @return description of port pair + */ + String description(); + + /** + * Returns the ingress port of this port pair. + * + * @return ingress of port pair + */ + String ingress(); + + /** + * Returns the egress port of this port pair. + * + * @return egress of port pair + */ + String egress(); + + /** + * Returns whether this port pair is an exact match to the port pair given + * in the argument. + * <p> + * Exact match means the Port port pairs match with the given port pair. + * It does not consider the port pair id, name and description. + * </p> + * @param portPair other port pair to match against + * @return true if the port pairs are an exact match, otherwise false + */ + boolean exactMatch(PortPair portPair); + + /** + * A port pair builder.. + */ + interface Builder { + + /** + * Assigns the port pair id to this object. + * + * @param portPairId the port pair id + * @return this the builder object + */ + Builder setId(PortPairId portPairId); + + /** + * Assigns tenant id to this object. + * + * @param tenantId tenant id of the port pair + * @return this the builder object + */ + Builder setTenantId(TenantId tenantId); + + /** + * Assigns the name to this object. + * + * @param name name of the port pair + * @return this the builder object + */ + Builder setName(String name); + + /** + * Assigns the description to this object. + * + * @param description description of the port pair + * @return this the builder object + */ + Builder setDescription(String description); + + /** + * Assigns the ingress port to this object. + * + * @param port ingress port of the port pair + * @return this the builder object + */ + Builder setIngress(String port); + + /** + * Assigns the egress port to this object. + * + * @param port egress port of the port pair + * @return this the builder object + */ + Builder setEgress(String port); + + /** + * Builds a port pair object. + * + * @return a port pair. + */ + PortPair build(); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairGroup.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairGroup.java new file mode 100644 index 00000000..f647b57f --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairGroup.java @@ -0,0 +1,126 @@ +/* + * 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.vtnrsc; + +import java.util.List; + +/** + * Abstraction of an entity providing Port Pair Group information. + * A port pair group consists of one or more port pairs. + */ +public interface PortPairGroup { + + /** + * Returns the ID of this port pair group. + * + * @return the port pair group id + */ + PortPairGroupId portPairGroupId(); + + /** + * Returns the tenant id of this port pair group. + * + * @return the tenant id + */ + TenantId tenantId(); + + /** + * Returns the name of this port pair group. + * + * @return name of port pair group + */ + String name(); + + /** + * Returns the description of this port pair group. + * + * @return description of port pair group + */ + String description(); + + /** + * Returns the list of port pairs associated with this port pair group. + * + * @return list of port pairs + */ + List<PortPairId> portPairs(); + + /** + * Returns whether this port pair group is an exact match to the + * port pair group given in the argument. + * <p> + * Exact match means the Port pairs match with the given port pair group. + * It does not consider the port pair group id, name and description. + * </p> + * @param portPairGroup other port pair group to match against + * @return true if the port pairs are an exact match, otherwise false + */ + boolean exactMatch(PortPairGroup portPairGroup); + + /** + * A port pair group builder.. + */ + interface Builder { + + /** + * Assigns the port pair group id to this object. + * + * @param portPairGroupId the port pair group id + * @return this the builder object + */ + Builder setId(PortPairGroupId portPairGroupId); + + /** + * Assigns tenant id to this object. + * + * @param tenantId tenant id of port pair group + * @return this the builder object + */ + Builder setTenantId(TenantId tenantId); + + /** + * Assigns the name to this object. + * + * @param name name of the port pair group + * @return this the builder object + */ + Builder setName(String name); + + /** + * Assigns the description to this object. + * + * @param description description of the port pair group + * @return this the builder object + */ + Builder setDescription(String description); + + /** + * Assigns the port pairs associated with the port pair group + * to this object. + * + * @param portPairs list of port pairs + * @return this the builder object + */ + Builder setPortPairs(List<PortPairId> portPairs); + + /** + * Builds a port pair group object. + * + * @return a port pair group object. + */ + PortPairGroup build(); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairGroupId.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairGroupId.java new file mode 100644 index 00000000..0474901c --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairGroupId.java @@ -0,0 +1,95 @@ +/* + * 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.vtnrsc; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.UUID; + +import com.google.common.base.Objects; + +/** + * Representation of a Port Pair Group ID. + */ +public final class PortPairGroupId { + + private final UUID portPairGroupId; + + /** + * Private constructor for port pair group id. + * + * @param id UUID id of port pair group + */ + private PortPairGroupId(UUID id) { + checkNotNull(id, "Port pair group id can not be null"); + this.portPairGroupId = id; + } + + /** + * Constructor to create port pair group id from UUID. + * + * @param id UUID of port pair group id + * @return object of port pair group id + */ + public static PortPairGroupId portPairGroupId(UUID id) { + return new PortPairGroupId(id); + } + + /** + * Constructor to create port pair group id from string. + * + * @param id port pair group id in string + * @return object of port pair group id + */ + public static PortPairGroupId portPairGroupId(String id) { + return new PortPairGroupId(UUID.fromString(id)); + } + + /** + * Returns the value of port pair group id. + * + * @return port pair group id + */ + public UUID value() { + return portPairGroupId; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj.getClass() == this.getClass()) { + PortPairGroupId that = (PortPairGroupId) obj; + return Objects.equal(this.portPairGroupId, that.portPairGroupId); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hashCode(this.portPairGroupId); + } + + @Override + public String toString() { + return toStringHelper(this) + .add("portPairGroupId", portPairGroupId.toString()) + .toString(); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairId.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairId.java new file mode 100644 index 00000000..05c31aac --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairId.java @@ -0,0 +1,95 @@ +/* + * 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.vtnrsc; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.UUID; + +import com.google.common.base.Objects; + +/** + * Representation of a Port Pair ID. + */ +public final class PortPairId { + + private final UUID portPairId; + + /** + * Private constructor for port pair id. + * + * @param id UUID id of port pair + */ + private PortPairId(UUID id) { + checkNotNull(id, "Port chain id can not be null"); + this.portPairId = id; + } + + /** + * Constructor to create port pair id from UUID. + * + * @param id UUID of port pair id + * @return object of port pair id + */ + public static PortPairId portPairId(UUID id) { + return new PortPairId(id); + } + + /** + * Constructor to create port pair id from string. + * + * @param id port pair id in string + * @return object of port pair id + */ + public static PortPairId portPairId(String id) { + return new PortPairId(UUID.fromString(id)); + } + + /** + * Returns teh value of port pair id. + * + * @return port pair id + */ + public UUID value() { + return portPairId; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj.getClass() == this.getClass()) { + PortPairId that = (PortPairId) obj; + return Objects.equal(this.portPairId, that.portPairId); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hashCode(this.portPairId); + } + + @Override + public String toString() { + return toStringHelper(this) + .add("portPairId", portPairId.toString()) + .toString(); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/FlowClassifierService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/FlowClassifierService.java new file mode 100644 index 00000000..e379be81 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/FlowClassifierService.java @@ -0,0 +1,72 @@ +/* + * 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.vtnrsc.flowClassifier; + +import org.onosproject.vtnrsc.FlowClassifier; +import org.onosproject.vtnrsc.FlowClassifierId; + +/** + * Provides Services for Flow Classifier. + */ +public interface FlowClassifierService { + + /** + * Store Flow Classifier. + * + * @param flowClassifier Flow Classifier + * @return true if adding Flow Classifier into store is success otherwise return false. + */ + boolean createFlowClassifier(FlowClassifier flowClassifier); + + /** + * Return the existing collection of Flow Classifier. + * + * @return Flow Classifier collections. + */ + Iterable<FlowClassifier> getFlowClassifiers(); + + /** + * Check whether Flow Classifier is present based on given Flow Classifier Id. + * + * @param id Flow Classifier. + * @return true if Flow Classifier is present otherwise return false. + */ + boolean hasFlowClassifier(FlowClassifierId id); + + /** + * Retrieve the Flow Classifier based on given Flow Classifier id. + * + * @param id Flow Classifier Id. + * @return Flow Classifier if present otherwise returns null. + */ + FlowClassifier getFlowClassifier(FlowClassifierId id); + + /** + * Update Flow Classifier based on given Flow Classifier Id. + * + * @param flowClassifier Flow Classifier. + * @return true if update is success otherwise return false. + */ + boolean updateFlowClassifier(FlowClassifier flowClassifier); + + /** + * Remove Flow Classifier from store based on given Flow Classifier Id. + * + * @param id Flow Classifier Id. + * @return true if Flow Classifier removal is success otherwise return false. + */ + boolean removeFlowClassifier(FlowClassifierId id); +}
\ No newline at end of file diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/FlowClassifierManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/FlowClassifierManager.java new file mode 100644 index 00000000..7238558a --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/FlowClassifierManager.java @@ -0,0 +1,108 @@ +/* + * 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.vtnrsc.flowClassifier.impl; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +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.Service; +import org.onosproject.vtnrsc.FlowClassifierId; +import org.onosproject.vtnrsc.FlowClassifier; +import org.onosproject.vtnrsc.flowClassifier.FlowClassifierService; + +import org.slf4j.Logger; +import static org.slf4j.LoggerFactory.getLogger; + +import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.collect.ImmutableList; + +/** + * Provides implementation of the Flow Classifier Service. + */ +@Component(immediate = true) +@Service +public class FlowClassifierManager implements FlowClassifierService { + + private final Logger log = getLogger(FlowClassifierManager.class); + + private static final String FLOW_CLASSIFIER_NOT_NULL = "Flow Classifier cannot be null"; + private static final String FLOW_CLASSIFIER_ID_NOT_NULL = "Flow Classifier Id cannot be null"; + + private ConcurrentMap<FlowClassifierId, FlowClassifier> flowClassifierStore + = new ConcurrentHashMap<FlowClassifierId, FlowClassifier>(); + + @Activate + private void activate() { + log.info("Flow Classifier service activated"); + } + + @Deactivate + private void deactivate() { + log.info("Flow Classifier service deactivated"); + } + + @Override + public boolean createFlowClassifier(FlowClassifier flowClassifier) { + log.debug("createFlowClassifier"); + checkNotNull(flowClassifier, FLOW_CLASSIFIER_NOT_NULL); + FlowClassifierId id = flowClassifier.flowClassifierId(); + + flowClassifierStore.put(id, flowClassifier); + if (!flowClassifierStore.containsKey(id)) { + log.debug("Flow Classifier creation is failed whose identifier is {}.", id.toString()); + return false; + } + return true; + } + + @Override + public Iterable<FlowClassifier> getFlowClassifiers() { + return ImmutableList.copyOf(flowClassifierStore.values()); + } + + @Override + public boolean hasFlowClassifier(FlowClassifierId id) { + checkNotNull(id, FLOW_CLASSIFIER_ID_NOT_NULL); + return flowClassifierStore.containsKey(id); + } + + @Override + public FlowClassifier getFlowClassifier(FlowClassifierId id) { + checkNotNull(id, FLOW_CLASSIFIER_ID_NOT_NULL); + return flowClassifierStore.get(id); + } + + @Override + public boolean updateFlowClassifier(FlowClassifier flowClassifier) { + checkNotNull(flowClassifier, FLOW_CLASSIFIER_NOT_NULL); + FlowClassifierId id = flowClassifier.flowClassifierId(); + return flowClassifierStore.replace(id, flowClassifierStore.get(id), flowClassifier); + } + + @Override + public boolean removeFlowClassifier(FlowClassifierId id) { + checkNotNull(id, FLOW_CLASSIFIER_ID_NOT_NULL); + flowClassifierStore.remove(id); + if (flowClassifierStore.containsKey(id)) { + log.debug("The Flow Classifier removal is failed whose identifier is {}", id.toString()); + return false; + } + return true; + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/package-info.java new file mode 100644 index 00000000..4ea050b3 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/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. + */ + +/** + * Provides implementation of the flow Classifier service. + */ +package org.onosproject.vtnrsc.flowClassifier.impl; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/package-info.java new file mode 100644 index 00000000..07584170 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/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 interacting with flow Classifier of SFC. + */ +package org.onosproject.vtnrsc.flowClassifier; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainService.java new file mode 100644 index 00000000..b4ff917e --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainService.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.vtnrsc.portchain; + +import org.onosproject.vtnrsc.PortChain; +import org.onosproject.vtnrsc.PortChainId; + +/** + * Service for interacting with the inventory of port chains. + */ +public interface PortChainService { + + /** + * Returns if the port chain is existed. + * + * @param portChainId port chain identifier + * @return true or false if one with the given identifier exists. + */ + boolean exists(PortChainId portChainId); + + /** + * Returns the number of port chains known to the system. + * + * @return number of port chains. + */ + int getPortChainCount(); + + /** + * Returns an iterable collection of the currently known port chains. + * + * @return collection of port chains. + */ + Iterable<PortChain> getPortChains(); + + /** + * Returns the portChain with the given identifier. + * + * @param portChainId port chain identifier + * @return PortChain or null if port chain with the given identifier is not + * known. + */ + PortChain getPortChain(PortChainId portChainId); + + /** + * Creates a PortChain in the store. + * + * @param portChain the port chain to create + * @return true if given port chain is created successfully. + */ + boolean createPortChain(PortChain portChain); + + /** + * Updates the portChain in the store. + * + * @param portChain the port chain to update + * @return true if given port chain is updated successfully. + */ + boolean updatePortChain(PortChain portChain); + + /** + * Deletes portChain by given portChainId. + * + * @param portChainId id of port chain to remove + * @return true if the give port chain is deleted successfully. + */ + boolean removePortChain(PortChainId portChainId); +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/package-info.java new file mode 100644 index 00000000..74642bc3 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/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 interacting with the inventory of port chains. + */ +package org.onosproject.vtnrsc.portchain; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupService.java new file mode 100644 index 00000000..77f483fc --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupService.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.vtnrsc.portpairgroup; + +import org.onosproject.vtnrsc.PortPairGroup; +import org.onosproject.vtnrsc.PortPairGroupId; + +/** + * Service for interacting with the inventory of port pair groups. + */ +public interface PortPairGroupService { + + /** + * Returns if the port pair group is existed. + * + * @param portPairGroupId port pair group identifier + * @return true or false if one with the given identifier exists. + */ + boolean exists(PortPairGroupId portPairGroupId); + + /** + * Returns the number of port pair groups known to the system. + * + * @return number of port pair groups. + */ + int getPortPairGroupCount(); + + /** + * Returns an iterable collection of the currently known port pair groups. + * + * @return collection of port pair groups. + */ + Iterable<PortPairGroup> getPortPairGroups(); + + /** + * Returns the portPairGroup with the given identifier. + * + * @param portPairGroupId port pair group identifier + * @return PortPairGroup or null if port pair group with the given identifier is not + * known. + */ + PortPairGroup getPortPairGroup(PortPairGroupId portPairGroupId); + + /** + * Creates a PortPairGroup in the store. + * + * @param portPairGroup the port pair group to create + * @return true if given port pair group is created successfully. + */ + boolean createPortPairGroup(PortPairGroup portPairGroup); + + /** + * Updates the portPairGroup in the store. + * + * @param portPairGroup the port pair group to update + * @return true if given port pair group is updated successfully. + */ + boolean updatePortPairGroup(PortPairGroup portPairGroup); + + /** + * Deletes portPairGroup by given portPairGroupId. + * + * @param portPairGroupId id of port pair group to remove + * @return true if the give port pair group is deleted successfully. + */ + boolean removePortPairGroup(PortPairGroupId portPairGroupId); +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/package-info.java new file mode 100644 index 00000000..8a79fe97 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/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 interacting with the inventory of port pair groups. + */ +package org.onosproject.vtnrsc.portpairgroup; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/tunnel/TunnelConfigService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/tunnel/TunnelConfigService.java deleted file mode 100644 index 6f3cf653..00000000 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/tunnel/TunnelConfigService.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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.vtnrsc.tunnel; - -import org.onosproject.vtnrsc.Subnet; -import org.onosproject.vtnrsc.SubnetId; - - -/** - * Service for interacting with the inventory of subnets. - */ -public interface TunnelConfigService { - /** - * Returns the subnet with the specified identifier. - * - * @param subnetId subnet identifier - * @return true or false - */ - boolean exists(SubnetId subnetId); - /** - * Returns a collection of the currently known subnets. - * - * @return iterable collection of subnets - */ - Iterable<Subnet> getSubnets(); - - /** - * Returns the subnet with the specified identifier. - * - * @param subnetId subnet identifier - * @return subnet or null if one with the given identifier is not known - */ - Subnet getSubnet(SubnetId subnetId); - /** - * Creates new subnets. - * - * @param subnets the iterable collection of subnets - * @return true if the identifier subnet has been created right - */ - boolean createSubnets(Iterable<Subnet> subnets); - - /** - * Updates existing subnets. - * - * @param subnets the iterable collection of subnets - * @return true if all subnets were updated successfully - */ - boolean updateSubnets(Iterable<Subnet> subnets); - - /** - * Administratively removes the specified subnets from the store. - * - * @param subnetIds the iterable collection of subnets identifier - * @return true if remove identifier subnets successfully - */ - boolean removeSubnets(Iterable<SubnetId> subnetIds); - - -} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java index c45373b9..daec7839 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java @@ -191,22 +191,20 @@ public class VirtualPortManager implements VirtualPortService { @Override public boolean updatePorts(Iterable<VirtualPort> vPorts) { checkNotNull(vPorts, VIRTUALPORT_NOT_NULL); - if (vPorts != null) { - for (VirtualPort vPort : vPorts) { - vPortStore.put(vPort.portId(), vPort); - if (!vPortStore.containsKey(vPort.portId())) { - log.debug("The virtualPort is not exist whose identifier is {}", - vPort.portId().toString()); - return false; - } + for (VirtualPort vPort : vPorts) { + vPortStore.put(vPort.portId(), vPort); + if (!vPortStore.containsKey(vPort.portId())) { + log.debug("The virtualPort is not exist whose identifier is {}", + vPort.portId().toString()); + return false; + } - vPortStore.put(vPort.portId(), vPort); + vPortStore.put(vPort.portId(), vPort); - if (!vPort.equals(vPortStore.get(vPort.portId()))) { - log.debug("The virtualPort is updated failed whose identifier is {}", - vPort.portId().toString()); - return false; - } + if (!vPort.equals(vPortStore.get(vPort.portId()))) { + log.debug("The virtualPort is updated failed whose identifier is {}", + vPort.portId().toString()); + return false; } } return true; @@ -215,14 +213,12 @@ public class VirtualPortManager implements VirtualPortService { @Override public boolean removePorts(Iterable<VirtualPortId> vPortIds) { checkNotNull(vPortIds, VIRTUALPORT_ID_NULL); - if (vPortIds != null) { - for (VirtualPortId vPortId : vPortIds) { - vPortStore.remove(vPortId); - if (vPortStore.containsKey(vPortId)) { - log.debug("The virtualPort is removed failed whose identifier is {}", - vPortId.toString()); - return false; - } + for (VirtualPortId vPortId : vPortIds) { + vPortStore.remove(vPortId); + if (vPortStore.containsKey(vPortId)) { + log.debug("The virtualPort is removed failed whose identifier is {}", + vPortId.toString()); + return false; } } return true; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/FlowClassifierCodec.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/FlowClassifierCodec.java new file mode 100644 index 00000000..fd5b1ee4 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/FlowClassifierCodec.java @@ -0,0 +1,134 @@ +/* + * 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.vtnrsc.web; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.onlab.util.Tools.nullIsIllegal; + +import java.util.UUID; + +import org.onlab.packet.IpPrefix; +import org.onosproject.codec.CodecContext; +import org.onosproject.codec.JsonCodec; +import org.onosproject.vtnrsc.DefaultFlowClassifier; +import org.onosproject.vtnrsc.FlowClassifier; +import org.onosproject.vtnrsc.FlowClassifierId; +import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.TenantId; + +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * Flow Classifier JSON codec. + */ +public final class FlowClassifierCodec extends JsonCodec<FlowClassifier> { + + private static final String FLOW_CLASSIFIER_ID = "id"; + private static final String TENANT_ID = "tenant_id"; + private static final String NAME = "name"; + private static final String DESCRIPTION = "description"; + private static final String ETHER_TYPE = "etherType"; + private static final String PROTOCOL = "protocol"; + private static final String MIN_SRC_PORT_RANGE = "source_port_range_min"; + private static final String MAX_SRC_PORT_RANGE = "source_port_range_max"; + private static final String MIN_DST_PORT_RANGE = "destination_port_range_min"; + private static final String MAX_DST_PORT_RANGE = "destination_port_range_max"; + private static final String SRC_IP_PREFIX = "source_ip_prefix"; + private static final String DST_IP_PREFIX = "destination_ip_prefix"; + private static final String SRC_PORT = "logical_source_port"; + private static final String DST_PORT = "logical_destination_port"; + private static final String MISSING_MEMBER_MESSAGE = " member is required in Flow Classifier."; + + @Override + public FlowClassifier decode(ObjectNode json, CodecContext context) { + if (json == null || !json.isObject()) { + return null; + } + + FlowClassifier.Builder resultBuilder = new DefaultFlowClassifier.Builder(); + + String flowClassifierId = nullIsIllegal(json.get(FLOW_CLASSIFIER_ID), + FLOW_CLASSIFIER_ID + MISSING_MEMBER_MESSAGE).asText(); + resultBuilder.setFlowClassifierId(FlowClassifierId.flowClassifierId(UUID.fromString(flowClassifierId))); + + String tenantId = nullIsIllegal(json.get(TENANT_ID), TENANT_ID + MISSING_MEMBER_MESSAGE).asText(); + resultBuilder.setTenantId(TenantId.tenantId(tenantId)); + + String flowClassiferName = nullIsIllegal(json.get(NAME), NAME + MISSING_MEMBER_MESSAGE).asText(); + resultBuilder.setName(flowClassiferName); + + String flowClassiferDescription = nullIsIllegal(json.get(DESCRIPTION), DESCRIPTION + MISSING_MEMBER_MESSAGE) + .asText(); + resultBuilder.setDescription(flowClassiferDescription); + + String etherType = nullIsIllegal(json.get(ETHER_TYPE), ETHER_TYPE + MISSING_MEMBER_MESSAGE).asText(); + resultBuilder.setEtherType(etherType); + + String protocol = nullIsIllegal(json.get(PROTOCOL), PROTOCOL + MISSING_MEMBER_MESSAGE).asText(); + resultBuilder.setProtocol(protocol); + + int minSrcPortRange = nullIsIllegal(json.get(MIN_SRC_PORT_RANGE), MIN_SRC_PORT_RANGE + MISSING_MEMBER_MESSAGE) + .asInt(); + resultBuilder.setMinSrcPortRange(minSrcPortRange); + + int maxSrcPortRange = nullIsIllegal(json.get(MAX_SRC_PORT_RANGE), MAX_SRC_PORT_RANGE + MISSING_MEMBER_MESSAGE) + .asInt(); + resultBuilder.setMaxSrcPortRange(maxSrcPortRange); + + int minDstPortRange = nullIsIllegal(json.get(MIN_DST_PORT_RANGE), MIN_DST_PORT_RANGE + MISSING_MEMBER_MESSAGE) + .asInt(); + resultBuilder.setMinDstPortRange(minDstPortRange); + + int maxDstPortRange = nullIsIllegal(json.get(MAX_DST_PORT_RANGE), MAX_DST_PORT_RANGE + MISSING_MEMBER_MESSAGE) + .asInt(); + resultBuilder.setMaxDstPortRange(maxDstPortRange); + + String srcIpPrefix = nullIsIllegal(json.get(SRC_IP_PREFIX), SRC_IP_PREFIX + MISSING_MEMBER_MESSAGE).asText(); + resultBuilder.setSrcIpPrefix(IpPrefix.valueOf(srcIpPrefix)); + + String dstIpPrefix = nullIsIllegal(json.get(DST_IP_PREFIX), DST_IP_PREFIX + MISSING_MEMBER_MESSAGE).asText(); + resultBuilder.setDstIpPrefix(IpPrefix.valueOf(dstIpPrefix)); + + String srcPort = nullIsIllegal(json.get(SRC_PORT), SRC_PORT + MISSING_MEMBER_MESSAGE).asText(); + resultBuilder.setSrcPort(VirtualPortId.portId(srcPort)); + + String dstPort = nullIsIllegal(json.get(DST_PORT), DST_PORT + MISSING_MEMBER_MESSAGE).asText(); + resultBuilder.setDstPort(VirtualPortId.portId(dstPort)); + + return resultBuilder.build(); + } + + @Override + public ObjectNode encode(FlowClassifier flowClassifier, CodecContext context) { + checkNotNull(flowClassifier, "flowClassifier cannot be null"); + ObjectNode result = context.mapper().createObjectNode() + .put("FLOW_CLASSIFIER_ID", flowClassifier.flowClassifierId().toString()) + .put("TENANT_ID", flowClassifier.tenantId().toString()) + .put("NAME", flowClassifier.name()) + .put("DESCRIPTION", flowClassifier.description()) + .put("ETHER_TYPE", flowClassifier.etherType()) + .put("PROTOCOL", flowClassifier.protocol()) + .put("MIN_SRC_PORT_RANGE", flowClassifier.minSrcPortRange()) + .put("MAX_SRC_PORT_RANGE", flowClassifier.maxSrcPortRange()) + .put("MIN_DST_PORT_RANGE", flowClassifier.minDstPortRange()) + .put("MAX_DST_PORT_RANGE", flowClassifier.maxDstPortRange()) + .put("SRC_IP_PREFIX", flowClassifier.srcIpPrefix().toString()) + .put("DST_IP_PREFIX", flowClassifier.dstIpPrefix().toString()) + .put("SRC_PORT", flowClassifier.srcPort().toString()) + .put("DST_PORT", flowClassifier.dstPort().toString()); + return result; + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierIdTest.java new file mode 100644 index 00000000..b2fed347 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierIdTest.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.vtnrsc.flowclassifier; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import org.junit.Test; +import org.onosproject.vtnrsc.FlowClassifierId; + +import com.google.common.testing.EqualsTester; +import java.util.UUID; + +/** + * Unit tests for FlowClassifierId class. + */ +public class FlowClassifierIdTest { + + final FlowClassifierId flowClassifierId1 = FlowClassifierId + .flowClassifierId("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae"); + final FlowClassifierId sameAsFlowClassifierId1 = FlowClassifierId + .flowClassifierId("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae"); + final FlowClassifierId flowClassifierId2 = FlowClassifierId + .flowClassifierId("dace4513-24fc-4fae-af4b-321c5e2eb3d1"); + + /** + * Checks that the FlowClassifierId class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(FlowClassifierId.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + new EqualsTester().addEqualityGroup(flowClassifierId1, sameAsFlowClassifierId1) + .addEqualityGroup(flowClassifierId2).testEquals(); + } + + /** + * Checks the construction of a FlowClassifierId object. + */ + @Test + public void testConstruction() { + final String flowClassifierIdValue = "dace4513-24fc-4fae-af4b-321c5e2eb3d1"; + final FlowClassifierId flowClassifierId = FlowClassifierId.flowClassifierId(flowClassifierIdValue); + assertThat(flowClassifierId, is(notNullValue())); + assertThat(flowClassifierId.value(), is(UUID.fromString(flowClassifierIdValue))); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/subnet/DefaultAllocationPoolTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/subnet/DefaultAllocationPoolTest.java new file mode 100644 index 00000000..4ce4def2 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/subnet/DefaultAllocationPoolTest.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.vtnrsc.subnet; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import org.junit.Test; +import org.onlab.packet.IpAddress; +import org.onosproject.vtnrsc.AllocationPool; +import org.onosproject.vtnrsc.DefaultAllocationPool; + +import com.google.common.testing.EqualsTester; + +/** + * Unit tests for DefaultAllocationPool class. + */ +public class DefaultAllocationPoolTest { + + final IpAddress startIP1 = IpAddress.valueOf("192.168.1.1"); + final IpAddress startIP2 = IpAddress.valueOf("192.168.1.2"); + final IpAddress endIP1 = IpAddress.valueOf("192.168.1.1"); + final IpAddress endIP2 = IpAddress.valueOf("192.168.1.2"); + + /** + * Checks that the DefaultAllocationPool class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(DefaultAllocationPool.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + AllocationPool pool1 = new DefaultAllocationPool(startIP1, endIP1); + AllocationPool pool2 = new DefaultAllocationPool(startIP1, endIP1); + AllocationPool pool3 = new DefaultAllocationPool(startIP2, endIP2); + new EqualsTester().addEqualityGroup(pool1, pool2) + .addEqualityGroup(pool3).testEquals(); + } + + /** + * Checks the construction of a DefaultAllocationPool object. + */ + @Test + public void testConstruction() { + final AllocationPool apool = new DefaultAllocationPool(startIP1, endIP1); + assertThat(startIP1, is(apool.startIp())); + assertThat(endIP1, is(apool.endIp())); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/subnet/DefaultHostRouteTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/subnet/DefaultHostRouteTest.java new file mode 100644 index 00000000..2f751742 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/subnet/DefaultHostRouteTest.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.vtnrsc.subnet; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import org.junit.Test; +import org.onlab.packet.IpAddress; +import org.onlab.packet.IpPrefix; +import org.onosproject.vtnrsc.DefaultHostRoute; +import org.onosproject.vtnrsc.HostRoute; + +import com.google.common.testing.EqualsTester; + +/** + * Unit tests for DefaultHostRoute class. + */ +public class DefaultHostRouteTest { + final IpAddress nexthop1 = IpAddress.valueOf("192.168.1.1"); + final IpAddress nexthop2 = IpAddress.valueOf("192.168.1.2"); + final IpPrefix destination1 = IpPrefix.valueOf("1.1.1.1/1"); + final IpPrefix destination2 = IpPrefix.valueOf("1.1.1.1/2"); + + /** + * Checks that the DefaultHostRoute class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(DefaultHostRoute.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + HostRoute route1 = new DefaultHostRoute(nexthop1, destination1); + HostRoute route2 = new DefaultHostRoute(nexthop1, destination1); + HostRoute route3 = new DefaultHostRoute(nexthop2, destination2); + new EqualsTester().addEqualityGroup(route1, route2) + .addEqualityGroup(route3).testEquals(); + } + + /** + * Checks the construction of a DefaultHostRoute object. + */ + @Test + public void testConstruction() { + final HostRoute host = new DefaultHostRoute(nexthop1, destination1); + assertThat(nexthop1, is(host.nexthop())); + assertThat(destination1, is(host.destination())); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/subnet/SubnetIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/subnet/SubnetIdTest.java new file mode 100644 index 00000000..d18dd41a --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/subnet/SubnetIdTest.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.vtnrsc.subnet; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import org.junit.Test; +import org.onosproject.vtnrsc.SubnetId; + +import com.google.common.testing.EqualsTester; + +/** + * Unit tests for SubnetId class. + */ +public class SubnetIdTest { + + final SubnetId subnetId1 = SubnetId.subnetId("1"); + final SubnetId sameAsSubnetId1 = SubnetId.subnetId("1"); + final SubnetId subnetId2 = SubnetId.subnetId("2"); + + /** + * Checks that the SubnetId class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(SubnetId.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + new EqualsTester().addEqualityGroup(subnetId1, sameAsSubnetId1).addEqualityGroup(subnetId2) + .testEquals(); + } + + /** + * Checks the construction of a SubnetId object. + */ + @Test + public void testConstruction() { + final String subnetIdValue = "s"; + final SubnetId subnetId = SubnetId.subnetId(subnetIdValue); + assertThat(subnetId, is(notNullValue())); + assertThat(subnetId.subnetId(), is(subnetIdValue)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/DefaultNeutronNetworkTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/DefaultNeutronNetworkTest.java new file mode 100644 index 00000000..742d5933 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/DefaultNeutronNetworkTest.java @@ -0,0 +1,83 @@ +/* + * 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.vtnrsc.tenantnetwork; + +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import org.junit.Test; +import org.onosproject.vtnrsc.DefaultTenantNetwork; +import org.onosproject.vtnrsc.PhysicalNetwork; +import org.onosproject.vtnrsc.SegmentationId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.TenantNetwork; +import org.onosproject.vtnrsc.TenantNetworkId; + +import com.google.common.testing.EqualsTester; + +/** + * Unit tests for DefaultNeutronNetwork class. + */ +public class DefaultNeutronNetworkTest { + + private String networkIdStr1 = "123"; + private String networkIdStr2 = "234"; + private String physicalNetworkStr = "1234"; + private String tenantIdStr = "345"; + private String segmentationIdStr = "1"; + private String name = "456"; + + /** + * Checks that the DefaultNeutronNetwork class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(DefaultTenantNetwork.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquality() { + TenantNetworkId networkid1 = TenantNetworkId.networkId(networkIdStr1); + TenantNetworkId networkid2 = TenantNetworkId.networkId(networkIdStr2); + PhysicalNetwork physicalNetwork = PhysicalNetwork + .physicalNetwork(physicalNetworkStr); + TenantId tenantId = TenantId.tenantId(tenantIdStr); + SegmentationId segmentationID = SegmentationId + .segmentationId(segmentationIdStr); + TenantNetwork p1 = new DefaultTenantNetwork(networkid1, name, false, + TenantNetwork.State.ACTIVE, + false, tenantId, false, + TenantNetwork.Type.LOCAL, + physicalNetwork, + segmentationID); + TenantNetwork p2 = new DefaultTenantNetwork(networkid1, name, false, + TenantNetwork.State.ACTIVE, + false, tenantId, false, + TenantNetwork.Type.LOCAL, + physicalNetwork, + segmentationID); + TenantNetwork p3 = new DefaultTenantNetwork(networkid2, name, false, + TenantNetwork.State.ACTIVE, + false, tenantId, false, + TenantNetwork.Type.LOCAL, + physicalNetwork, + segmentationID); + new EqualsTester().addEqualityGroup(p1, p2).addEqualityGroup(p3) + .testEquals(); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/PhysicalNetworkTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/PhysicalNetworkTest.java new file mode 100644 index 00000000..e101795e --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/PhysicalNetworkTest.java @@ -0,0 +1,65 @@ +/* + * 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.vtnrsc.tenantnetwork; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import org.junit.Test; +import org.onosproject.vtnrsc.PhysicalNetwork; + +import com.google.common.testing.EqualsTester; + +/** + * Unit tests for PhysicalNetwork class. + */ +public class PhysicalNetworkTest { + + final PhysicalNetwork physicalNetwork1 = PhysicalNetwork.physicalNetwork("1"); + final PhysicalNetwork sameAsPhysicalNetwork1 = PhysicalNetwork.physicalNetwork("1"); + final PhysicalNetwork physicalNetwork2 = PhysicalNetwork.physicalNetwork("2"); + + /** + * Checks that the PhysicalNetwork class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(PhysicalNetwork.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + new EqualsTester().addEqualityGroup(physicalNetwork1, sameAsPhysicalNetwork1) + .addEqualityGroup(physicalNetwork2).testEquals(); + } + + /** + * Checks the construction of a PhysicalNetwork object. + */ + @Test + public void testConstruction() { + final String physicalNetworkValue = "s"; + final PhysicalNetwork physicalNetwork = PhysicalNetwork + .physicalNetwork(physicalNetworkValue); + assertThat(physicalNetwork, is(notNullValue())); + assertThat(physicalNetwork.physicalNetwork(), is(physicalNetworkValue)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/SegmentationIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/SegmentationIdTest.java new file mode 100644 index 00000000..dea7baf6 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/SegmentationIdTest.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.vtnrsc.tenantnetwork; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import org.junit.Test; +import org.onosproject.vtnrsc.SegmentationId; + +import com.google.common.testing.EqualsTester; + +/** + * Unit tests for SegmentationId class. + */ +public class SegmentationIdTest { + + final SegmentationId segmentationID1 = SegmentationId.segmentationId("1"); + final SegmentationId sameAsSegmentationID1 = SegmentationId.segmentationId("1"); + final SegmentationId segmentationID2 = SegmentationId.segmentationId("2"); + + /** + * Checks that the SegmentationId class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(SegmentationId.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + new EqualsTester().addEqualityGroup(segmentationID1, sameAsSegmentationID1) + .addEqualityGroup(segmentationID2).testEquals(); + } + + /** + * Checks the construction of a segmentationId object. + */ + @Test + public void testConstruction() { + final String segmentationIdValue = "s"; + final SegmentationId segmentationId = SegmentationId.segmentationId(segmentationIdValue); + assertThat(segmentationId, is(notNullValue())); + assertThat(segmentationId.segmentationId(), is(segmentationIdValue)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/TenantIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/TenantIdTest.java new file mode 100644 index 00000000..e9216383 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/TenantIdTest.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.vtnrsc.tenantnetwork; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import org.junit.Test; +import org.onosproject.vtnrsc.TenantId; + +import com.google.common.testing.EqualsTester; + +/** + * Unit tests for TenantId class. + */ +public class TenantIdTest { + + final TenantId tenantId1 = TenantId.tenantId("1"); + final TenantId sameAsTenantId1 = TenantId.tenantId("1"); + final TenantId tenantId2 = TenantId.tenantId("2"); + + /** + * Checks that the TenantId class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(TenantId.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + new EqualsTester().addEqualityGroup(tenantId1, sameAsTenantId1).addEqualityGroup(tenantId2) + .testEquals(); + } + + /** + * Checks the construction of a TenantId object. + */ + @Test + public void testConstruction() { + final String tenantIdValue = "s"; + final TenantId tenantId = TenantId.tenantId(tenantIdValue); + assertThat(tenantId, is(notNullValue())); + assertThat(tenantId.tenantId(), is(tenantIdValue)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/TenantNetworkIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/TenantNetworkIdTest.java new file mode 100644 index 00000000..8271b51c --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/TenantNetworkIdTest.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.vtnrsc.tenantnetwork; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import org.junit.Test; +import org.onosproject.vtnrsc.TenantNetworkId; + +import com.google.common.testing.EqualsTester; + +/** + * Unit tests for TenantNetworkId class. + */ +public class TenantNetworkIdTest { + + final TenantNetworkId networkId1 = TenantNetworkId.networkId("1"); + final TenantNetworkId sameAsnetworkId1 = TenantNetworkId.networkId("1"); + final TenantNetworkId networkId2 = TenantNetworkId.networkId("2"); + + /** + * Checks that the TenantNetworkId class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(TenantNetworkId.class); + } + + /** + * Checks the operation of equals() methods. + */ + @Test + public void testEquals() { + new EqualsTester().addEqualityGroup(networkId1, sameAsnetworkId1) + .addEqualityGroup(networkId2).testEquals(); + } + + /** + * Checks the construction of a TenantNetworkId object. + */ + @Test + public void testConstruction() { + final String networkIdValue = "s"; + final TenantNetworkId networkId = TenantNetworkId.networkId(networkIdValue); + assertThat(networkId, is(notNullValue())); + assertThat(networkId.networkId(), is(networkIdValue)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/AllowedAddressPairTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/AllowedAddressPairTest.java new file mode 100644 index 00000000..dabe5896 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/AllowedAddressPairTest.java @@ -0,0 +1,76 @@ +/* + * 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.vtnrsc.virtualport; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import org.junit.Test; +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onosproject.vtnrsc.AllowedAddressPair; + +import com.google.common.testing.EqualsTester; + +/** + * Unit tests for AllowedAddressPair class. + */ +public class AllowedAddressPairTest { + + final IpAddress ip1 = IpAddress.valueOf("192.168.0.1"); + final IpAddress ip2 = IpAddress.valueOf("192.168.0.2"); + final MacAddress mac1 = MacAddress.valueOf("fa:16:3e:76:83:88"); + final MacAddress mac2 = MacAddress.valueOf("aa:16:3e:76:83:88"); + + /** + * Checks that the AllowedAddressPair class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(AllowedAddressPair.class); + } + + /** + * Checks the operation of equals(). + */ + @Test + public void testEquals() { + AllowedAddressPair p1 = AllowedAddressPair + .allowedAddressPair(ip1, mac1); + AllowedAddressPair p2 = AllowedAddressPair + .allowedAddressPair(ip1, mac1); + AllowedAddressPair p3 = AllowedAddressPair + .allowedAddressPair(ip2, mac2); + new EqualsTester().addEqualityGroup(p1, p2).addEqualityGroup(p3) + .testEquals(); + } + + /** + * Checks the construction of a AllowedAddressPair object. + */ + @Test + public void testConstruction() { + AllowedAddressPair allowedAddressPair = AllowedAddressPair + .allowedAddressPair(ip1, mac1); + assertThat(ip1, is(notNullValue())); + assertThat(ip1, is(allowedAddressPair.ip())); + assertThat(mac1, is(notNullValue())); + assertThat(mac1, is(allowedAddressPair.mac())); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/DefaultVirtualPortTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/DefaultVirtualPortTest.java new file mode 100644 index 00000000..8a0c8004 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/DefaultVirtualPortTest.java @@ -0,0 +1,142 @@ +/* + * 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.vtnrsc.virtualport; + +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import java.util.Map; +import java.util.Set; + +import org.junit.Test; +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onosproject.net.DeviceId; +import org.onosproject.vtnrsc.AllowedAddressPair; +import org.onosproject.vtnrsc.BindingHostId; +import org.onosproject.vtnrsc.DefaultVirtualPort; +import org.onosproject.vtnrsc.FixedIp; +import org.onosproject.vtnrsc.SecurityGroup; +import org.onosproject.vtnrsc.SubnetId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.TenantNetworkId; +import org.onosproject.vtnrsc.VirtualPort; +import org.onosproject.vtnrsc.VirtualPortId; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.common.testing.EqualsTester; + +/** + * Unit tests for DefaultVirtualPort class. + */ +public class DefaultVirtualPortTest { + + private Set<FixedIp> fixedIps; + private Map<String, String> propertyMap; + private Set<AllowedAddressPair> allowedAddressPairs; + private Set<SecurityGroup> securityGroups; + private VirtualPortId id1; + private VirtualPortId id2; + private String macAddressStr = "fa:12:3e:56:ee:a2"; + private String ipAddress = "10.1.1.1"; + private String deviceStr = "of:000000000000001"; + private String tenantIdStr = "123"; + private String portId1 = "1241"; + private String portId2 = "1242"; + private String tenantNetworkId = "1234567"; + private String subnet = "1212"; + private String hostIdStr = "fa:e2:3e:56:ee:a2"; + + private void initVirtualPortId() { + id1 = VirtualPortId.portId(portId1); + id2 = VirtualPortId.portId(portId2); + } + + private void initFixedIpSet() { + FixedIp fixedIp = FixedIp.fixedIp(SubnetId.subnetId(subnet), + IpAddress.valueOf(ipAddress)); + fixedIps = Sets.newHashSet(); + fixedIps.add(fixedIp); + } + + private void initPropertyMap() { + String deviceOwner = "james"; + propertyMap = Maps.newHashMap(); + propertyMap.putIfAbsent("deviceOwner", deviceOwner); + } + + private void initAddressPairSet() { + allowedAddressPairs = Sets.newHashSet(); + AllowedAddressPair allowedAddressPair = AllowedAddressPair + .allowedAddressPair(IpAddress.valueOf(ipAddress), + MacAddress.valueOf(macAddressStr)); + allowedAddressPairs.add(allowedAddressPair); + } + + private void initSecurityGroupSet() { + securityGroups = Sets.newHashSet(); + } + + /** + * Checks that the DefaultVirtualPort class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(SecurityGroup.class); + } + + /** + * Checks the operation of equals(). + */ + @Test + public void testEquals() { + initVirtualPortId(); + initFixedIpSet(); + initPropertyMap(); + initAddressPairSet(); + initSecurityGroupSet(); + TenantNetworkId networkId = TenantNetworkId.networkId(tenantNetworkId); + MacAddress macAddress = MacAddress.valueOf(macAddressStr); + TenantId tenantId = TenantId.tenantId(tenantIdStr); + DeviceId deviceId = DeviceId.deviceId(deviceStr); + BindingHostId bindingHostId = BindingHostId.bindingHostId(hostIdStr); + + VirtualPort d1 = new DefaultVirtualPort(id1, networkId, true, + propertyMap, + VirtualPort.State.ACTIVE, + macAddress, tenantId, deviceId, + fixedIps, bindingHostId, + allowedAddressPairs, + securityGroups); + VirtualPort d2 = new DefaultVirtualPort(id1, networkId, true, + propertyMap, + VirtualPort.State.ACTIVE, + macAddress, tenantId, deviceId, + fixedIps, bindingHostId, + allowedAddressPairs, + securityGroups); + VirtualPort d3 = new DefaultVirtualPort(id2, networkId, true, + propertyMap, + VirtualPort.State.ACTIVE, + macAddress, tenantId, deviceId, + fixedIps, bindingHostId, + allowedAddressPairs, + securityGroups); + new EqualsTester().addEqualityGroup(d1, d2).addEqualityGroup(d3) + .testEquals(); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/FixedIpTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/FixedIpTest.java new file mode 100644 index 00000000..1e33da09 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/FixedIpTest.java @@ -0,0 +1,72 @@ +/* + * 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.vtnrsc.virtualport; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import org.junit.Test; +import org.onlab.packet.IpAddress; +import org.onosproject.vtnrsc.FixedIp; +import org.onosproject.vtnrsc.SubnetId; + +import com.google.common.testing.EqualsTester; + +/** + * Unit tests for FixedIp class. + */ +public class FixedIpTest { + + final SubnetId subnetId1 = SubnetId.subnetId("lef11-95w-4er-9c9c"); + final SubnetId subnetId2 = SubnetId.subnetId("lefaa-95w-4er-9c9c"); + final IpAddress ip1 = IpAddress.valueOf("192.168.0.1"); + final IpAddress ip2 = IpAddress.valueOf("192.168.1.1"); + + /** + * Checks that the FixedIp class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(FixedIp.class); + } + + /** + * Checks the operation of equals(). + */ + @Test + public void testEquals() { + FixedIp fixedIp1 = FixedIp.fixedIp(subnetId1, ip1); + FixedIp fixedIp2 = FixedIp.fixedIp(subnetId1, ip1); + FixedIp fixedIp3 = FixedIp.fixedIp(subnetId2, ip2); + new EqualsTester().addEqualityGroup(fixedIp1, fixedIp2) + .addEqualityGroup(fixedIp3).testEquals(); + } + + /** + * Checks the construction of a FixedIp object. + */ + @Test + public void testConstruction() { + FixedIp fixedIp = FixedIp.fixedIp(subnetId1, ip1); + assertThat(ip1, is(notNullValue())); + assertThat(ip1, is(fixedIp.ip())); + assertThat(subnetId1, is(notNullValue())); + assertThat(subnetId1, is(fixedIp.subnetId())); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/SecurityGroupTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/SecurityGroupTest.java new file mode 100644 index 00000000..8c04e499 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/SecurityGroupTest.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.vtnrsc.virtualport; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import org.junit.Test; +import org.onosproject.vtnrsc.SecurityGroup; + +import com.google.common.testing.EqualsTester; + +/** + * Unit tests for SecurityGroup class. + */ +public class SecurityGroupTest { + + final SecurityGroup securityGroup1 = SecurityGroup.securityGroup("1"); + final SecurityGroup sameAssecurityGroup = SecurityGroup.securityGroup("1"); + final SecurityGroup securityGroup2 = SecurityGroup.securityGroup("2"); + + /** + * Checks that the SecurityGroup class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(SecurityGroup.class); + } + + /** + * Checks the operation of equals(). + */ + @Test + public void testEquals() { + new EqualsTester().addEqualityGroup(securityGroup1, sameAssecurityGroup) + .addEqualityGroup(securityGroup2).testEquals(); + } + + /** + * Checks the construction of a SecurityGroup object. + */ + @Test + public void testConstruction() { + final String securityGroupValue = "1"; + final SecurityGroup securityGroup = SecurityGroup.securityGroup(securityGroupValue); + assertThat(securityGroup, is(notNullValue())); + assertThat(securityGroup.securityGroup(), is(securityGroupValue)); + + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/VirtualPortIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/VirtualPortIdTest.java new file mode 100644 index 00000000..2d63e91c --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/VirtualPortIdTest.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.vtnrsc.virtualport; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; + +import org.junit.Test; +import org.onosproject.vtnrsc.VirtualPortId; + +import com.google.common.testing.EqualsTester; + +/** + * Unit tests for VirtualPortId class. + */ +public class VirtualPortIdTest { + + final VirtualPortId virtualPortId1 = VirtualPortId.portId("1"); + final VirtualPortId sameAsVirtualPortId1 = VirtualPortId.portId("1"); + final VirtualPortId virtualPortId2 = VirtualPortId.portId("2"); + + /** + * Checks that the VirtualPortId class is immutable. + */ + @Test + public void testImmutability() { + assertThatClassIsImmutable(VirtualPortId.class); + } + + /** + * Checks the operation of equals(). + */ + @Test + public void testEquals() { + new EqualsTester().addEqualityGroup(virtualPortId1, sameAsVirtualPortId1) + .addEqualityGroup(virtualPortId2).testEquals(); + } + + /** + * Checks the construction of a VirtualPortId object. + */ + @Test + public void testConstruction() { + final String vPortIdValue = "aaa"; + final VirtualPortId virtualPortId = VirtualPortId.portId(vPortIdValue); + assertThat(virtualPortId, is(notNullValue())); + assertThat(virtualPortId.portId(), is(vPortIdValue)); + + } +} diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FlowClassifierWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FlowClassifierWebResource.java new file mode 100644 index 00000000..1450e4ef --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FlowClassifierWebResource.java @@ -0,0 +1,192 @@ +/* + * 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.vtnweb.resources; + +import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; +import static org.onlab.util.Tools.nullIsNotFound; +import static javax.ws.rs.core.Response.Status.NOT_FOUND; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.UUID; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +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 org.onosproject.vtnrsc.FlowClassifier; +import org.onosproject.vtnrsc.FlowClassifierId; +import org.onosproject.rest.AbstractWebResource; +import org.onosproject.vtnrsc.flowClassifier.FlowClassifierService; +import org.onosproject.vtnrsc.web.FlowClassifierCodec; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * Query and program flow classifier. + */ +@Path("flow_classifiers") +public class FlowClassifierWebResource extends AbstractWebResource { + + final FlowClassifierService service = get(FlowClassifierService.class); + final ObjectNode root = mapper().createObjectNode(); + public static final String FLOW_CLASSIFIER_NOT_FOUND = "Flow classifier not found"; + + /** + * Get all flow classifiers created. Returns list of all flow classifiers + * created. + * + * @return 200 OK + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + public Response getFlowClassifiers() { + Iterable<FlowClassifier> flowClassifiers = service.getFlowClassifiers(); + ObjectNode result = new ObjectMapper().createObjectNode(); + result.set("flow_classifiers", new FlowClassifierCodec().encode(flowClassifiers, this)); + return ok(result.toString()).build(); + } + + /** + * Get details of a flow classifier. Returns details of a specified flow + * classifier id. + * + * @param id flow classifier id + * @return 200 OK + */ + @GET + @Path("{flow_id}") + @Produces(MediaType.APPLICATION_JSON) + public Response getFlowClassifier(@PathParam("flow_id") String id) { + + if (!service.hasFlowClassifier(FlowClassifierId.flowClassifierId(UUID.fromString(id)))) { + return Response.status(NOT_FOUND).entity(FLOW_CLASSIFIER_NOT_FOUND).build(); + } + FlowClassifier flowClassifier = nullIsNotFound( + service.getFlowClassifier(FlowClassifierId.flowClassifierId(UUID.fromString(id))), + FLOW_CLASSIFIER_NOT_FOUND); + + ObjectNode result = new ObjectMapper().createObjectNode(); + result.set("flow_classifier", new FlowClassifierCodec().encode(flowClassifier, this)); + return ok(result.toString()).build(); + } + + /** + * Creates and stores a new flow classifier. + * + * @param flowClassifierId flow classifier identifier + * @param stream flow classifier from JSON + * @return status of the request - CREATED if the JSON is correct, + * BAD_REQUEST if the JSON is invalid + */ + @POST + @Path("{flow_id}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response createFlowClassifier(@PathParam("flow_id") String flowClassifierId, InputStream stream) { + URI location; + try { + ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); + + FlowClassifier flowClassifier = codec(FlowClassifier.class).decode(jsonTree, this); + service.createFlowClassifier(flowClassifier); + location = new URI(flowClassifierId); + } catch (IOException | URISyntaxException ex) { + throw new IllegalArgumentException(ex); + } + return Response.created(location).build(); + } + + /** + * Creates and stores a new flow classifier. + * + * @param stream flow classifier from JSON + * @return status of the request - CREATED if the JSON is correct, + * BAD_REQUEST if the JSON is invalid + */ + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response createFlowClassifier(InputStream stream) { + URI location; + try { + ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); + + FlowClassifier flowClassifier = codec(FlowClassifier.class).decode(jsonTree, this); + service.createFlowClassifier(flowClassifier); + location = new URI(flowClassifier.flowClassifierId().toString()); + } catch (IOException | URISyntaxException ex) { + throw new IllegalArgumentException(ex); + } + return Response.created(location).build(); + } + + /** + * Update details of a flow classifier. Update details of a specified flow + * classifier id. + * + * @param id flow classifier id + * @param stream InputStream + * @return 200 OK + */ + @PUT + @Path("{flow_id}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public Response updateFlowClassifier(@PathParam("flow_id") String id, final InputStream stream) { + try { + ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); + FlowClassifier flowClassifier = codec(FlowClassifier.class).decode(jsonTree, this); + Boolean result = nullIsNotFound(service.updateFlowClassifier(flowClassifier), FLOW_CLASSIFIER_NOT_FOUND); + if (!result) { + return Response.status(204).entity(FLOW_CLASSIFIER_NOT_FOUND).build(); + } + return Response.status(203).entity(result.toString()).build(); + } catch (Exception e) { + return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString()).build(); + } + } + + /** + * Delete details of a flow classifier. Delete details of a specified flow + * classifier id. + * + * @param id flow classifier id + * @return 200 OK + * @throws IOException when input doesn't match. + */ + @Path("{flow_id}") + @DELETE + public Response deleteFlowClassifier(@PathParam("flow_id") String id) throws IOException { + try { + FlowClassifierId flowClassifierId = FlowClassifierId.flowClassifierId(UUID.fromString(id)); + service.removeFlowClassifier(flowClassifierId); + return Response.status(201).entity("SUCCESS").build(); + } catch (Exception e) { + return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString()).build(); + } + } +} diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/SubnetWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/SubnetWebResource.java index 251dcffc..0cc59a4e 100644 --- a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/SubnetWebResource.java +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/SubnetWebResource.java @@ -56,7 +56,7 @@ import org.onosproject.vtnrsc.TenantId; import org.onosproject.vtnrsc.TenantNetworkId; import org.onosproject.vtnrsc.Subnet.Mode; import org.onosproject.vtnrsc.subnet.SubnetService; -import org.onosproject.vtnrsc.web.SubnetCodec; +import org.onosproject.vtnweb.web.SubnetCodec; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java index 0b877822..2dd931ea 100644 --- a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java @@ -51,7 +51,7 @@ import org.onosproject.vtnrsc.TenantNetworkId; import org.onosproject.vtnrsc.TenantNetwork.State; import org.onosproject.vtnrsc.TenantNetwork.Type; import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService; -import org.onosproject.vtnrsc.web.TenantNetworkCodec; +import org.onosproject.vtnweb.web.TenantNetworkCodec; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/VirtualPortWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/VirtualPortWebResource.java index 03d3a653..e47a57df 100644 --- a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/VirtualPortWebResource.java +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/VirtualPortWebResource.java @@ -58,7 +58,7 @@ import org.onosproject.vtnrsc.VirtualPort; import org.onosproject.vtnrsc.VirtualPort.State; import org.onosproject.vtnrsc.VirtualPortId; import org.onosproject.vtnrsc.virtualport.VirtualPortService; -import org.onosproject.vtnrsc.web.VirtualPortCodec; +import org.onosproject.vtnweb.web.VirtualPortCodec; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/AllocationPoolsCodec.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/AllocationPoolsCodec.java index 57c97c1c..4b6b662f 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/AllocationPoolsCodec.java +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/AllocationPoolsCodec.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.vtnrsc.web; +package org.onosproject.vtnweb.web; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/AllowedAddressPairCodec.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/AllowedAddressPairCodec.java index 7960808f..8ffc4e91 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/AllowedAddressPairCodec.java +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/AllowedAddressPairCodec.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.vtnrsc.web; +package org.onosproject.vtnweb.web; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/FixedIpCodec.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/FixedIpCodec.java index 96c9bb4e..559de685 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/FixedIpCodec.java +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/FixedIpCodec.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.vtnrsc.web; +package org.onosproject.vtnweb.web; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/HostRoutesCodec.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/HostRoutesCodec.java index 69ca6b3f..815a0d02 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/HostRoutesCodec.java +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/HostRoutesCodec.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.vtnrsc.web; +package org.onosproject.vtnweb.web; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/PortChainCodec.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/PortChainCodec.java new file mode 100644 index 00000000..28da5cd1 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/PortChainCodec.java @@ -0,0 +1,105 @@ +/* + * 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.vtnweb.web; + + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.onlab.util.Tools.nullIsIllegal; + +import java.util.List; +import java.util.UUID; + +import org.onosproject.codec.CodecContext; +import org.onosproject.codec.JsonCodec; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.DefaultPortChain; +import org.onosproject.vtnrsc.FlowClassifierId; +import org.onosproject.vtnrsc.PortChain; +import org.onosproject.vtnrsc.PortChainId; +import org.onosproject.vtnrsc.PortPairGroupId; + +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.collect.Lists; + +/** + * Port chain JSON codec. + */ +public final class PortChainCodec extends JsonCodec<PortChain> { + + private static final String ID = "id"; + private static final String TENANT_ID = "tenant_id"; + private static final String NAME = "name"; + private static final String DESCRIPTION = "description"; + private static final String PORT_PAIR_GROUPS = "port_pair_groups"; + private static final String FLOW_CLASSIFIERS = "flow_classifiers"; + private static final String MISSING_MEMBER_MESSAGE = + " member is required in PortChain"; + + @Override + public PortChain decode(ObjectNode json, CodecContext context) { + if (json == null || !json.isObject()) { + return null; + } + + PortChain.Builder resultBuilder = new DefaultPortChain.Builder(); + + String id = nullIsIllegal(json.get(ID), + ID + MISSING_MEMBER_MESSAGE).asText(); + resultBuilder.setId(PortChainId.portChainId(id)); + + String tenantId = nullIsIllegal(json.get(TENANT_ID), + TENANT_ID + MISSING_MEMBER_MESSAGE).asText(); + resultBuilder.setTenantId(TenantId.tenantId(tenantId)); + + String name = nullIsIllegal(json.get(NAME), + NAME + MISSING_MEMBER_MESSAGE).asText(); + resultBuilder.setName(name); + + String description = nullIsIllegal(json.get(DESCRIPTION), + DESCRIPTION + MISSING_MEMBER_MESSAGE).asText(); + resultBuilder.setDescription(description); + + ArrayNode arrayNode = (ArrayNode) json.path(PORT_PAIR_GROUPS); + if (arrayNode != null) { + List<PortPairGroupId> list = Lists.newArrayList(); + arrayNode.forEach(i -> list.add(PortPairGroupId.portPairGroupId(i.asText()))); + resultBuilder.setPortPairGroups(list); + } + + arrayNode = (ArrayNode) json.path(FLOW_CLASSIFIERS); + if (arrayNode != null) { + List<FlowClassifierId> list = Lists.newArrayList(); + arrayNode.forEach(i -> list.add(FlowClassifierId.flowClassifierId(UUID.fromString(i.asText())))); + resultBuilder.setFlowClassifiers(list); + } + + return resultBuilder.build(); + } + + @Override + public ObjectNode encode(PortChain portChain, CodecContext context) { + checkNotNull(portChain, "port pair cannot be null"); + ObjectNode result = context.mapper().createObjectNode() + .put(ID, portChain.portChainId().toString()) + .put(TENANT_ID, portChain.tenantId().toString()) + .put(NAME, portChain.name()) + .put(DESCRIPTION, portChain.description()) + .put(PORT_PAIR_GROUPS, portChain.portPairGroups().toString()) + .put(FLOW_CLASSIFIERS, portChain.flowClassifiers().toString()); + return result; + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/SecurityGroupCodec.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/SecurityGroupCodec.java index c2ded196..18ed61ba 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/SecurityGroupCodec.java +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/SecurityGroupCodec.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.vtnrsc.web; +package org.onosproject.vtnweb.web; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/SubnetCodec.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/SubnetCodec.java index 122b75a9..e3d92fea 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/SubnetCodec.java +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/SubnetCodec.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.vtnrsc.web; +package org.onosproject.vtnweb.web; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/TenantNetworkCodec.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/TenantNetworkCodec.java index 48ba3b97..8adba034 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/TenantNetworkCodec.java +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/TenantNetworkCodec.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.vtnrsc.web; +package org.onosproject.vtnweb.web; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/VirtualPortCodec.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/VirtualPortCodec.java index e57d56bc..5cea5327 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/VirtualPortCodec.java +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/VirtualPortCodec.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.vtnrsc.web; +package org.onosproject.vtnweb.web; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/package-info.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/package-info.java new file mode 100644 index 00000000..3a609435 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/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. + */ + +/** + * Codecs for virtual tenant objects. + */ +package org.onosproject.vtnweb.web; |