aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/apps/vtn
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/apps/vtn')
-rw-r--r--framework/src/onos/apps/vtn/pom.xml6
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/ServiceFunctionForwarderService.java (renamed from framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/ServiceFunctionForwarder.java)28
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/impl/ServiceFunctionForwarderImpl.java293
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/impl/package-info.java20
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/NshSpiIdGenerators.java51
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/SfcService.java37
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java159
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/manager/impl/SfcManagerTest.java269
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowClassifierManagerTestImpl.java93
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowObjectiveServiceTestImpl.java53
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortChainManagerTestImpl.java85
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairGroupManagerTestImpl.java89
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairManagerTestImpl.java89
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortManagerTestImpl.java98
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VtnRscManagerTestImpl.java72
-rw-r--r--framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java29
-rw-r--r--framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java476
-rw-r--r--framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java6
-rw-r--r--framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ArpServiceImpl.java113
-rw-r--r--framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java82
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/ClassifierService.java41
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/impl/ClassifierManager.java78
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/impl/package-info.java20
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/package-info.java20
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetCreateCommand.java2
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetUpdateCommand.java2
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java50
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java133
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/FloatingIpManager.java59
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierEvent.java63
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierListener.java25
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierService.java3
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/impl/FlowClassifierManager.java18
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainEvent.java63
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainListener.java25
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainService.java3
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/impl/PortChainManager.java10
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairEvent.java63
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairListener.java25
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairService.java14
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/impl/PortPairManager.java22
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupEvent.java63
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupListener.java25
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupService.java14
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/impl/PortPairGroupManager.java22
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/VtnRscService.java18
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java152
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortService.java10
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java22
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FlowClassifierWebResource.java27
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortChainWebResource.java45
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairGroupWebResource.java51
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairWebResource.java39
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/VtnCodecRegistrator.java56
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/FlowClassifierResourceTest.java9
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortChainResourceTest.java247
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairGroupResourceTest.java234
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairResourceTest.java7
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/SfcCodecContext.java41
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortChain.json15
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortPairGroup.json11
61 files changed, 3729 insertions, 266 deletions
diff --git a/framework/src/onos/apps/vtn/pom.xml b/framework/src/onos/apps/vtn/pom.xml
index a42f91a0..e4528517 100644
--- a/framework/src/onos/apps/vtn/pom.xml
+++ b/framework/src/onos/apps/vtn/pom.xml
@@ -61,6 +61,12 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-api</artifactId>
+ <scope>test</scope>
+ <classifier>tests</classifier>
+ </dependency>
+ <dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
</dependency>
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/ServiceFunctionForwarder.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/ServiceFunctionForwarderService.java
index e91e6b69..0ed42fcf 100644
--- a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/ServiceFunctionForwarder.java
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/ServiceFunctionForwarderService.java
@@ -15,29 +15,37 @@
*/
package org.onosproject.sfc.forwarder;
-import org.onosproject.core.ApplicationId;
import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.NshServicePathId;
import org.onosproject.vtnrsc.PortChain;
/**
* Abstraction of an entity which provides Service function forwarder.
*/
-public interface ServiceFunctionForwarder {
+public interface ServiceFunctionForwarderService {
/**
- * Install Service function chain.
+ * Install Forwarding rule.
*
- * @param portChain Port chain
+ * @param portChain port-chain
+ * @param nshSPI nsh spi
*/
- void install(PortChain portChain);
+ void installForwardingRule(PortChain portChain, NshServicePathId nshSPI);
/**
- * Programs forwarding object for Service Function.
+ * Uninstall Forwarding rule.
*
- * @param portChain port chain
- * @param appid application id
+ * @param portChain port-chain
+ * @param nshSPI nsh spi
+ */
+ void unInstallForwardingRule(PortChain portChain, NshServicePathId nshSPI);
+
+ /**
+ * Prepare forwarding object for Service Function.
+ *
+ * @param portChain port-chain
+ * @param nshSPI nsh spi
* @param type forwarding objective operation type
*/
- void programServiceFunctionForwarder(PortChain portChain, ApplicationId appid,
- Objective.Operation type);
+ void prepareServiceFunctionForwarder(PortChain portChain, NshServicePathId nshSPI, Objective.Operation type);
}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/impl/ServiceFunctionForwarderImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/impl/ServiceFunctionForwarderImpl.java
new file mode 100644
index 00000000..2846ee01
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/impl/ServiceFunctionForwarderImpl.java
@@ -0,0 +1,293 @@
+/*
+ * 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.forwarder.impl;
+
+import static org.slf4j.LoggerFactory.getLogger;
+import static org.onosproject.net.flow.criteria.ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SPI;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+import java.util.ListIterator;
+
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.osgi.DefaultServiceDirectory;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.behaviour.ExtensionSelectorResolver;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.NshServicePathId;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.driver.DriverService;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.criteria.ExtensionSelector;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.ForwardingObjective.Flag;
+import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.service.VtnRscService;
+import org.onosproject.vtnrsc.PortChain;
+import org.onosproject.vtnrsc.PortPair;
+import org.onosproject.vtnrsc.PortPairGroup;
+import org.onosproject.vtnrsc.PortPairGroupId;
+import org.onosproject.vtnrsc.PortPairId;
+import org.onosproject.vtnrsc.virtualport.VirtualPortService;
+import org.onosproject.vtnrsc.portpair.PortPairService;
+import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
+import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService;
+import org.onosproject.vtnrsc.portchain.PortChainService;
+import org.onosproject.sfc.forwarder.ServiceFunctionForwarderService;
+
+import org.slf4j.Logger;
+
+/**
+ * Provides Service Function Forwarder implementation.
+ */
+public class ServiceFunctionForwarderImpl implements ServiceFunctionForwarderService {
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DriverService driverService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected VirtualPortService virtualPortService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected VtnRscService vtnRscService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PortPairService portPairService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PortPairGroupService portPairGroupService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected FlowClassifierService flowClassifierService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PortChainService portChainService;
+
+ private final Logger log = getLogger(getClass());
+ protected ApplicationId appId;
+ protected FlowObjectiveService flowObjectiveService;
+
+ private static final String DRIVER_NAME = "onosfw";
+ private static final String PORT_CHAIN_NOT_NULL = "Port-Chain cannot be null";
+ private static final String PORT_CHAIN_ID_NOT_NULL = "Port-Chain-Id cannot be null";
+ private static final String APP_ID_NOT_NULL = "Application-Id cannot be null";
+ private static final int NULL = 0;
+
+ /**
+ * Default constructor.
+ */
+ public ServiceFunctionForwarderImpl() {
+ }
+
+ /**
+ * Explicit constructor.
+ */
+ public ServiceFunctionForwarderImpl(ApplicationId appId) {
+ this.appId = checkNotNull(appId, APP_ID_NOT_NULL);
+ ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
+ this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class);
+ }
+
+ @Override
+ public void installForwardingRule(PortChain portChain, NshServicePathId nshSPI) {
+ checkNotNull(portChain, PORT_CHAIN_NOT_NULL);
+ prepareServiceFunctionForwarder(portChain, nshSPI, Objective.Operation.ADD);
+ }
+
+ @Override
+ public void unInstallForwardingRule(PortChain portChain, NshServicePathId nshSPI) {
+ checkNotNull(portChain, PORT_CHAIN_NOT_NULL);
+ prepareServiceFunctionForwarder(portChain, nshSPI, Objective.Operation.REMOVE);
+ }
+
+ @Override
+ public void prepareServiceFunctionForwarder(PortChain portChain, NshServicePathId nshSPI,
+ Objective.Operation type) {
+
+ // Go through the port pair group list
+ List<PortPairGroupId> portPairGrpList = portChain.portPairGroups();
+ ListIterator<PortPairGroupId> listGrpIterator = portPairGrpList.listIterator();
+
+ // Get source port pair group
+ if (!listGrpIterator.hasNext()) {
+ return;
+ }
+ PortPairGroupId portPairGrpId = listGrpIterator.next();
+ PortPairGroup currentPortPairGroup = portPairGroupService.getPortPairGroup(portPairGrpId);
+
+ // Get destination port pair group
+ if (!listGrpIterator.hasNext()) {
+ return;
+ }
+ portPairGrpId = listGrpIterator.next();
+ PortPairGroup nextPortPairGroup = portPairGroupService.getPortPairGroup(portPairGrpId);
+
+ // push SFF to OVS
+ pushServiceFunctionForwarder(currentPortPairGroup, nextPortPairGroup, listGrpIterator, nshSPI, type);
+ }
+
+ /**
+ * Push service-function-forwarder to OVS.
+ *
+ * @param currentPortPairGroup current port-pair-group
+ * @param nextPortPairGroup next port-pair-group
+ * @param listGrpIterator pointer to port-pair-group list
+ */
+ public void pushServiceFunctionForwarder(PortPairGroup currentPortPairGroup, PortPairGroup nextPortPairGroup,
+ ListIterator<PortPairGroupId> listGrpIterator, NshServicePathId nshSPI, Objective.Operation type) {
+ MacAddress srcMacAddress = null;
+ MacAddress dstMacAddress = null;
+ DeviceId deviceId = null;
+ DeviceId currentDeviceId = null;
+ DeviceId nextDeviceId = null;
+ PortPairGroupId portPairGrpId = null;
+
+ // Travel from SF to SF.
+ do {
+ // Get the required information on port pairs from source port pair
+ // group
+ List<PortPairId> portPairList = currentPortPairGroup.portPairs();
+ ListIterator<PortPairId> portPLIterator = portPairList.listIterator();
+ if (!portPLIterator.hasNext()) {
+ break;
+ }
+
+ PortPairId portPairId = portPLIterator.next();
+ PortPair portPair = portPairService.getPortPair(portPairId);
+
+ currentDeviceId = vtnRscService.getSFToSFFMaping(VirtualPortId.portId(portPair.ingress()));
+ if (deviceId == null) {
+ deviceId = currentDeviceId;
+ }
+ srcMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.ingress())).macAddress();
+ dstMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.egress())).macAddress();
+
+ // pack traffic selector
+ TrafficSelector.Builder selector = packTrafficSelector(deviceId, srcMacAddress, dstMacAddress, nshSPI);
+
+ // Get the required information on port pairs from destination port
+ // pair group
+ portPairList = nextPortPairGroup.portPairs();
+ portPLIterator = portPairList.listIterator();
+ if (!portPLIterator.hasNext()) {
+ break;
+ }
+
+ portPairId = portPLIterator.next();
+ portPair = portPairService.getPortPair(portPairId);
+
+ nextDeviceId = vtnRscService.getSFToSFFMaping(VirtualPortId.portId(portPair.ingress()));
+
+ // pack traffic treatment
+ TrafficTreatment.Builder treatment = packTrafficTreatment(currentDeviceId, nextDeviceId, portPair);
+
+ // Send SFF to OVS
+ sendServiceFunctionForwarder(selector, treatment, deviceId, type);
+
+ // Replace source port pair group with destination port pair group
+ // for moving to next SFF processing.
+ currentPortPairGroup = nextPortPairGroup;
+ if (!listGrpIterator.hasNext()) {
+ break;
+ }
+ portPairGrpId = listGrpIterator.next();
+ nextPortPairGroup = portPairGroupService.getPortPairGroup(portPairGrpId);
+ } while (true);
+ }
+
+ /**
+ * Pack Traffic selector.
+ *
+ * @param deviceId device id
+ * @param srcMacAddress source mac-address
+ * @param dstMacAddress destination mac-address
+ * @param nshSPI nsh spi
+ * @return traffic treatment
+ */
+ public TrafficSelector.Builder packTrafficSelector(DeviceId deviceId, MacAddress srcMacAddress,
+ MacAddress dstMacAddress, NshServicePathId nshSPI) {
+ TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+ selector.matchEthSrc(srcMacAddress);
+ selector.matchEthDst(dstMacAddress);
+
+ DriverHandler handler = driverService.createHandler(deviceId);
+ ExtensionSelectorResolver resolver = handler.behaviour(ExtensionSelectorResolver.class);
+ ExtensionSelector nspSpiSelector = resolver.getExtensionSelector(NICIRA_MATCH_NSH_SPI.type());
+
+ try {
+ nspSpiSelector.setPropertyValue("nshSpi", nshSPI);
+ } catch (Exception e) {
+ log.error("Failed to get extension instruction to set Nsh Spi Id {}", deviceId);
+ }
+
+ selector.extension(nspSpiSelector, deviceId);
+ return selector;
+ }
+
+ /**
+ * Pack Traffic treatment.
+ *
+ * @param currentDeviceId current device id
+ * @param nextDeviceId next device id
+ * @param portPair port-pair
+ * @return traffic treatment
+ */
+ public TrafficTreatment.Builder packTrafficTreatment(DeviceId currentDeviceId, DeviceId nextDeviceId,
+ PortPair portPair) {
+ MacAddress srcMacAddress = null;
+ MacAddress dstMacAddress = null;
+
+ // Check the treatment whether destination SF is on same OVS or in
+ // different OVS.
+ TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+ if (currentDeviceId.equals(nextDeviceId)) {
+ srcMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.ingress())).macAddress();
+ dstMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.egress())).macAddress();
+ treatment.setEthSrc(srcMacAddress);
+ treatment.setEthDst(dstMacAddress);
+ } else {
+ treatment.setVlanId(VlanId.vlanId(Short.parseShort((vtnRscService.getL3vni(portPair
+ .tenantId()).toString()))));
+ }
+
+ return treatment;
+ }
+
+ /**
+ * Send service function forwarder to OVS.
+ *
+ * @param selector traffic selector
+ * @param treatment traffic treatment
+ * @param deviceId device id
+ * @param type operation type
+ */
+ public void sendServiceFunctionForwarder(TrafficSelector.Builder selector, TrafficTreatment.Builder treatment,
+ DeviceId deviceId, Objective.Operation type) {
+ ForwardingObjective.Builder objective = DefaultForwardingObjective.builder().withTreatment(treatment.build())
+ .withSelector(selector.build()).fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC);
+ if (type.equals(Objective.Operation.ADD)) {
+ log.debug("ADD");
+ flowObjectiveService.forward(deviceId, objective.add());
+ } else {
+ log.debug("REMOVE");
+ flowObjectiveService.forward(deviceId, objective.remove());
+ }
+ }
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/impl/package-info.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/impl/package-info.java
new file mode 100644
index 00000000..02221196
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/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.forwarder.impl;
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/NshSpiIdGenerators.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/NshSpiIdGenerators.java
new file mode 100644
index 00000000..1dbe8c8f
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/NshSpiIdGenerators.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.sfc.manager;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Unique NSH SPI Id generator for NSH header.
+ */
+public final class NshSpiIdGenerators {
+
+ private static final AtomicInteger NSH_SPI_ID_GEN = new AtomicInteger();
+ private static final int MAX_NSH_SPI_ID = 0x7FFFFFFF;
+ private static int nshSpiId;
+
+ /**
+ * Default constructor.
+ */
+ private NshSpiIdGenerators() {
+ }
+
+ /**
+ * Get the next NSH SPI id.
+ *
+ * @return NSH SPI id
+ */
+ public static int create() {
+ do {
+ if (nshSpiId >= MAX_NSH_SPI_ID) {
+ if (NSH_SPI_ID_GEN.get() >= MAX_NSH_SPI_ID) {
+ NSH_SPI_ID_GEN.set(0);
+ }
+ }
+ nshSpiId = NSH_SPI_ID_GEN.incrementAndGet();
+ } while (nshSpiId > MAX_NSH_SPI_ID);
+ return nshSpiId;
+ }
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/SfcService.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/SfcService.java
index ef5fc529..4af2d47c 100644
--- a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/SfcService.java
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/SfcService.java
@@ -15,6 +15,11 @@
*/
package org.onosproject.sfc.manager;
+import org.onosproject.vtnrsc.PortPair;
+import org.onosproject.vtnrsc.PortPairGroup;
+import org.onosproject.vtnrsc.FlowClassifier;
+import org.onosproject.vtnrsc.PortChain;
+
/**
* SFC application that applies flows to the device.
*/
@@ -23,48 +28,64 @@ public interface SfcService {
/**
* When port-pair is created, check whether Forwarding Rule needs to be
* updated in OVS.
+ *
+ * @param portPair port-pair
*/
- public void onPortPairCreated();
+ void onPortPairCreated(PortPair portPair);
/**
* When port-pair is deleted, check whether Forwarding Rule needs to be
* updated in OVS.
+ *
+ * @param portPair port-pair
*/
- public void onPortPairDeleted();
+ void onPortPairDeleted(PortPair portPair);
/**
* When port-pair-group is created, check whether Forwarding Rule needs to
* be updated in OVS.
+ *
+ * @param portPairGroup port-pair-group
*/
- public void onPortPairGroupCreated();
+ void onPortPairGroupCreated(PortPairGroup portPairGroup);
/**
* When port-pair-group is deleted, check whether Forwarding Rule needs to
* be updated in OVS.
+ *
+ * @param portPairGroup port-pair-group
*/
- public void onPortPairGroupDeleted();
+ void onPortPairGroupDeleted(PortPairGroup portPairGroup);
/**
* When flow-classifier is created, check whether Forwarding Rule needs to
* be updated in OVS.
+ *
+ * @param flowClassifier flow-classifier
*/
- public void onFlowClassifierCreated();
+ void onFlowClassifierCreated(FlowClassifier flowClassifier);
/**
* When flow-classifier is deleted, check whether Forwarding Rule needs to
* be updated in OVS.
+ *
+ * @param flowClassifier flow-classifier
*/
- public void onFlowClassifierDeleted();
+ void onFlowClassifierDeleted(FlowClassifier flowClassifier);
/**
* When port-chain is created, check whether Forwarding Rule needs to be
* updated in OVS.
+ *
+ * @param portChain port-chain
*/
- public void onPortChainCreated();
+ void onPortChainCreated(PortChain portChain);
/**
* When port-chain is deleted, check whether Forwarding Rule needs to be
* updated in OVS.
+ *
+ * @param portChain port-chain
*/
- public void onPortChainDeleted();
+ void onPortChainDeleted(PortChain portChain);
}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java
index 12d27c87..4df07929 100644
--- a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java
@@ -20,9 +20,26 @@ 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.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
import org.onosproject.sfc.manager.SfcService;
+import org.onosproject.vtnrsc.PortPair;
+import org.onosproject.vtnrsc.PortPairId;
+import org.onosproject.vtnrsc.PortPairGroup;
+import org.onosproject.vtnrsc.PortPairGroupId;
+import org.onosproject.vtnrsc.FlowClassifier;
+import org.onosproject.vtnrsc.FlowClassifierId;
import org.onosproject.vtnrsc.PortChain;
+import org.onosproject.vtnrsc.PortChainId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.event.VtnRscEvent;
+import org.onosproject.vtnrsc.event.VtnRscListener;
+import org.onosproject.vtnrsc.service.VtnRscService;
+
import org.slf4j.Logger;
/**
@@ -33,93 +50,137 @@ import org.slf4j.Logger;
public class SfcManager implements SfcService {
private final Logger log = getLogger(getClass());
+ private static final String APP_ID = "org.onosproject.app.vtn";
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected VtnRscService vtnRscService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
+
+ protected ApplicationId appId;
+
+ private final VtnRscListener vtnRscListener = new InnerVtnRscListener();
@Activate
public void activate() {
+ appId = coreService.registerApplication(APP_ID);
+
+ vtnRscService.addListener(vtnRscListener);
+
+ KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
+ .register(TenantId.class)
+ .register(PortPairId.class)
+ .register(PortPairGroupId.class)
+ .register(FlowClassifierId.class)
+ .register(PortChainId.class);
+
log.info("Started");
}
@Deactivate
public void deactivate() {
+ vtnRscService.removeListener(vtnRscListener);
+
log.info("Stopped");
}
+ /*
+ * Handle events.
+ */
+ private class InnerVtnRscListener implements VtnRscListener {
+ @Override
+ public void event(VtnRscEvent event) {
+
+ if (VtnRscEvent.Type.PORT_PAIR_PUT == event.type()) {
+ PortPair portPair = (PortPair) event.subject();
+ onPortPairCreated(portPair);
+ } else if (VtnRscEvent.Type.PORT_PAIR_DELETE == event.type()) {
+ PortPair portPair = (PortPair) event.subject();
+ onPortPairDeleted(portPair);
+ } else if (VtnRscEvent.Type.PORT_PAIR_UPDATE == event.type()) {
+ PortPair portPair = (PortPair) event.subject();
+ onPortPairDeleted(portPair);
+ onPortPairCreated(portPair);
+ } else if (VtnRscEvent.Type.PORT_PAIR_GROUP_PUT == event.type()) {
+ PortPairGroup portPairGroup = (PortPairGroup) event.subject();
+ onPortPairGroupCreated(portPairGroup);
+ } else if (VtnRscEvent.Type.PORT_PAIR_GROUP_DELETE == event.type()) {
+ PortPairGroup portPairGroup = (PortPairGroup) event.subject();
+ onPortPairGroupDeleted(portPairGroup);
+ } else if (VtnRscEvent.Type.PORT_PAIR_GROUP_UPDATE == event.type()) {
+ PortPairGroup portPairGroup = (PortPairGroup) event.subject();
+ onPortPairGroupDeleted(portPairGroup);
+ onPortPairGroupCreated(portPairGroup);
+ } else if (VtnRscEvent.Type.FLOW_CLASSIFIER_PUT == event.type()) {
+ FlowClassifier flowClassifier = (FlowClassifier) event.subject();
+ onFlowClassifierCreated(flowClassifier);
+ } else if (VtnRscEvent.Type.FLOW_CLASSIFIER_DELETE == event.type()) {
+ FlowClassifier flowClassifier = (FlowClassifier) event.subject();
+ onFlowClassifierDeleted(flowClassifier);
+ } else if (VtnRscEvent.Type.FLOW_CLASSIFIER_UPDATE == event.type()) {
+ FlowClassifier flowClassifier = (FlowClassifier) event.subject();
+ onFlowClassifierDeleted(flowClassifier);
+ onFlowClassifierCreated(flowClassifier);
+ } else if (VtnRscEvent.Type.PORT_CHAIN_PUT == event.type()) {
+ PortChain portChain = (PortChain) event.subject();
+ onPortChainCreated(portChain);
+ } else if (VtnRscEvent.Type.PORT_CHAIN_DELETE == event.type()) {
+ PortChain portChain = (PortChain) event.subject();
+ onPortChainDeleted(portChain);
+ } else if (VtnRscEvent.Type.PORT_CHAIN_UPDATE == event.type()) {
+ PortChain portChain = (PortChain) event.subject();
+ onPortChainDeleted(portChain);
+ onPortChainCreated(portChain);
+ }
+ }
+ }
+
@Override
- public void onPortPairCreated() {
+ public void onPortPairCreated(PortPair portPair) {
log.debug("onPortPairCreated");
- // TODO: Process port-pair on creation.
- // TODO: Parameter also needs to be modified.
+ // TODO: Modify forwarding rule on port-pair creation.
}
@Override
- public void onPortPairDeleted() {
+ public void onPortPairDeleted(PortPair portPair) {
log.debug("onPortPairDeleted");
- // TODO: Process port-pair on deletion.
- // TODO: Parameter also needs to be modified.
+ // TODO: Modify forwarding rule on port-pair deletion.
}
@Override
- public void onPortPairGroupCreated() {
+ public void onPortPairGroupCreated(PortPairGroup portPairGroup) {
log.debug("onPortPairGroupCreated");
- // TODO: Process port-pair-group on creation.
- // TODO: Parameter also needs to be modified.
+ // TODO: Modify forwarding rule on port-pair-group creation.
}
@Override
- public void onPortPairGroupDeleted() {
+ public void onPortPairGroupDeleted(PortPairGroup portPairGroup) {
log.debug("onPortPairGroupDeleted");
- // TODO: Process port-pair-group on deletion.
- // TODO: Parameter also needs to be modified.
+ // TODO: Modify forwarding rule on port-pair-group deletion.
}
@Override
- public void onFlowClassifierCreated() {
+ public void onFlowClassifierCreated(FlowClassifier flowClassifier) {
log.debug("onFlowClassifierCreated");
- // TODO: Process flow-classifier on creation.
- // TODO: Parameter also needs to be modified.
+ // TODO: Modify forwarding rule on flow-classifier creation.
}
@Override
- public void onFlowClassifierDeleted() {
+ public void onFlowClassifierDeleted(FlowClassifier flowClassifier) {
log.debug("onFlowClassifierDeleted");
- // TODO: Process flow-classifier on deletion.
- // TODO: Parameter also needs to be modified.
+ // TODO: Modify forwarding rule on flow-classifier deletion.
}
@Override
- public void onPortChainCreated() {
- log.debug("onPortChainCreated");
- // TODO: Process port-chain on creation.
- // TODO: Parameter also needs to be modified.
-
+ public void onPortChainCreated(PortChain portChain) {
+ log.debug("onPortChainCreated");
+ //TODO: Apply forwarding rule on port-chain creation.
}
@Override
- public void onPortChainDeleted() {
+ public void onPortChainDeleted(PortChain portChain) {
log.debug("onPortChainDeleted");
- // TODO: Process port-chain on deletion.
- // TODO: Parameter also needs to be modified.
- }
-
- /**
- * Install SF Forwarding rule into OVS.
- *
- * @param portChain
- * port chain
- */
- public void installForwardingRule(PortChain portChain) {
- log.debug("installForwardingRule");
- // TODO: Installation of SF Forwarding rule into OVS.
- }
-
- /**
- * Uninstall SF Forwarding rule from OVS.
- *
- * @param portChain
- * port chain
- */
- public void unInstallForwardingRule(PortChain portChain) {
- log.debug("unInstallForwardingRule");
- // TODO: Uninstallation of SF Forwarding rule from OVS.
+ //TODO: Apply forwarding rule on port-chain deletion.
}
-} \ No newline at end of file
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/manager/impl/SfcManagerTest.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/manager/impl/SfcManagerTest.java
new file mode 100644
index 00000000..e4f31f98
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/manager/impl/SfcManagerTest.java
@@ -0,0 +1,269 @@
+/*
+ * 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.manager.impl;
+
+import org.junit.Test;
+
+import java.util.List;
+import java.util.LinkedList;
+
+import org.onlab.packet.IpPrefix;
+import org.onosproject.sfc.manager.SfcService;
+import org.onosproject.vtnrsc.DefaultPortChain;
+import org.onosproject.vtnrsc.DefaultPortPair;
+import org.onosproject.vtnrsc.DefaultPortPairGroup;
+import org.onosproject.vtnrsc.PortChain;
+import org.onosproject.vtnrsc.PortChainId;
+import org.onosproject.vtnrsc.PortPair;
+import org.onosproject.vtnrsc.PortPairGroup;
+import org.onosproject.vtnrsc.PortPairGroupId;
+import org.onosproject.vtnrsc.PortPairId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.DefaultFlowClassifier;
+import org.onosproject.vtnrsc.FlowClassifierId;
+import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.FlowClassifier;
+
+/**
+ * Unit tests for SfcManager class.
+ */
+public class SfcManagerTest {
+ /**
+ * Checks the operation of onPortPairCreated() method.
+ */
+ @Test
+ public void testOnPortPairCreated() {
+ final PortPairId portPairId = PortPairId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae");
+ final TenantId tenantId = TenantId.tenantId("1");
+ final String name = "PortPair";
+ final String description = "PortPair";
+ final String ingress = "d3333333-24fc-4fae-af4b-321c5e2eb3d1";
+ final String egress = "a4444444-4a56-2a6e-cd3a-9dee4e2ec345";
+ DefaultPortPair.Builder portPairBuilder = new DefaultPortPair.Builder();
+ PortPair portPair = null;
+ SfcService sfcService = new SfcManager();
+
+ // create port pair
+ portPair = portPairBuilder.setId(portPairId).setTenantId(tenantId).setName(name).setDescription(description)
+ .setIngress(ingress).setEgress(egress).build();
+ sfcService.onPortPairCreated(portPair);
+ }
+
+ /**
+ * Checks the operation of onPortPairDeleted() method.
+ */
+ @Test
+ public void testOnPortPairDeleted() {
+ final PortPairId portPairId = PortPairId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae");
+ final TenantId tenantId = TenantId.tenantId("1");
+ final String name = "PortPair";
+ final String description = "PortPair";
+ final String ingress = "d3333333-24fc-4fae-af4b-321c5e2eb3d1";
+ final String egress = "a4444444-4a56-2a6e-cd3a-9dee4e2ec345";
+ DefaultPortPair.Builder portPairBuilder = new DefaultPortPair.Builder();
+ PortPair portPair = null;
+ SfcService sfcService = new SfcManager();
+
+ // create port pair
+ portPair = portPairBuilder.setId(portPairId).setTenantId(tenantId).setName(name).setDescription(description)
+ .setIngress(ingress).setEgress(egress).build();
+ sfcService.onPortPairDeleted(portPair);
+ }
+
+ /**
+ * Checks the operation of onPortPairGroupCreated() method.
+ */
+ @Test
+ public void testOnPortPairGroupCreated() {
+ final PortPairGroupId portPairGroupId = PortPairGroupId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae");
+ final TenantId tenantId = TenantId.tenantId("1");
+ final String name = "PortPairGroup";
+ final String description = "PortPairGroup";
+ final List<PortPairId> portPairIdList = new LinkedList<PortPairId>();
+ DefaultPortPairGroup.Builder portPairGroupBuilder = new DefaultPortPairGroup.Builder();
+ PortPairGroup portPairGroup = null;
+ SfcService sfcService = new SfcManager();
+
+ // create port-pair-id list
+ PortPairId portPairId = PortPairId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae");
+ portPairIdList.add(portPairId);
+ portPairId = PortPairId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae");
+ portPairIdList.add(portPairId);
+
+ // create port pair
+ portPairGroup = portPairGroupBuilder.setId(portPairGroupId).setTenantId(tenantId).setName(name)
+ .setDescription(description).setPortPairs(portPairIdList).build();
+ sfcService.onPortPairGroupCreated(portPairGroup);
+ }
+
+ /**
+ * Checks the operation of onPortPairGroupDeleted() method.
+ */
+ @Test
+ public void testOnPortPairGroupDeleted() {
+ final PortPairGroupId portPairGroupId = PortPairGroupId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae");
+ final TenantId tenantId = TenantId.tenantId("1");
+ final String name = "PortPairGroup";
+ final String description = "PortPairGroup";
+ final List<PortPairId> portPairIdList = new LinkedList<PortPairId>();
+ DefaultPortPairGroup.Builder portPairGroupBuilder = new DefaultPortPairGroup.Builder();
+ PortPairGroup portPairGroup = null;
+ SfcService sfcService = new SfcManager();
+
+ // create port-pair-id list
+ PortPairId portPairId = PortPairId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae");
+ portPairIdList.add(portPairId);
+ portPairId = PortPairId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae");
+ portPairIdList.add(portPairId);
+
+ // create port pair
+ portPairGroup = portPairGroupBuilder.setId(portPairGroupId).setTenantId(tenantId).setName(name)
+ .setDescription(description).setPortPairs(portPairIdList).build();
+ sfcService.onPortPairGroupDeleted(portPairGroup);
+ }
+
+ /**
+ * Checks the operation of onFlowClassifierCreated() method.
+ */
+ @Test
+ public void testOnFlowClassifierCreated() {
+ final String name = "FlowClassifier";
+ final String description = "FlowClassifier";
+ final String ethType = "IPv4";
+ final String protocol = "udp";
+ final int minSrcPortRange = 1024;
+ final int maxSrcPortRange = 5000;
+ final int minDstPortRange = 1024;
+ final int maxDstPortRange = 5000;
+ final FlowClassifierId flowClassifierId = FlowClassifierId.of("71111111-fc23-aeb6-f44b-56dc5e2fb3ae");
+ final TenantId tenantId = TenantId.tenantId("8");
+ final IpPrefix srcIpPrefix = IpPrefix.valueOf("0.0.0.0/0");
+ final IpPrefix dstIpPrefix = IpPrefix.valueOf("100.100.100.100/0");
+ final VirtualPortId virtualSrcPort = VirtualPortId.portId("100");
+ final VirtualPortId virtualDstPort = VirtualPortId.portId("200");
+ DefaultFlowClassifier.Builder flowClassifierBuilder = new DefaultFlowClassifier.Builder();
+ FlowClassifier flowClassifier = null;
+ SfcService sfcService = new SfcManager();
+
+ // create flow classifier
+ flowClassifier = flowClassifierBuilder.setFlowClassifierId(flowClassifierId).setTenantId(tenantId)
+ .setName(name).setDescription(description).setEtherType(ethType).setProtocol(protocol)
+ .setMinSrcPortRange(minSrcPortRange).setMaxSrcPortRange(maxSrcPortRange)
+ .setMinDstPortRange(minDstPortRange).setMaxDstPortRange(maxDstPortRange).setSrcIpPrefix(srcIpPrefix)
+ .setDstIpPrefix(dstIpPrefix).setSrcPort(virtualSrcPort).setDstPort(virtualDstPort).build();
+ sfcService.onFlowClassifierCreated(flowClassifier);
+ }
+
+ /**
+ * Checks the operation of onFlowClassifierDeleted() method.
+ */
+ @Test
+ public void testOnFlowClassifierDeleted() {
+ final String name = "FlowClassifier";
+ final String description = "FlowClassifier";
+ final String ethType = "IPv4";
+ final String protocol = "udp";
+ final int minSrcPortRange = 1024;
+ final int maxSrcPortRange = 5000;
+ final int minDstPortRange = 1024;
+ final int maxDstPortRange = 5000;
+ final FlowClassifierId flowClassifierId = FlowClassifierId.of("71111111-fc23-aeb6-f44b-56dc5e2fb3ae");
+ final TenantId tenantId = TenantId.tenantId("8");
+ final IpPrefix srcIpPrefix = IpPrefix.valueOf("0.0.0.0/0");
+ final IpPrefix dstIpPrefix = IpPrefix.valueOf("100.100.100.100/0");
+ final VirtualPortId virtualSrcPort = VirtualPortId.portId("100");
+ final VirtualPortId virtualDstPort = VirtualPortId.portId("200");
+ DefaultFlowClassifier.Builder flowClassifierBuilder = new DefaultFlowClassifier.Builder();
+ FlowClassifier flowClassifier = null;
+ SfcService sfcService = new SfcManager();
+
+ // create flow classifier
+ flowClassifier = flowClassifierBuilder.setFlowClassifierId(flowClassifierId).setTenantId(tenantId)
+ .setName(name).setDescription(description).setEtherType(ethType).setProtocol(protocol)
+ .setMinSrcPortRange(minSrcPortRange).setMaxSrcPortRange(maxSrcPortRange)
+ .setMinDstPortRange(minDstPortRange).setMaxDstPortRange(maxDstPortRange).setSrcIpPrefix(srcIpPrefix)
+ .setDstIpPrefix(dstIpPrefix).setSrcPort(virtualSrcPort).setDstPort(virtualDstPort).build();
+ sfcService.onFlowClassifierDeleted(flowClassifier);
+ }
+
+ /**
+ * Checks the operation of onPortChainCreated() method.
+ */
+ @Test
+ public void testOnPortChainCreated() {
+ final PortChainId portChainId = PortChainId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae");
+ final TenantId tenantId = TenantId.tenantId("1");
+ final String name = "PortChain";
+ final String description = "PortChain";
+ final List<PortPairGroupId> portPairGroupList = new LinkedList<PortPairGroupId>();
+ final List<FlowClassifierId> flowClassifierList = new LinkedList<FlowClassifierId>();
+ DefaultPortChain.Builder portChainBuilder = new DefaultPortChain.Builder();
+ DefaultFlowClassifier.Builder flowClassifierBuilder = new DefaultFlowClassifier.Builder();
+ PortChain portChain = null;
+ SfcService sfcService = new SfcManager();
+
+ // create list of Port Pair Groups.
+ PortPairGroupId portPairGroupId = PortPairGroupId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae");
+ portPairGroupList.add(portPairGroupId);
+ portPairGroupId = PortPairGroupId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3af");
+ portPairGroupList.add(portPairGroupId);
+
+ // create list of Flow classifiers.
+ FlowClassifierId flowClassifierId = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae");
+ flowClassifierList.add(flowClassifierId);
+ flowClassifierId = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3af");
+ flowClassifierList.add(flowClassifierId);
+
+ // create port chain
+ portChain = portChainBuilder.setId(portChainId).setTenantId(tenantId).setName(name).setDescription(description)
+ .setPortPairGroups(portPairGroupList).setFlowClassifiers(flowClassifierList).build();
+ sfcService.onPortChainCreated(portChain);
+ }
+
+ /**
+ * Checks the operation of onPortChainDeleted() method.
+ */
+ @Test
+ public void testOnPortChainDeleted() {
+ final PortChainId portChainId = PortChainId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae");
+ final TenantId tenantId = TenantId.tenantId("1");
+ final String name = "PortChain";
+ final String description = "PortChain";
+ final List<PortPairGroupId> portPairGroupList = new LinkedList<PortPairGroupId>();
+ final List<FlowClassifierId> flowClassifierList = new LinkedList<FlowClassifierId>();
+ DefaultPortChain.Builder portChainBuilder = new DefaultPortChain.Builder();
+ DefaultFlowClassifier.Builder flowClassifierBuilder = new DefaultFlowClassifier.Builder();
+ PortChain portChain = null;
+ SfcService sfcService = new SfcManager();
+
+ // create list of Port Pair Groups.
+ PortPairGroupId portPairGroupId = PortPairGroupId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae");
+ portPairGroupList.add(portPairGroupId);
+ portPairGroupId = PortPairGroupId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3af");
+ portPairGroupList.add(portPairGroupId);
+
+ // create list of Flow classifiers.
+ FlowClassifierId flowClassifierId = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae");
+ flowClassifierList.add(flowClassifierId);
+ flowClassifierId = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3af");
+ flowClassifierList.add(flowClassifierId);
+
+ // create port chain
+ portChain = portChainBuilder.setId(portChainId).setTenantId(tenantId).setName(name).setDescription(description)
+ .setPortPairGroups(portPairGroupList).setFlowClassifiers(flowClassifierList).build();
+ sfcService.onPortChainDeleted(portChain);
+ }
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowClassifierManagerTestImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowClassifierManagerTestImpl.java
new file mode 100644
index 00000000..fe5babbd
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowClassifierManagerTestImpl.java
@@ -0,0 +1,93 @@
+/*
+ * 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.util;
+
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.onosproject.vtnrsc.FlowClassifierId;
+import org.onosproject.vtnrsc.FlowClassifier;
+import org.onosproject.vtnrsc.flowclassifier.FlowClassifierListener;
+import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Provides implementation of the Flow Classifier Service.
+ */
+public class FlowClassifierManagerTestImpl implements FlowClassifierService {
+
+ private final ConcurrentMap<FlowClassifierId, FlowClassifier> flowClassifierStore = new ConcurrentHashMap<>();
+
+ @Override
+ public boolean exists(FlowClassifierId id) {
+ return flowClassifierStore.containsKey(id);
+ }
+
+ @Override
+ public int getFlowClassifierCount() {
+ return flowClassifierStore.size();
+ }
+
+ @Override
+ public Iterable<FlowClassifier> getFlowClassifiers() {
+ return ImmutableList.copyOf(flowClassifierStore.values());
+ }
+
+ @Override
+ public FlowClassifier getFlowClassifier(FlowClassifierId id) {
+ return flowClassifierStore.get(id);
+ }
+
+ @Override
+ public boolean createFlowClassifier(FlowClassifier flowClassifier) {
+ FlowClassifierId id = flowClassifier.flowClassifierId();
+
+ flowClassifierStore.put(id, flowClassifier);
+ if (!flowClassifierStore.containsKey(id)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean updateFlowClassifier(FlowClassifier flowClassifier) {
+
+ if (!flowClassifierStore.containsKey(flowClassifier.flowClassifierId())) {
+ return false;
+ }
+
+ flowClassifierStore.put(flowClassifier.flowClassifierId(), flowClassifier);
+
+ if (!flowClassifier.equals(flowClassifierStore.get(flowClassifier.flowClassifierId()))) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean removeFlowClassifier(FlowClassifierId id) {
+ return true;
+ }
+
+ @Override
+ public void addListener(FlowClassifierListener listener) {
+ }
+
+ @Override
+ public void removeListener(FlowClassifierListener listener) {
+ }
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowObjectiveServiceTestImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowObjectiveServiceTestImpl.java
new file mode 100644
index 00000000..9da9ee94
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowObjectiveServiceTestImpl.java
@@ -0,0 +1,53 @@
+/*
+ * 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.util;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+
+/**
+ * Testing version of implementation on FlowObjectiveService.
+ */
+public class FlowObjectiveServiceTestImpl implements FlowObjectiveService {
+
+ @Override
+ public void filter(DeviceId deviceId, FilteringObjective filteringObjective) {
+
+ }
+
+ @Override
+ public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
+
+ }
+
+ @Override
+ public void next(DeviceId deviceId, NextObjective nextObjective) {
+
+ }
+
+ @Override
+ public int allocateNextId() {
+ return 0;
+ }
+
+ @Override
+ public void initPolicy(String policy) {
+
+ }
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortChainManagerTestImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortChainManagerTestImpl.java
new file mode 100644
index 00000000..4a3ba03d
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortChainManagerTestImpl.java
@@ -0,0 +1,85 @@
+/*
+ * 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.util;
+
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.Collections;
+
+import org.onosproject.vtnrsc.PortChain;
+import org.onosproject.vtnrsc.PortChainId;
+import org.onosproject.vtnrsc.portchain.PortChainService;
+import org.onosproject.vtnrsc.portchain.PortChainEvent;
+import org.onosproject.vtnrsc.portchain.PortChainListener;
+import org.onosproject.event.AbstractListenerManager;
+
+/**
+ * Provides implementation of the portChainService.
+ */
+public class PortChainManagerTestImpl
+ extends AbstractListenerManager<PortChainEvent, PortChainListener>
+ implements PortChainService {
+
+ private ConcurrentMap<PortChainId, PortChain> portChainStore = new ConcurrentHashMap<>();
+
+ @Override
+ public boolean exists(PortChainId portChainId) {
+ return portChainStore.containsKey(portChainId);
+ }
+
+ @Override
+ public int getPortChainCount() {
+ return portChainStore.size();
+ }
+
+ @Override
+ public Iterable<PortChain> getPortChains() {
+ return Collections.unmodifiableCollection(portChainStore.values());
+ }
+
+ @Override
+ public PortChain getPortChain(PortChainId portChainId) {
+ return portChainStore.get(portChainId);
+ }
+
+ @Override
+ public boolean createPortChain(PortChain portChain) {
+ portChainStore.put(portChain.portChainId(), portChain);
+ if (!portChainStore.containsKey(portChain.portChainId())) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean updatePortChain(PortChain portChain) {
+ if (!portChainStore.containsKey(portChain.portChainId())) {
+ return false;
+ }
+
+ portChainStore.put(portChain.portChainId(), portChain);
+
+ if (!portChain.equals(portChainStore.get(portChain.portChainId()))) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean removePortChain(PortChainId portChainId) {
+ return true;
+ }
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairGroupManagerTestImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairGroupManagerTestImpl.java
new file mode 100644
index 00000000..ba31cd60
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairGroupManagerTestImpl.java
@@ -0,0 +1,89 @@
+/*
+ * 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.util;
+
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.Collections;
+
+import org.onosproject.vtnrsc.PortPairGroup;
+import org.onosproject.vtnrsc.PortPairGroupId;
+import org.onosproject.vtnrsc.portpairgroup.PortPairGroupListener;
+import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
+
+/**
+ * Provides implementation of the portPairGroupService.
+ */
+public class PortPairGroupManagerTestImpl implements PortPairGroupService {
+
+ private ConcurrentMap<PortPairGroupId, PortPairGroup> portPairGroupStore = new ConcurrentHashMap<>();
+
+ @Override
+ public boolean exists(PortPairGroupId portPairGroupId) {
+ return portPairGroupStore.containsKey(portPairGroupId);
+ }
+
+ @Override
+ public int getPortPairGroupCount() {
+ return portPairGroupStore.size();
+ }
+
+ @Override
+ public Iterable<PortPairGroup> getPortPairGroups() {
+ return Collections.unmodifiableCollection(portPairGroupStore.values());
+ }
+
+ @Override
+ public PortPairGroup getPortPairGroup(PortPairGroupId portPairGroupId) {
+ return portPairGroupStore.get(portPairGroupId);
+ }
+
+ @Override
+ public boolean createPortPairGroup(PortPairGroup portPairGroup) {
+ portPairGroupStore.put(portPairGroup.portPairGroupId(), portPairGroup);
+ if (!portPairGroupStore.containsKey(portPairGroup.portPairGroupId())) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean updatePortPairGroup(PortPairGroup portPairGroup) {
+ if (!portPairGroupStore.containsKey(portPairGroup.portPairGroupId())) {
+ return false;
+ }
+
+ portPairGroupStore.put(portPairGroup.portPairGroupId(), portPairGroup);
+
+ if (!portPairGroup.equals(portPairGroupStore.get(portPairGroup.portPairGroupId()))) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean removePortPairGroup(PortPairGroupId portPairGroupId) {
+ return true;
+ }
+
+ @Override
+ public void addListener(PortPairGroupListener listener) {
+ }
+
+ @Override
+ public void removeListener(PortPairGroupListener listener) {
+ }
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairManagerTestImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairManagerTestImpl.java
new file mode 100644
index 00000000..aff58823
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairManagerTestImpl.java
@@ -0,0 +1,89 @@
+/*
+ * 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.util;
+
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.Collections;
+
+import org.onosproject.vtnrsc.PortPair;
+import org.onosproject.vtnrsc.PortPairId;
+import org.onosproject.vtnrsc.portpair.PortPairListener;
+import org.onosproject.vtnrsc.portpair.PortPairService;
+
+/**
+ * Provides implementation of the portPairService.
+ */
+public class PortPairManagerTestImpl implements PortPairService {
+
+ private ConcurrentMap<PortPairId, PortPair> portPairStore = new ConcurrentHashMap<>();
+
+ @Override
+ public boolean exists(PortPairId portPairId) {
+ return portPairStore.containsKey(portPairId);
+ }
+
+ @Override
+ public int getPortPairCount() {
+ return portPairStore.size();
+ }
+
+ @Override
+ public Iterable<PortPair> getPortPairs() {
+ return Collections.unmodifiableCollection(portPairStore.values());
+ }
+
+ @Override
+ public PortPair getPortPair(PortPairId portPairId) {
+ return portPairStore.get(portPairId);
+ }
+
+ @Override
+ public boolean createPortPair(PortPair portPair) {
+ portPairStore.put(portPair.portPairId(), portPair);
+ if (!portPairStore.containsKey(portPair.portPairId())) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean updatePortPair(PortPair portPair) {
+ if (!portPairStore.containsKey(portPair.portPairId())) {
+ return false;
+ }
+
+ portPairStore.put(portPair.portPairId(), portPair);
+
+ if (!portPair.equals(portPairStore.get(portPair.portPairId()))) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean removePortPair(PortPairId portPairId) {
+ return true;
+ }
+
+ @Override
+ public void addListener(PortPairListener listener) {
+ }
+
+ @Override
+ public void removeListener(PortPairListener listener) {
+ }
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortManagerTestImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortManagerTestImpl.java
new file mode 100644
index 00000000..de056a78
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortManagerTestImpl.java
@@ -0,0 +1,98 @@
+/*
+ * 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.util;
+
+import java.util.Collection;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.onlab.packet.IpAddress;
+import org.onosproject.net.DeviceId;
+import org.onosproject.vtnrsc.FixedIp;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.VirtualPort;
+import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.virtualport.VirtualPortService;
+
+/**
+ * Provides implementation of the VirtualPort APIs.
+ */
+public class VirtualPortManagerTestImpl implements VirtualPortService {
+
+ protected ConcurrentMap<VirtualPortId, VirtualPort> vPortStore = new ConcurrentHashMap<>();
+
+ @Override
+ public boolean exists(VirtualPortId vPortId) {
+ return vPortStore.containsKey(vPortId);
+ }
+
+ @Override
+ public VirtualPort getPort(VirtualPortId vPortId) {
+ return vPortStore.get(vPortId);
+ }
+
+ @Override
+ public VirtualPort getPort(FixedIp fixedIP) {
+ return null;
+ }
+
+ @Override
+ public Collection<VirtualPort> getPorts() {
+ return null;
+ }
+
+ @Override
+ public Collection<VirtualPort> getPorts(TenantNetworkId networkId) {
+ return null;
+ }
+
+ @Override
+ public Collection<VirtualPort> getPorts(TenantId tenantId) {
+ return null;
+ }
+
+ @Override
+ public Collection<VirtualPort> getPorts(DeviceId deviceId) {
+ return null;
+ }
+
+ @Override
+ public VirtualPort getPort(TenantNetworkId networkId, IpAddress ipAddress) {
+ return null;
+ }
+
+ @Override
+ public boolean createPorts(Iterable<VirtualPort> vPorts) {
+ for (VirtualPort vPort : vPorts) {
+ vPortStore.put(vPort.portId(), vPort);
+ if (!vPortStore.containsKey(vPort.portId())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean updatePorts(Iterable<VirtualPort> vPorts) {
+ return true;
+ }
+
+ @Override
+ public boolean removePorts(Iterable<VirtualPortId> vPortIds) {
+ return true;
+ }
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VtnRscManagerTestImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VtnRscManagerTestImpl.java
new file mode 100644
index 00000000..4188cee6
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VtnRscManagerTestImpl.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.sfc.util;
+
+import java.util.Iterator;
+
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.vtnrsc.SegmentationId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.event.VtnRscListener;
+import org.onosproject.vtnrsc.service.VtnRscService;
+
+/**
+ * Provides implementation of the VtnRsc service.
+ */
+public class VtnRscManagerTestImpl implements VtnRscService {
+ @Override
+ public void addListener(VtnRscListener listener) {
+ }
+
+ @Override
+ public void removeListener(VtnRscListener listener) {
+ }
+
+ @Override
+ public SegmentationId getL3vni(TenantId tenantId) {
+ return null;
+ }
+
+ @Override
+ public Iterator<Device> getClassifierOfTenant(TenantId tenantId) {
+ return null;
+ }
+
+ @Override
+ public Iterator<Device> getSFFOfTenant(TenantId tenantId) {
+ return null;
+ }
+
+ @Override
+ public MacAddress getGatewayMac(HostId hostId) {
+ return null;
+ }
+
+ @Override
+ public boolean isServiceFunction(VirtualPortId portId) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public DeviceId getSFToSFFMaping(VirtualPortId portId) {
+ return DeviceId.deviceId("www.google.com");
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java
index a104e529..d7ee3607 100644
--- a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java
+++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java
@@ -17,6 +17,7 @@ package org.onosproject.vtn.manager;
import org.onosproject.net.Device;
import org.onosproject.net.Host;
+import org.onosproject.vtnrsc.event.VtnRscEventFeedback;
/**
* VTN application that applies configuration and flows to the device.
@@ -67,4 +68,32 @@ public interface VTNService {
*/
void onHostVanished(Host host);
+ /**
+ * Applies east west flows when neutron created router interface.
+ *
+ * @param l3Feedback VtnrscEventFeedback
+ */
+ void onRouterInterfaceDetected(VtnRscEventFeedback l3Feedback);
+
+ /**
+ * Remove east west flows when neutron removed router interface.
+ *
+ * @param l3Feedback VtnrscEventFeedback
+ */
+ void onRouterInterfaceVanished(VtnRscEventFeedback l3Feedback);
+
+ /**
+ * Applies north south flows when neutron bind floating ip.
+ *
+ * @param l3Feedback VtnrscEventFeedback
+ */
+ void onFloatingIpDetected(VtnRscEventFeedback l3Feedback);
+
+ /**
+ * Applies north south flows when neutron unbind floating ip.
+ *
+ * @param l3Feedback VtnrscEventFeedback
+ */
+ void onFloatingIpVanished(VtnRscEventFeedback l3Feedback);
+
}
diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java
index be6b9364..6429314e 100644
--- a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java
+++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java
@@ -18,6 +18,7 @@ package org.onosproject.vtn.manager.impl;
import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST;
import static org.slf4j.LoggerFactory.getLogger;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@@ -25,6 +26,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
@@ -39,9 +41,11 @@ import org.onlab.util.KryoNamespace;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.behaviour.BridgeConfig;
@@ -74,8 +78,12 @@ import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.LogicalClockService;
import org.onosproject.store.service.StorageService;
import org.onosproject.vtn.manager.VTNService;
+import org.onosproject.vtn.table.ArpService;
import org.onosproject.vtn.table.ClassifierService;
+import org.onosproject.vtn.table.DnatService;
import org.onosproject.vtn.table.L2ForwardService;
+import org.onosproject.vtn.table.L3ForwardService;
+import org.onosproject.vtn.table.SnatService;
import org.onosproject.vtn.table.impl.ClassifierServiceImpl;
import org.onosproject.vtn.table.impl.L2ForwardServiceImpl;
import org.onosproject.vtn.util.DataPathIdGenerator;
@@ -85,6 +93,11 @@ import org.onosproject.vtnrsc.AllowedAddressPair;
import org.onosproject.vtnrsc.BindingHostId;
import org.onosproject.vtnrsc.DefaultVirtualPort;
import org.onosproject.vtnrsc.FixedIp;
+import org.onosproject.vtnrsc.FloatingIp;
+import org.onosproject.vtnrsc.Router;
+import org.onosproject.vtnrsc.RouterGateway;
+import org.onosproject.vtnrsc.RouterId;
+import org.onosproject.vtnrsc.RouterInterface;
import org.onosproject.vtnrsc.SecurityGroup;
import org.onosproject.vtnrsc.SegmentationId;
import org.onosproject.vtnrsc.SubnetId;
@@ -93,6 +106,14 @@ import org.onosproject.vtnrsc.TenantNetwork;
import org.onosproject.vtnrsc.TenantNetworkId;
import org.onosproject.vtnrsc.VirtualPort;
import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.event.VtnRscEvent;
+import org.onosproject.vtnrsc.event.VtnRscEventFeedback;
+import org.onosproject.vtnrsc.event.VtnRscListener;
+import org.onosproject.vtnrsc.floatingip.FloatingIpService;
+import org.onosproject.vtnrsc.router.RouterService;
+import org.onosproject.vtnrsc.routerinterface.RouterInterfaceService;
+import org.onosproject.vtnrsc.service.VtnRscService;
+import org.onosproject.vtnrsc.subnet.SubnetService;
import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
import org.onosproject.vtnrsc.virtualport.VirtualPortService;
import org.slf4j.Logger;
@@ -142,12 +163,32 @@ public class VTNManager implements VTNService {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected GroupService groupService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected SubnetService subnetService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected VtnRscService vtnRscService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected FloatingIpService floatingIpService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected RouterService routerService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected RouterInterfaceService routerInterfaceService;
+
private ApplicationId appId;
private ClassifierService classifierService;
private L2ForwardService l2ForwardService;
+ private ArpService arpService;
+ private L3ForwardService l3ForwardService;
+ private SnatService snatService;
+ private DnatService dnatService;
private final HostListener hostListener = new InnerHostListener();
private final DeviceListener deviceListener = new InnerDeviceListener();
+ private final VtnRscListener l3EventListener = new VtnL3EventListener();
private static final String IFACEID = "ifaceid";
private static final String CONTROLLER_IP_KEY = "ipaddress";
@@ -156,11 +197,19 @@ public class VTNManager implements VTNService {
private static final String VIRTUALPORT = "vtn-virtual-port";
private static final String SWITCHES_OF_CONTROLLER = "switchesOfController";
private static final String SWITCH_OF_LOCAL_HOST_PORTS = "switchOfLocalHostPorts";
+ private static final String ROUTERINF_FLAG_OF_TENANT = "routerInfFlagOfTenant";
+ private static final String HOSTS_OF_SUBNET = "hostsOfSubnet";
+ private static final String EX_PORT_OF_DEVICE = "exPortOfDevice";
private static final String DEFAULT_IP = "0.0.0.0";
+ private static final String PORT_MAC = "portMac";
+ private static final int SUBNET_NUM = 2;
private EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore;
private EventuallyConsistentMap<IpAddress, Boolean> switchesOfController;
private EventuallyConsistentMap<DeviceId, NetworkOfLocalHostPorts> switchOfLocalHostPorts;
+ private EventuallyConsistentMap<SubnetId, Map<HostId, Host>> hostsOfSubnet;
+ private EventuallyConsistentMap<TenantId, Boolean> routerInfFlagOfTenant;
+ private EventuallyConsistentMap<DeviceId, Port> exPortOfDevice;
@Activate
public void activate() {
@@ -206,6 +255,24 @@ public class VTNManager implements VTNService {
.withTimestampProvider((k, v) -> clockService.getTimestamp())
.build();
+ hostsOfSubnet = storageService
+ .<SubnetId, Map<HostId, Host>>eventuallyConsistentMapBuilder()
+ .withName(HOSTS_OF_SUBNET).withSerializer(serializer)
+ .withTimestampProvider((k, v) -> clockService.getTimestamp())
+ .build();
+
+ routerInfFlagOfTenant = storageService
+ .<TenantId, Boolean>eventuallyConsistentMapBuilder()
+ .withName(ROUTERINF_FLAG_OF_TENANT).withSerializer(serializer)
+ .withTimestampProvider((k, v) -> clockService.getTimestamp())
+ .build();
+
+ exPortOfDevice = storageService
+ .<DeviceId, Port>eventuallyConsistentMapBuilder()
+ .withName(EX_PORT_OF_DEVICE).withSerializer(serializer)
+ .withTimestampProvider((k, v) -> clockService.getTimestamp())
+ .build();
+
log.info("Started");
}
@@ -213,6 +280,7 @@ public class VTNManager implements VTNService {
public void deactivate() {
deviceService.removeListener(deviceListener);
hostService.removeListener(hostListener);
+ vtnRscService.removeListener(l3EventListener);
log.info("Stopped");
}
@@ -278,14 +346,36 @@ public class VTNManager implements VTNService {
@Override
public void onHostDetected(Host host) {
+ DeviceId deviceId = host.location().deviceId();
+ if (!mastershipService.isLocalMaster(deviceId)) {
+ return;
+ }
+ String ifaceId = host.annotations().value(IFACEID);
+ if (ifaceId == null) {
+ log.error("The ifaceId of Host is null");
+ return;
+ }
// apply L2 openflow rules
applyHostMonitoredL2Rules(host, Objective.Operation.ADD);
+ // apply L3 openflow rules
+ applyHostMonitoredL3Rules(host, Objective.Operation.ADD);
}
@Override
public void onHostVanished(Host host) {
+ DeviceId deviceId = host.location().deviceId();
+ if (!mastershipService.isLocalMaster(deviceId)) {
+ return;
+ }
+ String ifaceId = host.annotations().value(IFACEID);
+ if (ifaceId == null) {
+ log.error("The ifaceId of Host is null");
+ return;
+ }
// apply L2 openflow rules
applyHostMonitoredL2Rules(host, Objective.Operation.REMOVE);
+ // apply L3 openflow rules
+ applyHostMonitoredL3Rules(host, Objective.Operation.REMOVE);
}
private void programTunnelConfig(DeviceId localDeviceId, IpAddress localIp,
@@ -376,7 +466,7 @@ public class VTNManager implements VTNService {
VirtualPortId virtualPortId = VirtualPortId.portId(ifaceId);
VirtualPort virtualPort = virtualPortService.getPort(virtualPortId);
if (virtualPort == null) {
- virtualPort = vPortStore.get(virtualPortId);
+ virtualPort = VtnData.getPort(vPortStore, virtualPortId);
}
Iterable<Device> devices = deviceService.getAvailableDevices();
@@ -582,4 +672,388 @@ public class VTNManager implements VTNService {
appid);
groupService.addGroup(groupDescription);
}
+
+ private class VtnL3EventListener implements VtnRscListener {
+ @Override
+ public void event(VtnRscEvent event) {
+ VtnRscEventFeedback l3Feedback = event.subject();
+ if (VtnRscEvent.Type.ROUTER_INTERFACE_PUT == event.type()) {
+ onRouterInterfaceDetected(l3Feedback);
+ } else
+ if (VtnRscEvent.Type.ROUTER_INTERFACE_DELETE == event.type()) {
+ onRouterInterfaceVanished(l3Feedback);
+ } else if (VtnRscEvent.Type.FLOATINGIP_PUT == event.type()) {
+ onFloatingIpDetected(l3Feedback);
+ } else if (VtnRscEvent.Type.FLOATINGIP_DELETE == event.type()) {
+ onFloatingIpVanished(l3Feedback);
+ }
+ }
+
+ }
+
+ @Override
+ public void onRouterInterfaceDetected(VtnRscEventFeedback l3Feedback) {
+ Objective.Operation operation = Objective.Operation.ADD;
+ RouterInterface routerInf = l3Feedback.routerInterface();
+ Iterable<RouterInterface> interfaces = routerInterfaceService
+ .getRouterInterfaces();
+ Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces)
+ .stream().filter(r -> r.tenantId().equals(routerInf.tenantId()))
+ .collect(Collectors.toSet());
+ if (routerInfFlagOfTenant.get(routerInf.tenantId()) != null) {
+ programRouterInterface(routerInf, operation);
+ } else {
+ if (interfacesSet.size() >= SUBNET_NUM) {
+ programInterfacesSet(interfacesSet, operation);
+ }
+ }
+ }
+
+ @Override
+ public void onRouterInterfaceVanished(VtnRscEventFeedback l3Feedback) {
+ Objective.Operation operation = Objective.Operation.REMOVE;
+ RouterInterface routerInf = l3Feedback.routerInterface();
+ Iterable<RouterInterface> interfaces = routerInterfaceService
+ .getRouterInterfaces();
+ Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces)
+ .stream().filter(r -> r.tenantId().equals(routerInf.tenantId()))
+ .collect(Collectors.toSet());
+ if (routerInfFlagOfTenant.get(routerInf.tenantId()) != null) {
+ programRouterInterface(routerInf, operation);
+ if (interfacesSet.size() == 1) {
+ routerInfFlagOfTenant.remove(routerInf.tenantId());
+ interfacesSet.stream().forEach(r -> {
+ programRouterInterface(r, operation);
+ });
+ }
+ }
+ }
+
+ @Override
+ public void onFloatingIpDetected(VtnRscEventFeedback l3Feedback) {
+ programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_PUT);
+ }
+
+ @Override
+ public void onFloatingIpVanished(VtnRscEventFeedback l3Feedback) {
+ programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_DELETE);
+ }
+
+ private void programInterfacesSet(Set<RouterInterface> interfacesSet,
+ Objective.Operation operation) {
+ int subnetVmNum = 0;
+ for (RouterInterface r : interfacesSet) {
+ // Get all the host of the subnet
+ Map<HostId, Host> hosts = hostsOfSubnet.get(r.subnetId());
+ if (hosts.size() > 0) {
+ subnetVmNum++;
+ if (subnetVmNum >= SUBNET_NUM) {
+ routerInfFlagOfTenant.put(r.tenantId(), true);
+ interfacesSet.stream().forEach(f -> {
+ programRouterInterface(f, operation);
+ });
+ break;
+ }
+ }
+ }
+ }
+
+ private void programRouterInterface(RouterInterface routerInf,
+ Objective.Operation operation) {
+ SegmentationId l3vni = vtnRscService.getL3vni(routerInf.tenantId());
+ // Get all the host of the subnet
+ Map<HostId, Host> hosts = hostsOfSubnet.get(routerInf.subnetId());
+ hosts.values().stream().forEach(h -> {
+ applyEastWestL3Flows(h, l3vni, operation);
+ });
+ }
+
+ private void applyEastWestL3Flows(Host h, SegmentationId l3vni,
+ Objective.Operation operation) {
+ if (!mastershipService.isLocalMaster(h.location().deviceId())) {
+ log.debug("not master device:{}", h.location().deviceId());
+ return;
+ }
+ String ifaceId = h.annotations().value(IFACEID);
+ VirtualPort hPort = virtualPortService
+ .getPort(VirtualPortId.portId(ifaceId));
+ if (hPort == null) {
+ hPort = VtnData.getPort(vPortStore, VirtualPortId.portId(ifaceId));
+ }
+ IpAddress srcIp = null;
+ IpAddress srcGwIp = null;
+ MacAddress srcVmGwMac = null;
+ SubnetId srcSubnetId = null;
+ Iterator<FixedIp> srcIps = hPort.fixedIps().iterator();
+ if (srcIps.hasNext()) {
+ FixedIp fixedIp = srcIps.next();
+ srcIp = fixedIp.ip();
+ srcSubnetId = fixedIp.subnetId();
+ srcGwIp = subnetService.getSubnet(srcSubnetId).gatewayIp();
+ FixedIp fixedGwIp = FixedIp.fixedIp(srcSubnetId, srcGwIp);
+ VirtualPort gwPort = virtualPortService.getPort(fixedGwIp);
+ if (gwPort == null) {
+ gwPort = VtnData.getPort(vPortStore, fixedGwIp);
+ }
+ srcVmGwMac = gwPort.macAddress();
+ }
+ TenantNetwork network = tenantNetworkService
+ .getNetwork(hPort.networkId());
+ // Classifier rules
+ classifierService
+ .programL3InPortClassifierRules(h.location().deviceId(),
+ h.location().port(), h.mac(),
+ srcVmGwMac, l3vni, operation);
+ // Arp rules
+ if (operation == Objective.Operation.ADD) {
+ classifierService.programArpClassifierRules(h.location().deviceId(),
+ srcGwIp,
+ network.segmentationId(),
+ operation);
+ DriverHandler handler = driverService.createHandler(h.location().deviceId());
+ arpService.programArpRules(handler, h.location().deviceId(), srcGwIp,
+ network.segmentationId(), srcVmGwMac,
+ operation);
+ }
+ Iterable<Device> devices = deviceService.getAvailableDevices();
+ IpAddress srcArpIp = srcIp;
+ MacAddress srcArpGwMac = srcVmGwMac;
+ Sets.newHashSet(devices).stream()
+ .filter(d -> Device.Type.SWITCH == d.type()).forEach(d -> {
+ // L3FWD rules
+ l3ForwardService.programRouteRules(d.id(), l3vni, srcArpIp,
+ network.segmentationId(),
+ srcArpGwMac, h.mac(),
+ operation);
+ });
+ }
+
+ private void programFloatingIpEvent(VtnRscEventFeedback l3Feedback,
+ VtnRscEvent.Type type) {
+ FloatingIp floaingIp = l3Feedback.floatingIp();
+ if (floaingIp != null) {
+ VirtualPortId vmPortId = floaingIp.portId();
+ VirtualPort vmPort = virtualPortService.getPort(vmPortId);
+ VirtualPort fipPort = virtualPortService
+ .getPort(floaingIp.networkId(), floaingIp.floatingIp());
+ if (vmPort == null) {
+ vmPort = VtnData.getPort(vPortStore, vmPortId);
+ }
+ if (fipPort == null) {
+ fipPort = VtnData.getPort(vPortStore, floaingIp.networkId(),
+ floaingIp.floatingIp());
+ }
+ Set<Host> hostSet = hostService.getHostsByMac(vmPort.macAddress());
+ Host host = null;
+ for (Host h : hostSet) {
+ String ifaceid = h.annotations().value(IFACEID);
+ if (ifaceid != null && ifaceid.equals(vmPortId.portId())) {
+ host = h;
+ break;
+ }
+ }
+ if (host != null && vmPort != null && fipPort != null) {
+ DeviceId deviceId = host.location().deviceId();
+ Port exPort = exPortOfDevice.get(deviceId);
+ SegmentationId l3vni = vtnRscService
+ .getL3vni(vmPort.tenantId());
+ // Floating ip BIND
+ if (type == VtnRscEvent.Type.FLOATINGIP_PUT) {
+ applyNorthSouthL3Flows(deviceId, host, vmPort, fipPort,
+ floaingIp, l3vni, exPort,
+ Objective.Operation.ADD);
+ } else if (type == VtnRscEvent.Type.FLOATINGIP_DELETE) {
+ // Floating ip UNBIND
+ applyNorthSouthL3Flows(deviceId, host, vmPort, fipPort,
+ floaingIp, l3vni, exPort,
+ Objective.Operation.REMOVE);
+ }
+ }
+ }
+ }
+
+ private void applyNorthSouthL3Flows(DeviceId deviceId, Host host,
+ VirtualPort vmPort, VirtualPort fipPort,
+ FloatingIp floatingIp,
+ SegmentationId l3Vni, Port exPort,
+ Objective.Operation operation) {
+ if (!mastershipService.isLocalMaster(deviceId)) {
+ log.debug("not master device:{}", deviceId);
+ return;
+ }
+ List gwIpMac = getGwIpAndMac(vmPort);
+ IpAddress dstVmGwIp = (IpAddress) gwIpMac.get(0);
+ MacAddress dstVmGwMac = (MacAddress) gwIpMac.get(1);
+ FixedIp fixedGwIp = getGwFixedIp(floatingIp);
+ MacAddress fGwMac = null;
+ if (fixedGwIp != null) {
+ VirtualPort gwPort = virtualPortService.getPort(fixedGwIp);
+ if (gwPort == null) {
+ gwPort = VtnData.getPort(vPortStore, fixedGwIp);
+ }
+ fGwMac = gwPort.macAddress();
+ }
+ TenantNetwork vmNetwork = tenantNetworkService
+ .getNetwork(vmPort.networkId());
+ TenantNetwork fipNetwork = tenantNetworkService
+ .getNetwork(fipPort.networkId());
+ // L3 downlink traffic flow
+ MacAddress exPortMac = MacAddress.valueOf(exPort.annotations().value(PORT_MAC));
+ classifierService.programArpClassifierRules(deviceId, floatingIp.floatingIp(),
+ fipNetwork.segmentationId(),
+ operation);
+ classifierService.programL3ExPortClassifierRules(deviceId, exPort.number(),
+ floatingIp.floatingIp(), operation);
+ DriverHandler handler = driverService.createHandler(deviceId);
+ arpService.programArpRules(handler, deviceId, floatingIp.floatingIp(),
+ fipNetwork.segmentationId(), exPortMac,
+ operation);
+ dnatService.programRules(deviceId, floatingIp.floatingIp(),
+ fGwMac, floatingIp.fixedIp(),
+ l3Vni, operation);
+ l3ForwardService
+ .programRouteRules(deviceId, l3Vni, floatingIp.fixedIp(),
+ vmNetwork.segmentationId(), dstVmGwMac,
+ vmPort.macAddress(), operation);
+
+ // L3 uplink traffic flow
+ classifierService.programL3InPortClassifierRules(deviceId,
+ host.location().port(),
+ host.mac(), dstVmGwMac,
+ l3Vni, operation);
+ snatService.programRules(deviceId, l3Vni, floatingIp.fixedIp(),
+ fGwMac, exPortMac,
+ floatingIp.floatingIp(),
+ fipNetwork.segmentationId(), operation);
+ if (operation == Objective.Operation.ADD) {
+ classifierService.programArpClassifierRules(deviceId, dstVmGwIp,
+ vmNetwork.segmentationId(),
+ operation);
+ arpService.programArpRules(handler, deviceId, dstVmGwIp,
+ vmNetwork.segmentationId(), dstVmGwMac,
+ operation);
+ l2ForwardService.programLocalOut(deviceId,
+ fipNetwork.segmentationId(),
+ exPort.number(), fGwMac, operation);
+ }
+ }
+
+ private Port getExPort(DeviceId deviceId) {
+ List<Port> ports = deviceService.getPorts(deviceId);
+ Port exPort = null;
+ for (Port port : ports) {
+ String portName = port.annotations().value(AnnotationKeys.PORT_NAME);
+ if (portName != null && portName.equals(EX_PORT_NAME)) {
+ exPort = port;
+ break;
+ }
+ }
+ return exPort;
+ }
+
+ private List getGwIpAndMac(VirtualPort port) {
+ List list = new ArrayList();
+ MacAddress gwMac = null;
+ SubnetId subnetId = null;
+ IpAddress gwIp = null;
+ Iterator<FixedIp> fixips = port.fixedIps().iterator();
+ if (fixips.hasNext()) {
+ FixedIp fixip = fixips.next();
+ subnetId = fixip.subnetId();
+ gwIp = subnetService.getSubnet(subnetId).gatewayIp();
+ FixedIp fixedGwIp = FixedIp.fixedIp(fixip.subnetId(), gwIp);
+ VirtualPort gwPort = virtualPortService.getPort(fixedGwIp);
+ if (gwPort == null) {
+ gwPort = VtnData.getPort(vPortStore, fixedGwIp);
+ }
+ gwMac = gwPort.macAddress();
+ }
+ list.add(gwIp);
+ list.add(gwMac);
+ return list;
+ }
+
+ private FixedIp getGwFixedIp(FloatingIp floatingIp) {
+ RouterId routerId = floatingIp.routerId();
+ Router router = routerService.getRouter(routerId);
+ RouterGateway routerGateway = router.externalGatewayInfo();
+ Iterable<FixedIp> externalFixedIps = routerGateway.externalFixedIps();
+ FixedIp fixedGwIp = null;
+ if (externalFixedIps != null) {
+ Iterator<FixedIp> exFixedIps = externalFixedIps.iterator();
+ if (exFixedIps.hasNext()) {
+ fixedGwIp = exFixedIps.next();
+ }
+ }
+ return fixedGwIp;
+ }
+
+ private void applyHostMonitoredL3Rules(Host host,
+ Objective.Operation operation) {
+ String ifaceId = host.annotations().value(IFACEID);
+ DeviceId deviceId = host.location().deviceId();
+ VirtualPortId portId = VirtualPortId.portId(ifaceId);
+ VirtualPort port = virtualPortService.getPort(portId);
+ if (port == null) {
+ port = VtnData.getPort(vPortStore, portId);
+ }
+ TenantId tenantId = port.tenantId();
+ Port exPort = exPortOfDevice.get(deviceId);
+ SegmentationId l3vni = vtnRscService.getL3vni(tenantId);
+ Iterator<FixedIp> fixips = port.fixedIps().iterator();
+ SubnetId sid = null;
+ IpAddress hostIp = null;
+ if (fixips.hasNext()) {
+ FixedIp fixip = fixips.next();
+ sid = fixip.subnetId();
+ hostIp = fixip.ip();
+ }
+ final SubnetId subnetId = sid;
+ // L3 internal network access to each other
+ Iterable<RouterInterface> interfaces = routerInterfaceService
+ .getRouterInterfaces();
+ Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces)
+ .stream().filter(r -> r.tenantId().equals(tenantId))
+ .collect(Collectors.toSet());
+ long count = interfacesSet.stream()
+ .filter(r -> !r.subnetId().equals(subnetId)).count();
+ if (count > 0) {
+ if (operation == Objective.Operation.ADD) {
+ if (routerInfFlagOfTenant.get(tenantId) != null) {
+ applyEastWestL3Flows(host, l3vni, operation);
+ } else {
+ if (interfacesSet.size() > 1) {
+ programInterfacesSet(interfacesSet, operation);
+ }
+ }
+ } else if (operation == Objective.Operation.REMOVE) {
+ if (routerInfFlagOfTenant.get(tenantId) != null) {
+ applyEastWestL3Flows(host, l3vni, operation);
+ }
+ }
+ }
+ // L3 external and internal network access to each other
+ FloatingIp floatingIp = null;
+ Iterable<FloatingIp> floatingIps = floatingIpService.getFloatingIps();
+ Set<FloatingIp> floatingIpSet = Sets.newHashSet(floatingIps).stream()
+ .filter(f -> f.tenantId().equals(tenantId))
+ .collect(Collectors.toSet());
+ for (FloatingIp f : floatingIpSet) {
+ IpAddress fixedIp = f.fixedIp();
+ if (fixedIp.equals(hostIp)) {
+ floatingIp = f;
+ break;
+ }
+ }
+ if (floatingIp != null) {
+ VirtualPort fipPort = virtualPortService
+ .getPort(floatingIp.networkId(), floatingIp.floatingIp());
+ if (fipPort == null) {
+ fipPort = VtnData.getPort(vPortStore, floatingIp.networkId(),
+ floatingIp.floatingIp());
+ }
+ applyNorthSouthL3Flows(deviceId, host, port, fipPort, floatingIp,
+ l3vni, exPort, operation);
+ }
+ }
}
diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java
index b548938b..ebb9ac3b 100644
--- a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java
+++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java
@@ -17,10 +17,13 @@ package org.onosproject.vtn.table;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
+
import org.onosproject.net.DeviceId;
+import org.onosproject.net.driver.DriverHandler;
import org.onosproject.net.flowobjective.Objective;
import org.onosproject.vtnrsc.SegmentationId;
+
/**
* ArpService interface providing the rules in ARP table which is Table(10).
*/
@@ -32,13 +35,14 @@ public interface ArpService {
* Action: set arp_operation, move arp_eth_src to arp_eth_dst, set arp_eth_src,
* move arp_ip_src to arp_ip_dst, set arp_ip_src, set output port.
*
+ * @param hander DriverHandler
* @param deviceId Device Id
* @param dstIP destination ip
* @param matchVni the vni of the source network (l2vni)
* @param dstMac destination mac
* @param type the operation type of the flow rules
*/
- void programArpRules(DeviceId deviceId, IpAddress dstIP,
+ void programArpRules(DriverHandler hander, DeviceId deviceId, IpAddress dstIP,
SegmentationId matchVni, MacAddress dstMac,
Objective.Operation type);
}
diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ArpServiceImpl.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ArpServiceImpl.java
new file mode 100644
index 00000000..574d15a7
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ArpServiceImpl.java
@@ -0,0 +1,113 @@
+/*
+ * 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.vtn.table.impl;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import org.onlab.osgi.DefaultServiceDirectory;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.packet.EthType.EtherType;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
+import org.onosproject.net.driver.DriverHandler;
+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.flow.instructions.ExtensionTreatment;
+import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.ForwardingObjective.Flag;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.Objective.Operation;
+import org.onosproject.vtn.table.ArpService;
+import org.onosproject.vtnrsc.SegmentationId;
+import org.slf4j.Logger;
+
+/**
+ * ArpTable class providing the rules in ARP table.
+ */
+public class ArpServiceImpl implements ArpService {
+ private final Logger log = getLogger(getClass());
+
+ private static final int ARP_PRIORITY = 0xffff;
+ private static final short ARP_RESPONSE = 0x2;
+ private static final EtherType ARP_TYPE = EtherType.ARP;
+
+ private final FlowObjectiveService flowObjectiveService;
+ private final ApplicationId appId;
+
+ /**
+ * Construct a ArpServiceImpl object.
+ *
+ * @param appId the application id of vtn
+ */
+ public ArpServiceImpl(ApplicationId appId) {
+ this.appId = checkNotNull(appId, "ApplicationId can not be null");
+ ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
+ this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class);
+ }
+
+ @Override
+ public void programArpRules(DriverHandler hander, DeviceId deviceId,
+ IpAddress dstIP, SegmentationId srcVni,
+ MacAddress dstMac, Operation type) {
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchEthType(ARP_TYPE.ethType().toShort())
+ .matchArpTpa(Ip4Address.valueOf(dstIP.toString()))
+ .matchTunnelId(Long.parseLong(srcVni.segmentationId())).build();
+
+ ExtensionTreatmentResolver resolver = hander
+ .behaviour(ExtensionTreatmentResolver.class);
+ ExtensionTreatment ethSrcToDst = resolver
+ .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes
+ .NICIRA_MOV_ETH_SRC_TO_DST.type());
+ ExtensionTreatment arpShaToTha = resolver
+ .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes
+ .NICIRA_MOV_ARP_SHA_TO_THA.type());
+ ExtensionTreatment arpSpaToTpa = resolver
+ .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes
+ .NICIRA_MOV_ARP_SPA_TO_TPA.type());
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .extension(ethSrcToDst, deviceId)
+ .setEthSrc(dstMac).setArpOp(ARP_RESPONSE)
+ .extension(arpShaToTha, deviceId)
+ .extension(arpSpaToTpa, deviceId)
+ .setArpSha(dstMac).setArpSpa(dstIP)
+ .setOutput(PortNumber.IN_PORT).build();
+
+ ForwardingObjective.Builder objective = DefaultForwardingObjective
+ .builder().withTreatment(treatment).withSelector(selector)
+ .fromApp(appId).withFlag(Flag.SPECIFIC)
+ .withPriority(ARP_PRIORITY);
+
+ if (type.equals(Objective.Operation.ADD)) {
+ log.debug("PrivateArpRules-->ADD");
+ flowObjectiveService.forward(deviceId, objective.add());
+ } else {
+ log.debug("PrivateArpRules-->REMOVE");
+ flowObjectiveService.forward(deviceId, objective.remove());
+ }
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java
index a8562e7f..cca905c2 100644
--- a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java
+++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java
@@ -17,12 +17,20 @@ package org.onosproject.vtn.util;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import org.onlab.packet.IpAddress;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.vtnrsc.FixedIp;
+import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.VirtualPort;
+import org.onosproject.vtnrsc.VirtualPortId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -94,4 +102,78 @@ public final class VtnData {
return localTunnelPorts;
}
+ /**
+ * Get VirtualPort.
+ *
+ * @param vPortStore EventuallyConsistentMap of VirtualPort
+ * @param vPortId VirtualPortId of the VirtualPort
+ * @return VirtualPort
+ */
+ public static VirtualPort getPort(EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore,
+ VirtualPortId vPortId) {
+ if (vPortStore != null) {
+ return vPortStore.get(vPortId);
+ }
+ return null;
+ }
+
+ /**
+ * Get VirtualPort.
+ *
+ * @param vPortStore EventuallyConsistentMap of VirtualPort
+ * @param fixedIP FixedIp of the VirtualPort
+ * @return VirtualPort
+ */
+ public static VirtualPort getPort(EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore,
+ FixedIp fixedIP) {
+ if (vPortStore != null) {
+ List<VirtualPort> vPorts = new ArrayList<>();
+ vPortStore.values().stream().forEach(p -> {
+ Iterator<FixedIp> fixedIps = p.fixedIps().iterator();
+ while (fixedIps.hasNext()) {
+ if (fixedIps.next().equals(fixedIP)) {
+ vPorts.add(p);
+ break;
+ }
+ }
+ });
+ if (vPorts.size() == 0) {
+ return null;
+ }
+ return vPorts.get(0);
+ }
+ return null;
+ }
+
+ /**
+ * Get VirtualPort.
+ *
+ * @param vPortStore EventuallyConsistentMap of VirtualPort
+ * @param networkId TenantNetworkId of the VirtualPort
+ * @param ip IpAddress of the VirtualPort
+ * @return VirtualPort
+ */
+ public static VirtualPort getPort(EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore,
+ TenantNetworkId networkId, IpAddress ip) {
+ if (vPortStore != null) {
+ List<VirtualPort> vPorts = new ArrayList<>();
+ vPortStore.values().stream()
+ .filter(p -> p.networkId().equals(networkId))
+ .forEach(p -> {
+ Iterator<FixedIp> fixedIps = p.fixedIps().iterator();
+ while (fixedIps.hasNext()) {
+ if (fixedIps.next().ip().equals(ip)) {
+ vPorts.add(p);
+ break;
+ }
+ }
+ });
+ if (vPorts.size() == 0) {
+ return null;
+ }
+ return vPorts.get(0);
+ }
+ return null;
+ }
+
}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/ClassifierService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/ClassifierService.java
new file mode 100644
index 00000000..a15da3ef
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/ClassifierService.java
@@ -0,0 +1,41 @@
+/*
+ * 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.classifier;
+
+import org.onosproject.net.DeviceId;
+
+/**
+ * Provides Services for Classifier.
+ */
+public interface ClassifierService {
+
+ /**
+ * Get Classifier devices for sfc.
+ *
+ * @return list of device id's for classifiers
+ */
+ Iterable<DeviceId> getClassifiers();
+
+ /**
+ * Add Classifier device for sfc.
+ */
+ void addClassifier(DeviceId deviceId);
+
+ /**
+ * Remove Classifier device for sfc.
+ */
+ void removeClassifier(DeviceId deviceId);
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/impl/ClassifierManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/impl/ClassifierManager.java
new file mode 100644
index 00000000..a12d6221
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/impl/ClassifierManager.java
@@ -0,0 +1,78 @@
+/*
+ * 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.classifier.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.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.net.DeviceId;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.DistributedSet;
+import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.vtnrsc.classifier.ClassifierService;
+import org.slf4j.Logger;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Provides implementation of the Classifier Service.
+ */
+@Component(immediate = true)
+@Service
+public class ClassifierManager implements ClassifierService {
+
+ private final Logger log = getLogger(ClassifierManager.class);
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected StorageService storageService;
+
+ private DistributedSet<DeviceId> classifierList;
+
+ @Activate
+ protected void activate() {
+ classifierList = storageService.<DeviceId>setBuilder()
+ .withName("classifier")
+ .withSerializer(Serializer.using(KryoNamespaces.API))
+ .build();
+ log.info("Started");
+ }
+
+ @Deactivate
+ protected void deactivate() {
+ log.info("Stopped");
+ }
+
+ @Override
+ public void addClassifier(DeviceId deviceId) {
+ classifierList.add(deviceId);
+ }
+
+ @Override
+ public Iterable<DeviceId> getClassifiers() {
+ return ImmutableList.copyOf(classifierList);
+ }
+
+ @Override
+ public void removeClassifier(DeviceId deviceId) {
+ classifierList.remove(deviceId);
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/impl/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/impl/package-info.java
new file mode 100644
index 00000000..dc72e806
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/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 Classifier service.
+ */
+package org.onosproject.vtnrsc.classifier.impl;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/package-info.java
new file mode 100644
index 00000000..56976d96
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/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 Classifier of SFC.
+ */
+package org.onosproject.vtnrsc.classifier;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetCreateCommand.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetCreateCommand.java
index 56236408..de8cfe53 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetCreateCommand.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetCreateCommand.java
@@ -98,7 +98,7 @@ public class SubnetCreateCommand extends AbstractShellCommand {
protected void execute() {
SubnetService service = get(SubnetService.class);
if (id == null || networkId == null || tenantId == null) {
- print(null, "id,networkId,tenantId can not be null");
+ print("id,networkId,tenantId can not be null");
return;
}
Subnet subnet = new DefaultSubnet(SubnetId.subnetId(id), subnetName,
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetUpdateCommand.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetUpdateCommand.java
index b0578a1e..c76ca5b2 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetUpdateCommand.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetUpdateCommand.java
@@ -98,7 +98,7 @@ public class SubnetUpdateCommand extends AbstractShellCommand {
protected void execute() {
SubnetService service = get(SubnetService.class);
if (id == null || networkId == null || tenantId == null) {
- print(null, "id,networkId,tenantId can not be null");
+ print("id,networkId,tenantId can not be null");
return;
}
Subnet subnet = new DefaultSubnet(SubnetId.subnetId(id), subnetName,
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java
index 3bac158b..ce3faae7 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java
@@ -51,7 +51,55 @@ public class VtnRscEvent
/**
* Signifies that router interface has remove.
*/
- ROUTER_INTERFACE_DELETE
+ ROUTER_INTERFACE_DELETE,
+ /**
+ * Signifies that port-pair has add.
+ */
+ PORT_PAIR_PUT,
+ /**
+ * Signifies that port-pair has remove.
+ */
+ PORT_PAIR_DELETE,
+ /**
+ * Signifies that port-pair has update.
+ */
+ PORT_PAIR_UPDATE,
+ /**
+ * Signifies that port-pair-group has add.
+ */
+ PORT_PAIR_GROUP_PUT,
+ /**
+ * Signifies that port-pair-group has remove.
+ */
+ PORT_PAIR_GROUP_DELETE,
+ /**
+ * Signifies that port-pair-group has update.
+ */
+ PORT_PAIR_GROUP_UPDATE,
+ /**
+ * Signifies that flow-classifier has add.
+ */
+ FLOW_CLASSIFIER_PUT,
+ /**
+ * Signifies that flow-classifier has remove.
+ */
+ FLOW_CLASSIFIER_DELETE,
+ /**
+ * Signifies that flow-classifier has update.
+ */
+ FLOW_CLASSIFIER_UPDATE,
+ /**
+ * Signifies that port-chain has add.
+ */
+ PORT_CHAIN_PUT,
+ /**
+ * Signifies that port-chain has remove.
+ */
+ PORT_CHAIN_DELETE,
+ /**
+ * Signifies that port-chain has update.
+ */
+ PORT_CHAIN_UPDATE
}
/**
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java
index 63dcaeee..112c6411 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java
@@ -20,6 +20,10 @@ import java.util.Objects;
import org.onosproject.vtnrsc.FloatingIp;
import org.onosproject.vtnrsc.Router;
import org.onosproject.vtnrsc.RouterInterface;
+import org.onosproject.vtnrsc.PortPair;
+import org.onosproject.vtnrsc.PortPairGroup;
+import org.onosproject.vtnrsc.FlowClassifier;
+import org.onosproject.vtnrsc.PortChain;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -31,6 +35,10 @@ public class VtnRscEventFeedback {
private final FloatingIp floaingtIp;
private final Router router;
private final RouterInterface routerInterface;
+ private final PortPair portPair;
+ private final PortPairGroup portPairGroup;
+ private final FlowClassifier flowClassifier;
+ private final PortChain portChain;
/**
* Creates VtnRscEventFeedback object.
@@ -41,6 +49,10 @@ public class VtnRscEventFeedback {
this.floaingtIp = checkNotNull(floatingIp, "floaintIp cannot be null");
this.router = null;
this.routerInterface = null;
+ this.portPair = null;
+ this.portPairGroup = null;
+ this.flowClassifier = null;
+ this.portChain = null;
}
/**
@@ -52,6 +64,10 @@ public class VtnRscEventFeedback {
this.floaingtIp = null;
this.router = checkNotNull(router, "router cannot be null");
this.routerInterface = null;
+ this.portPair = null;
+ this.portPairGroup = null;
+ this.flowClassifier = null;
+ this.portChain = null;
}
/**
@@ -64,6 +80,74 @@ public class VtnRscEventFeedback {
this.router = null;
this.routerInterface = checkNotNull(routerInterface,
"routerInterface cannot be null");
+ this.portPair = null;
+ this.portPairGroup = null;
+ this.flowClassifier = null;
+ this.portChain = null;
+ }
+
+ /**
+ * Creates VtnRscEventFeedback object.
+ *
+ * @param portPair the Port-Pair
+ */
+ public VtnRscEventFeedback(PortPair portPair) {
+ this.floaingtIp = null;
+ this.router = null;
+ this.routerInterface = null;
+ this.portPair = checkNotNull(portPair,
+ "Port-Pair cannot be null");
+ this.portPairGroup = null;
+ this.flowClassifier = null;
+ this.portChain = null;
+ }
+
+ /**
+ * Creates VtnRscEventFeedback object.
+ *
+ * @param portPairGroup the Port-Pair-Group
+ */
+ public VtnRscEventFeedback(PortPairGroup portPairGroup) {
+ this.floaingtIp = null;
+ this.router = null;
+ this.routerInterface = null;
+ this.portPair = null;
+ this.portPairGroup = checkNotNull(portPairGroup,
+ "Port-Pair-Group cannot be null");
+ this.flowClassifier = null;
+ this.portChain = null;
+ }
+
+ /**
+ * Creates VtnRscEventFeedback object.
+ *
+ * @param flowClassifier the Flow-Classifier
+ */
+ public VtnRscEventFeedback(FlowClassifier flowClassifier) {
+ this.floaingtIp = null;
+ this.router = null;
+ this.routerInterface = null;
+ this.portPair = null;
+ this.portPairGroup = null;
+ this.flowClassifier = checkNotNull(flowClassifier,
+ "Flow-Classifier cannot be null");
+ this.portChain = null;
+ }
+
+ /**
+ * Creates VtnRscEventFeedback object.
+ *
+ * @param portChain the Port-Chain
+ */
+ public VtnRscEventFeedback(PortChain portChain) {
+ this.floaingtIp = null;
+ this.router = null;
+ this.routerInterface = null;
+ this.portPair = null;
+ this.portPairGroup = null;
+ this.flowClassifier = null;
+ this.portChain = checkNotNull(portChain,
+ "Port-Chain cannot be null");
}
/**
@@ -93,9 +177,46 @@ public class VtnRscEventFeedback {
return routerInterface;
}
+ /**
+ * Returns Port-Pair.
+ *
+ * @return portPair the Port-Pair
+ */
+ public PortPair portPair() {
+ return portPair;
+ }
+
+ /**
+ * Returns Port-Pair-Group.
+ *
+ * @return portPairGroup the Port-Pair-Group
+ */
+ public PortPairGroup portPairGroup() {
+ return portPairGroup;
+ }
+
+ /**
+ * Returns Flow-Classifier.
+ *
+ * @return flowClassifier the Flow-Classifier
+ */
+ public FlowClassifier flowClassifier() {
+ return flowClassifier;
+ }
+
+ /**
+ * Returns Port-Chain.
+ *
+ * @return portChain the Port-Chain
+ */
+ public PortChain portChain() {
+ return portChain;
+ }
+
@Override
public int hashCode() {
- return Objects.hash(floaingtIp, router, routerInterface);
+ return Objects.hash(floaingtIp, router, routerInterface, portPair,
+ portPairGroup, flowClassifier, portChain);
}
@Override
@@ -107,7 +228,11 @@ public class VtnRscEventFeedback {
final VtnRscEventFeedback that = (VtnRscEventFeedback) obj;
return Objects.equals(this.floaingtIp, that.floaingtIp)
&& Objects.equals(this.router, that.router)
- && Objects.equals(this.routerInterface, that.routerInterface);
+ && Objects.equals(this.routerInterface, that.routerInterface)
+ && Objects.equals(this.portPair, that.portPair)
+ && Objects.equals(this.portPairGroup, that.portPairGroup)
+ && Objects.equals(this.flowClassifier, that.flowClassifier)
+ && Objects.equals(this.portChain, that.portChain);
}
return false;
}
@@ -118,6 +243,10 @@ public class VtnRscEventFeedback {
.add("router", router)
.add("floaingtIp", floaingtIp)
.add("routerInterface", routerInterface)
+ .add("portPair", portPair)
+ .add("portPairGroup", portPairGroup)
+ .add("flowClassifier", flowClassifier)
+ .add("portChain", portChain)
.toString();
}
}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/FloatingIpManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/FloatingIpManager.java
index 9f944da1..ce9bb21f 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/FloatingIpManager.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/FloatingIpManager.java
@@ -202,27 +202,24 @@ public class FloatingIpManager implements FloatingIpService {
public boolean updateFloatingIps(Collection<FloatingIp> floatingIps) {
checkNotNull(floatingIps, FLOATINGIP_NOT_NULL);
boolean result = true;
- if (floatingIps != null) {
- for (FloatingIp floatingIp : floatingIps) {
- verifyFloatingIpData(floatingIp);
- if (floatingIp.portId() != null) {
- floatingIpStore.put(floatingIp.id(), floatingIp);
- if (!floatingIpStore.containsKey(floatingIp.id())) {
+ for (FloatingIp floatingIp : floatingIps) {
+ verifyFloatingIpData(floatingIp);
+ if (floatingIp.portId() != null) {
+ floatingIpStore.put(floatingIp.id(), floatingIp);
+ if (!floatingIpStore.containsKey(floatingIp.id())) {
+ log.debug("The floating Ip is updated failed whose identifier is {}",
+ floatingIp.id().toString());
+ result = false;
+ }
+ } else {
+ FloatingIp oldFloatingIp = floatingIpStore.get(floatingIp.id());
+ if (oldFloatingIp != null) {
+ floatingIpStore.remove(floatingIp.id(), oldFloatingIp);
+ if (floatingIpStore.containsKey(floatingIp.id())) {
log.debug("The floating Ip is updated failed whose identifier is {}",
floatingIp.id().toString());
result = false;
}
- } else {
- FloatingIp oldFloatingIp = floatingIpStore.get(floatingIp
- .id());
- if (oldFloatingIp != null) {
- floatingIpStore.remove(floatingIp.id(), oldFloatingIp);
- if (floatingIpStore.containsKey(floatingIp.id())) {
- log.debug("The floating Ip is updated failed whose identifier is {}",
- floatingIp.id().toString());
- result = false;
- }
- }
}
}
}
@@ -233,21 +230,19 @@ public class FloatingIpManager implements FloatingIpService {
public boolean removeFloatingIps(Collection<FloatingIpId> floatingIpIds) {
checkNotNull(floatingIpIds, FLOATINGIP_ID_NOT_NULL);
boolean result = true;
- if (floatingIpIds != null) {
- for (FloatingIpId floatingIpId : floatingIpIds) {
- if (!floatingIpStore.containsKey(floatingIpId)) {
- log.debug("The floatingIp is not exist whose identifier is {}",
- floatingIpId.toString());
- throw new IllegalArgumentException(
- "FloatingIP ID doesn't exist");
- }
- FloatingIp floatingIp = floatingIpStore.get(floatingIpId);
- floatingIpStore.remove(floatingIpId, floatingIp);
- if (floatingIpStore.containsKey(floatingIpId)) {
- log.debug("The floating Ip is deleted failed whose identifier is {}",
- floatingIpId.toString());
- result = false;
- }
+ for (FloatingIpId floatingIpId : floatingIpIds) {
+ if (!floatingIpStore.containsKey(floatingIpId)) {
+ log.debug("The floatingIp is not exist whose identifier is {}",
+ floatingIpId.toString());
+ throw new IllegalArgumentException(
+ "FloatingIP ID doesn't exist");
+ }
+ FloatingIp floatingIp = floatingIpStore.get(floatingIpId);
+ floatingIpStore.remove(floatingIpId, floatingIp);
+ if (floatingIpStore.containsKey(floatingIpId)) {
+ log.debug("The floating Ip is deleted failed whose identifier is {}",
+ floatingIpId.toString());
+ result = false;
}
}
return result;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierEvent.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierEvent.java
new file mode 100644
index 00000000..d81ab48a
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierEvent.java
@@ -0,0 +1,63 @@
+/*
+ * 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.event.AbstractEvent;
+import org.onosproject.vtnrsc.FlowClassifier;
+
+/**
+ * Describes network Flow-Classifier event.
+ */
+public class FlowClassifierEvent extends AbstractEvent<FlowClassifierEvent.Type, FlowClassifier> {
+ /**
+ * Type of flow-classifier events.
+ */
+ public enum Type {
+ /**
+ * Signifies that flow-classifier has been created.
+ */
+ FLOW_CLASSIFIER_PUT,
+ /**
+ * Signifies that flow-classifier has been deleted.
+ */
+ FLOW_CLASSIFIER_DELETE,
+ /**
+ * Signifies that flow-classifier has been updated.
+ */
+ FLOW_CLASSIFIER_UPDATE
+ }
+
+ /**
+ * Creates an event of a given type and for the specified Flow-Classifier.
+ *
+ * @param type Flow-Classifier event type
+ * @param flowClassifier Flow-Classifier subject
+ */
+ public FlowClassifierEvent(Type type, FlowClassifier flowClassifier) {
+ super(type, flowClassifier);
+ }
+
+ /**
+ * Creates an event of a given type and for the specified Flow-Classifier.
+ *
+ * @param type Flow-Classifier event type
+ * @param flowClassifier Flow-Classifier subject
+ * @param time occurrence time
+ */
+ public FlowClassifierEvent(Type type, FlowClassifier flowClassifier, long time) {
+ super(type, flowClassifier, time);
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierListener.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierListener.java
new file mode 100644
index 00000000..3c0409ad
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierListener.java
@@ -0,0 +1,25 @@
+/*
+ * 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.event.EventListener;
+
+/**
+ * Entity capable of Flow-Classifier related events.
+ */
+public interface FlowClassifierListener extends EventListener<FlowClassifierEvent> {
+
+}
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
index c5911ff2..48438846 100644
--- 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
@@ -15,13 +15,14 @@
*/
package org.onosproject.vtnrsc.flowclassifier;
+import org.onosproject.event.ListenerService;
import org.onosproject.vtnrsc.FlowClassifier;
import org.onosproject.vtnrsc.FlowClassifierId;
/**
* Provides Services for Flow Classifier.
*/
-public interface FlowClassifierService {
+public interface FlowClassifierService extends ListenerService<FlowClassifierEvent, FlowClassifierListener> {
/**
* Check whether Flow Classifier is present based on given Flow Classifier
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
index 4a60cd34..18f63b30 100644
--- 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
@@ -15,6 +15,9 @@
*/
package org.onosproject.vtnrsc.flowclassifier.impl;
+import static org.slf4j.LoggerFactory.getLogger;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -22,6 +25,7 @@ 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.KryoNamespace;
+import org.onosproject.event.AbstractListenerManager;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.MultiValuedTimestamp;
@@ -29,12 +33,11 @@ import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.WallClockTimestamp;
import org.onosproject.vtnrsc.FlowClassifierId;
import org.onosproject.vtnrsc.FlowClassifier;
+import org.onosproject.vtnrsc.flowclassifier.FlowClassifierEvent;
+import org.onosproject.vtnrsc.flowclassifier.FlowClassifierListener;
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;
/**
@@ -42,14 +45,17 @@ import com.google.common.collect.ImmutableList;
*/
@Component(immediate = true)
@Service
-public class FlowClassifierManager implements FlowClassifierService {
-
- private final Logger log = getLogger(FlowClassifierManager.class);
+public class FlowClassifierManager extends AbstractListenerManager<FlowClassifierEvent, FlowClassifierListener>
+ implements FlowClassifierService {
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 static final String LISTENER_NOT_NULL = "Listener cannot be null";
+
+ private final Logger log = getLogger(FlowClassifierManager.class);
private EventuallyConsistentMap<FlowClassifierId, FlowClassifier> flowClassifierStore;
+
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected StorageService storageService;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainEvent.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainEvent.java
new file mode 100644
index 00000000..44a4e8ed
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainEvent.java
@@ -0,0 +1,63 @@
+/*
+ * 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.event.AbstractEvent;
+import org.onosproject.vtnrsc.PortChain;
+
+/**
+ * Describes network Port-Chain event.
+ */
+public class PortChainEvent extends AbstractEvent<PortChainEvent.Type, PortChain> {
+ /**
+ * Type of port-chain events.
+ */
+ public enum Type {
+ /**
+ * Signifies that port-chain has been created.
+ */
+ PORT_CHAIN_PUT,
+ /**
+ * Signifies that port-chain has been deleted.
+ */
+ PORT_CHAIN_DELETE,
+ /**
+ * Signifies that port-chain has been updated.
+ */
+ PORT_CHAIN_UPDATE
+ }
+
+ /**
+ * Creates an event of a given type and for the specified Port-Chain.
+ *
+ * @param type Port-Chain event type
+ * @param portChain Port-Chain subject
+ */
+ public PortChainEvent(Type type, PortChain portChain) {
+ super(type, portChain);
+ }
+
+ /**
+ * Creates an event of a given type and for the specified Port-Chain.
+ *
+ * @param type Port-Chain event type
+ * @param portChain Port-Chain subject
+ * @param time occurrence time
+ */
+ public PortChainEvent(Type type, PortChain portChain, long time) {
+ super(type, portChain, time);
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainListener.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainListener.java
new file mode 100644
index 00000000..27a498b5
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainListener.java
@@ -0,0 +1,25 @@
+/*
+ * 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.event.EventListener;
+
+/**
+ * Entity capable of Port-Chain related events.
+ */
+public interface PortChainListener extends EventListener<PortChainEvent> {
+
+}
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
index b4ff917e..5b08262b 100644
--- 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
@@ -15,13 +15,14 @@
*/
package org.onosproject.vtnrsc.portchain;
+import org.onosproject.event.ListenerService;
import org.onosproject.vtnrsc.PortChain;
import org.onosproject.vtnrsc.PortChainId;
/**
* Service for interacting with the inventory of port chains.
*/
-public interface PortChainService {
+public interface PortChainService extends ListenerService<PortChainEvent, PortChainListener> {
/**
* Returns if the port chain is existed.
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/impl/PortChainManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/impl/PortChainManager.java
index 5201a2ca..0062db48 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/impl/PortChainManager.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/impl/PortChainManager.java
@@ -27,6 +27,7 @@ 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.KryoNamespace;
+import org.onosproject.event.AbstractListenerManager;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.MultiValuedTimestamp;
@@ -34,6 +35,8 @@ import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.WallClockTimestamp;
import org.onosproject.vtnrsc.PortChain;
import org.onosproject.vtnrsc.PortChainId;
+import org.onosproject.vtnrsc.portchain.PortChainEvent;
+import org.onosproject.vtnrsc.portchain.PortChainListener;
import org.onosproject.vtnrsc.portchain.PortChainService;
import org.slf4j.Logger;
@@ -42,13 +45,14 @@ import org.slf4j.Logger;
*/
@Component(immediate = true)
@Service
-public class PortChainManager implements PortChainService {
-
- private final Logger log = getLogger(getClass());
+public class PortChainManager extends AbstractListenerManager<PortChainEvent, PortChainListener> implements
+ PortChainService {
private static final String PORT_CHAIN_ID_NULL = "PortChain ID cannot be null";
private static final String PORT_CHAIN_NULL = "PortChain cannot be null";
+ private static final String LISTENER_NOT_NULL = "Listener cannot be null";
+ private final Logger log = getLogger(getClass());
private EventuallyConsistentMap<PortChainId, PortChain> portChainStore;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairEvent.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairEvent.java
new file mode 100644
index 00000000..31ecc737
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairEvent.java
@@ -0,0 +1,63 @@
+/*
+ * 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.portpair;
+
+import org.onosproject.event.AbstractEvent;
+import org.onosproject.vtnrsc.PortPair;
+
+/**
+ * Describes network Port-Pair event.
+ */
+public class PortPairEvent extends AbstractEvent<PortPairEvent.Type, PortPair> {
+ /**
+ * Type of port-pair events.
+ */
+ public enum Type {
+ /**
+ * Signifies that port-pair has been created.
+ */
+ PORT_PAIR_PUT,
+ /**
+ * Signifies that port-pair has been deleted.
+ */
+ PORT_PAIR_DELETE,
+ /**
+ * Signifies that port-pair has been updated.
+ */
+ PORT_PAIR_UPDATE
+ }
+
+ /**
+ * Creates an event of a given type and for the specified Port-Pair.
+ *
+ * @param type Port-Pair event type
+ * @param portPair Port-Pair subject
+ */
+ public PortPairEvent(Type type, PortPair portPair) {
+ super(type, portPair);
+ }
+
+ /**
+ * Creates an event of a given type and for the specified Port-Pair.
+ *
+ * @param type Port-Pair event type
+ * @param portPair Port-Pair subject
+ * @param time occurrence time
+ */
+ public PortPairEvent(Type type, PortPair portPair, long time) {
+ super(type, portPair, time);
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairListener.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairListener.java
new file mode 100644
index 00000000..3bdb9e4e
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairListener.java
@@ -0,0 +1,25 @@
+/*
+ * 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.portpair;
+
+import org.onosproject.event.EventListener;
+
+/**
+ * Entity capable of Port-Pair related events.
+ */
+public interface PortPairListener extends EventListener<PortPairEvent> {
+
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairService.java
index f99cc2cf..e98a6a20 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairService.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairService.java
@@ -77,4 +77,18 @@ public interface PortPairService {
* @return true if the give port pair is deleted successfully.
*/
boolean removePortPair(PortPairId portPairId);
+
+ /**
+ * Adds the specified listener to Port-Pair manager.
+ *
+ * @param listener Port-Pair listener
+ */
+ void addListener(PortPairListener listener);
+
+ /**
+ * Removes the specified listener to Port-Pair manager.
+ *
+ * @param listener Port-Pair listener
+ */
+ void removeListener(PortPairListener listener);
}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/impl/PortPairManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/impl/PortPairManager.java
index 93c8782a..ad6fd4bb 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/impl/PortPairManager.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/impl/PortPairManager.java
@@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
import java.util.Collections;
+import java.util.Set;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
@@ -34,9 +35,12 @@ import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.WallClockTimestamp;
import org.onosproject.vtnrsc.PortPair;
import org.onosproject.vtnrsc.PortPairId;
+import org.onosproject.vtnrsc.portpair.PortPairListener;
import org.onosproject.vtnrsc.portpair.PortPairService;
import org.slf4j.Logger;
+import com.google.common.collect.Sets;
+
/**
* Provides implementation of the portPairService.
*/
@@ -44,11 +48,12 @@ import org.slf4j.Logger;
@Service
public class PortPairManager implements PortPairService {
- private final Logger log = getLogger(getClass());
-
private static final String PORT_PAIR_ID_NULL = "PortPair ID cannot be null";
private static final String PORT_PAIR_NULL = "PortPair cannot be null";
+ private static final String LISTENER_NOT_NULL = "Listener cannot be null";
+ private final Logger log = getLogger(getClass());
+ private final Set<PortPairListener> listeners = Sets.newCopyOnWriteArraySet();
private EventuallyConsistentMap<PortPairId, PortPair> portPairStore;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -73,6 +78,7 @@ public class PortPairManager implements PortPairService {
@Deactivate
public void deactivate() {
portPairStore.destroy();
+ listeners.clear();
log.info("Stopped");
}
@@ -143,4 +149,16 @@ public class PortPairManager implements PortPairService {
}
return true;
}
+
+ @Override
+ public void addListener(PortPairListener listener) {
+ checkNotNull(listener, LISTENER_NOT_NULL);
+ listeners.add(listener);
+ }
+
+ @Override
+ public void removeListener(PortPairListener listener) {
+ checkNotNull(listener, LISTENER_NOT_NULL);
+ listeners.remove(listener);
+ }
}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupEvent.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupEvent.java
new file mode 100644
index 00000000..88e1d7fb
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupEvent.java
@@ -0,0 +1,63 @@
+/*
+ * 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.event.AbstractEvent;
+import org.onosproject.vtnrsc.PortPairGroup;
+
+/**
+ * Describes network Port-Pair-Group event.
+ */
+public class PortPairGroupEvent extends AbstractEvent<PortPairGroupEvent.Type, PortPairGroup> {
+ /**
+ * Type of port-pair-group events.
+ */
+ public enum Type {
+ /**
+ * Signifies that port-pair-group has been created.
+ */
+ PORT_PAIR_GROUP_PUT,
+ /**
+ * Signifies that port-pair-group has been deleted.
+ */
+ PORT_PAIR_GROUP_DELETE,
+ /**
+ * Signifies that port-pair-group has been updated.
+ */
+ PORT_PAIR_GROUP_UPDATE
+ }
+
+ /**
+ * Creates an event of a given type and for the specified Port-Pair-Group.
+ *
+ * @param type Port-Pair-Group event type
+ * @param portPairGroup Port-Pair-Group subject
+ */
+ public PortPairGroupEvent(Type type, PortPairGroup portPairGroup) {
+ super(type, portPairGroup);
+ }
+
+ /**
+ * Creates an event of a given type and for the specified Port-Pair-Group.
+ *
+ * @param type Port-Pair-Group event type
+ * @param portPairGroup Port-Pair-Group subject
+ * @param time occurrence time
+ */
+ public PortPairGroupEvent(Type type, PortPairGroup portPairGroup, long time) {
+ super(type, portPairGroup, time);
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupListener.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupListener.java
new file mode 100644
index 00000000..637149e3
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupListener.java
@@ -0,0 +1,25 @@
+/*
+ * 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.event.EventListener;
+
+/**
+ * Entity capable of Port-Pair-Group related events.
+ */
+public interface PortPairGroupListener extends EventListener<PortPairGroupEvent> {
+
+}
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
index 77f483fc..efee0eb9 100644
--- 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
@@ -77,4 +77,18 @@ public interface PortPairGroupService {
* @return true if the give port pair group is deleted successfully.
*/
boolean removePortPairGroup(PortPairGroupId portPairGroupId);
+
+ /**
+ * Adds the specified listener to Port-Pair-Group manager.
+ *
+ * @param listener Port-Pair-Group listener
+ */
+ void addListener(PortPairGroupListener listener);
+
+ /**
+ * Removes the specified listener to Port-Pair-Group manager.
+ *
+ * @param listener Port-Pair-Group listener
+ */
+ void removeListener(PortPairGroupListener listener);
}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/impl/PortPairGroupManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/impl/PortPairGroupManager.java
index 55fb4e43..5f80ef64 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/impl/PortPairGroupManager.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/impl/PortPairGroupManager.java
@@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
import java.util.Collections;
+import java.util.Set;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
@@ -34,9 +35,12 @@ import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.WallClockTimestamp;
import org.onosproject.vtnrsc.PortPairGroup;
import org.onosproject.vtnrsc.PortPairGroupId;
+import org.onosproject.vtnrsc.portpairgroup.PortPairGroupListener;
import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
import org.slf4j.Logger;
+import com.google.common.collect.Sets;
+
/**
* Provides implementation of the portPairGroupService.
*/
@@ -44,11 +48,12 @@ import org.slf4j.Logger;
@Service
public class PortPairGroupManager implements PortPairGroupService {
- private final Logger log = getLogger(getClass());
-
private static final String PORT_PAIR_GROUP_ID_NULL = "PortPairGroup ID cannot be null";
private static final String PORT_PAIR_GROUP_NULL = "PortPairGroup cannot be null";
+ private static final String LISTENER_NOT_NULL = "Listener cannot be null";
+ private final Logger log = getLogger(getClass());
+ private final Set<PortPairGroupListener> listeners = Sets.newCopyOnWriteArraySet();
private EventuallyConsistentMap<PortPairGroupId, PortPairGroup> portPairGroupStore;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -73,6 +78,7 @@ public class PortPairGroupManager implements PortPairGroupService {
@Deactivate
public void deactivate() {
portPairGroupStore.destroy();
+ listeners.clear();
log.info("Stopped");
}
@@ -143,4 +149,16 @@ public class PortPairGroupManager implements PortPairGroupService {
}
return true;
}
+
+ @Override
+ public void addListener(PortPairGroupListener listener) {
+ checkNotNull(listener, LISTENER_NOT_NULL);
+ listeners.add(listener);
+ }
+
+ @Override
+ public void removeListener(PortPairGroupListener listener) {
+ checkNotNull(listener, LISTENER_NOT_NULL);
+ listeners.remove(listener);
+ }
}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/VtnRscService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/VtnRscService.java
index 21161ba5..bc9f4e68 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/VtnRscService.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/VtnRscService.java
@@ -18,32 +18,20 @@ package org.onosproject.vtnrsc.service;
import java.util.Iterator;
import org.onlab.packet.MacAddress;
+import org.onosproject.event.ListenerService;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.HostId;
import org.onosproject.vtnrsc.SegmentationId;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.event.VtnRscEvent;
import org.onosproject.vtnrsc.event.VtnRscListener;
/**
* Service for interacting with the inventory of Vtn resource.
*/
-public interface VtnRscService {
- /**
- * Adds the specified listener.
- *
- * @param listener VtnRsc listener
- */
- void addListener(VtnRscListener listener);
-
- /**
- * Removes the specified listener.
- *
- * @param listener VtnRsc listener
- */
- void removeListener(VtnRscListener listener);
-
+public interface VtnRscService extends ListenerService<VtnRscEvent, VtnRscListener> {
/**
* Returns the SegmentationId of tenant.
*
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java
index ec9ca3ef..b21ad200 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java
@@ -32,6 +32,7 @@ import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.util.KryoNamespace;
import org.onosproject.core.CoreService;
+import org.onosproject.event.AbstractListenerManager;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Host;
@@ -54,6 +55,11 @@ import org.onosproject.vtnrsc.SubnetId;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.VirtualPort;
import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.PortPair;
+import org.onosproject.vtnrsc.PortPairId;
+import org.onosproject.vtnrsc.PortPairGroup;
+import org.onosproject.vtnrsc.FlowClassifier;
+import org.onosproject.vtnrsc.PortChain;
import org.onosproject.vtnrsc.event.VtnRscEvent;
import org.onosproject.vtnrsc.event.VtnRscEventFeedback;
import org.onosproject.vtnrsc.event.VtnRscListener;
@@ -70,16 +76,27 @@ import org.onosproject.vtnrsc.service.VtnRscService;
import org.onosproject.vtnrsc.subnet.SubnetService;
import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
import org.onosproject.vtnrsc.virtualport.VirtualPortService;
+import org.onosproject.vtnrsc.portpair.PortPairEvent;
+import org.onosproject.vtnrsc.portpair.PortPairListener;
+import org.onosproject.vtnrsc.portpair.PortPairService;
+import org.onosproject.vtnrsc.portpairgroup.PortPairGroupEvent;
+import org.onosproject.vtnrsc.portpairgroup.PortPairGroupListener;
+import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
+import org.onosproject.vtnrsc.flowclassifier.FlowClassifierEvent;
+import org.onosproject.vtnrsc.flowclassifier.FlowClassifierListener;
+import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService;
+import org.onosproject.vtnrsc.portchain.PortChainEvent;
+import org.onosproject.vtnrsc.portchain.PortChainListener;
+import org.onosproject.vtnrsc.portchain.PortChainService;
import org.slf4j.Logger;
-import com.google.common.collect.Sets;
-
/**
* Provides implementation of the VtnRsc service.
*/
@Component(immediate = true)
@Service
-public class VtnRscManager implements VtnRscService {
+public class VtnRscManager extends AbstractListenerManager<VtnRscEvent, VtnRscListener>
+ implements VtnRscService {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -88,11 +105,14 @@ public class VtnRscManager implements VtnRscService {
protected LogicalClockService clockService;
private final Logger log = getLogger(getClass());
- private final Set<VtnRscListener> listeners = Sets.newCopyOnWriteArraySet();
private HostListener hostListener = new InnerHostListener();
private FloatingIpListener floatingIpListener = new InnerFloatingIpListener();
private RouterListener routerListener = new InnerRouterListener();
private RouterInterfaceListener routerInterfaceListener = new InnerRouterInterfaceListener();
+ private PortPairListener portPairListener = new InnerPortPairListener();
+ private PortPairGroupListener portPairGroupListener = new InnerPortPairGroupListener();
+ private FlowClassifierListener flowClassifierListener = new InnerFlowClassifierListener();
+ private PortChainListener portChainListener = new InnerPortChainListener();
private EventuallyConsistentMap<TenantId, SegmentationId> l3vniMap;
private EventuallyConsistentMap<TenantId, Set<DeviceId>> classifierOvsMap;
@@ -125,6 +145,14 @@ public class VtnRscManager implements VtnRscService {
protected TenantNetworkService tenantNetworkService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceService deviceService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PortPairService portPairService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PortPairGroupService portPairGroupService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected FlowClassifierService flowClassifierService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PortChainService portChainService;
@Activate
public void activate() {
@@ -132,6 +160,10 @@ public class VtnRscManager implements VtnRscService {
floatingIpService.addListener(floatingIpListener);
routerService.addListener(routerListener);
routerInterfaceService.addListener(routerInterfaceListener);
+ portPairService.addListener(portPairListener);
+ portPairGroupService.addListener(portPairGroupListener);
+ flowClassifierService.addListener(flowClassifierListener);
+ portChainService.addListener(portChainListener);
KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
.register(KryoNamespaces.API)
@@ -161,26 +193,18 @@ public class VtnRscManager implements VtnRscService {
floatingIpService.removeListener(floatingIpListener);
routerService.removeListener(routerListener);
routerInterfaceService.removeListener(routerInterfaceListener);
+ portPairService.removeListener(portPairListener);
+ portPairGroupService.removeListener(portPairGroupListener);
+ flowClassifierService.removeListener(flowClassifierListener);
+ portChainService.removeListener(portChainListener);
+
l3vniMap.destroy();
classifierOvsMap.destroy();
sffOvsMap.destroy();
- listeners.clear();
log.info("Stopped");
}
@Override
- public void addListener(VtnRscListener listener) {
- checkNotNull(listener, LISTENER_NOT_NULL);
- listeners.add(listener);
- }
-
- @Override
- public void removeListener(VtnRscListener listener) {
- checkNotNull(listener, LISTENER_NOT_NULL);
- listeners.add(listener);
- }
-
- @Override
public SegmentationId getL3vni(TenantId tenantId) {
checkNotNull(tenantId, "tenantId cannot be null");
SegmentationId l3vni = l3vniMap.get(tenantId);
@@ -282,6 +306,93 @@ public class VtnRscManager implements VtnRscService {
}
}
+ private class InnerPortPairListener implements PortPairListener {
+
+ @Override
+ public void event(PortPairEvent event) {
+ checkNotNull(event, EVENT_NOT_NULL);
+ PortPair portPair = event.subject();
+ if (PortPairEvent.Type.PORT_PAIR_PUT == event.type()) {
+ notifyListeners(new VtnRscEvent(VtnRscEvent.Type.PORT_PAIR_PUT,
+ new VtnRscEventFeedback(portPair)));
+ } else if (PortPairEvent.Type.PORT_PAIR_DELETE == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.PORT_PAIR_DELETE,
+ new VtnRscEventFeedback(portPair)));
+ } else if (PortPairEvent.Type.PORT_PAIR_UPDATE == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.PORT_PAIR_UPDATE,
+ new VtnRscEventFeedback(portPair)));
+ }
+ }
+ }
+
+ private class InnerPortPairGroupListener implements PortPairGroupListener {
+
+ @Override
+ public void event(PortPairGroupEvent event) {
+ checkNotNull(event, EVENT_NOT_NULL);
+ PortPairGroup portPairGroup = event.subject();
+ if (PortPairGroupEvent.Type.PORT_PAIR_GROUP_PUT == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.PORT_PAIR_GROUP_PUT,
+ new VtnRscEventFeedback(portPairGroup)));
+ } else if (PortPairGroupEvent.Type.PORT_PAIR_GROUP_DELETE == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.PORT_PAIR_GROUP_DELETE,
+ new VtnRscEventFeedback(portPairGroup)));
+ } else if (PortPairGroupEvent.Type.PORT_PAIR_GROUP_UPDATE == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.PORT_PAIR_GROUP_UPDATE,
+ new VtnRscEventFeedback(portPairGroup)));
+ }
+ }
+ }
+
+ private class InnerFlowClassifierListener implements FlowClassifierListener {
+
+ @Override
+ public void event(FlowClassifierEvent event) {
+ checkNotNull(event, EVENT_NOT_NULL);
+ FlowClassifier flowClassifier = event.subject();
+ if (FlowClassifierEvent.Type.FLOW_CLASSIFIER_PUT == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.FLOW_CLASSIFIER_PUT,
+ new VtnRscEventFeedback(flowClassifier)));
+ } else if (FlowClassifierEvent.Type.FLOW_CLASSIFIER_DELETE == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.FLOW_CLASSIFIER_DELETE,
+ new VtnRscEventFeedback(flowClassifier)));
+ } else if (FlowClassifierEvent.Type.FLOW_CLASSIFIER_UPDATE == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.FLOW_CLASSIFIER_UPDATE,
+ new VtnRscEventFeedback(flowClassifier)));
+ }
+ }
+ }
+
+ private class InnerPortChainListener implements PortChainListener {
+
+ @Override
+ public void event(PortChainEvent event) {
+ checkNotNull(event, EVENT_NOT_NULL);
+ PortChain portChain = event.subject();
+ if (PortChainEvent.Type.PORT_CHAIN_PUT == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.PORT_CHAIN_PUT,
+ new VtnRscEventFeedback(portChain)));
+ } else if (PortChainEvent.Type.PORT_CHAIN_DELETE == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.PORT_CHAIN_DELETE,
+ new VtnRscEventFeedback(portChain)));
+ } else if (PortChainEvent.Type.PORT_CHAIN_UPDATE == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.PORT_CHAIN_UPDATE,
+ new VtnRscEventFeedback(portChain)));
+ }
+ }
+ }
+
@Override
public Iterator<Device> getClassifierOfTenant(TenantId tenantId) {
checkNotNull(tenantId, TENANTID_NOT_NULL);
@@ -333,8 +444,7 @@ public class VtnRscManager implements VtnRscService {
@Override
public boolean isServiceFunction(VirtualPortId portId) {
- // TODO Auto-generated method stub
- return false;
+ return portPairService.exists(PortPairId.of(portId.portId()));
}
@Override
@@ -343,7 +453,7 @@ public class VtnRscManager implements VtnRscService {
VirtualPort vmPort = virtualPortService.getPort(portId);
Set<Host> hostSet = hostService.getHostsByMac(vmPort.macAddress());
for (Host host : hostSet) {
- if (host.annotations().value(IFACEID).equals(vmPort.portId())) {
+ if (host.annotations().value(IFACEID).equals(vmPort.portId().portId())) {
return host.location().deviceId();
}
}
@@ -467,6 +577,6 @@ public class VtnRscManager implements VtnRscService {
*/
private void notifyListeners(VtnRscEvent event) {
checkNotNull(event, EVENT_NOT_NULL);
- listeners.forEach(listener -> listener.event(event));
+ post(event);
}
}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortService.java
index 0a3ea2cd..19548db8 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortService.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortService.java
@@ -17,6 +17,7 @@ package org.onosproject.vtnrsc.virtualport;
import java.util.Collection;
+import org.onlab.packet.IpAddress;
import org.onosproject.net.DeviceId;
import org.onosproject.vtnrsc.FixedIp;
import org.onosproject.vtnrsc.TenantId;
@@ -53,6 +54,15 @@ public interface VirtualPortService {
VirtualPort getPort(FixedIp fixedIP);
/**
+ * Returns the virtualPort associated with the networkId and ip.
+ *
+ * @param networkId the TenantNetworkId identifier
+ * @param ip the ip identifier
+ * @return virtualPort.
+ */
+ VirtualPort getPort(TenantNetworkId networkId, IpAddress ip);
+
+ /**
* Returns the collection of the currently known virtualPort.
* @return collection of VirtualPort.
*/
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 daec7839..9639e086 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
@@ -72,6 +72,7 @@ public class VirtualPortManager implements VirtualPortService {
private static final String NETWORKID_NOT_NULL = "NetworkId cannot be null";
private static final String DEVICEID_NOT_NULL = "DeviceId cannot be null";
private static final String FIXEDIP_NOT_NULL = "FixedIp cannot be null";
+ private static final String IP_NOT_NULL = "Ip cannot be null";
protected Map<VirtualPortId, VirtualPort> vPortStore;
protected ApplicationId appId;
@@ -148,6 +149,27 @@ public class VirtualPortManager implements VirtualPortService {
}
@Override
+ public VirtualPort getPort(TenantNetworkId networkId, IpAddress ip) {
+ checkNotNull(networkId, NETWORKID_NOT_NULL);
+ checkNotNull(ip, IP_NOT_NULL);
+ List<VirtualPort> vPorts = new ArrayList<>();
+ vPortStore.values().stream().filter(p -> p.networkId().equals(networkId))
+ .forEach(p -> {
+ Iterator<FixedIp> fixedIps = p.fixedIps().iterator();
+ while (fixedIps.hasNext()) {
+ if (fixedIps.next().ip().equals(ip)) {
+ vPorts.add(p);
+ break;
+ }
+ }
+ });
+ if (vPorts.size() == 0) {
+ return null;
+ }
+ return vPorts.get(0);
+ }
+
+ @Override
public Collection<VirtualPort> getPorts() {
return Collections.unmodifiableCollection(vPortStore.values());
}
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
index 08e37f96..4fd3fa48 100644
--- 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
@@ -36,12 +36,10 @@ import org.onosproject.rest.AbstractWebResource;
import org.onosproject.vtnrsc.FlowClassifier;
import org.onosproject.vtnrsc.FlowClassifierId;
import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService;
-import org.onosproject.vtnweb.web.FlowClassifierCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -64,11 +62,11 @@ public class FlowClassifierWebResource extends AbstractWebResource {
@Produces(MediaType.APPLICATION_JSON)
public Response getFlowClassifiers() {
Iterable<FlowClassifier> flowClassifiers = get(FlowClassifierService.class).getFlowClassifiers();
- ObjectNode result = new ObjectMapper().createObjectNode();
+ ObjectNode result = mapper().createObjectNode();
ArrayNode flowClassifierEntry = result.putArray("flow_classifiers");
if (flowClassifiers != null) {
for (final FlowClassifier flowClassifier : flowClassifiers) {
- flowClassifierEntry.add(new FlowClassifierCodec().encode(flowClassifier, this));
+ flowClassifierEntry.add(codec(FlowClassifier.class).encode(flowClassifier, this));
}
}
return ok(result.toString()).build();
@@ -85,11 +83,11 @@ public class FlowClassifierWebResource extends AbstractWebResource {
@Path("{flow_id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getFlowClassifier(@PathParam("flow_id") String id) {
- FlowClassifier flowClassifier = nullIsNotFound(
- get(FlowClassifierService.class).getFlowClassifier(FlowClassifierId.of(id)), FLOW_CLASSIFIER_NOT_FOUND);
+ FlowClassifier flowClassifier = nullIsNotFound(get(FlowClassifierService.class)
+ .getFlowClassifier(FlowClassifierId.of(id)), FLOW_CLASSIFIER_NOT_FOUND);
- ObjectNode result = new ObjectMapper().createObjectNode();
- result.set("flow_classifier", new FlowClassifierCodec().encode(flowClassifier, this));
+ ObjectNode result = mapper().createObjectNode();
+ result.set("flow_classifier", codec(FlowClassifier.class).encode(flowClassifier, this));
return ok(result.toString()).build();
}
@@ -107,13 +105,12 @@ public class FlowClassifierWebResource extends AbstractWebResource {
@Produces(MediaType.APPLICATION_JSON)
public Response createFlowClassifier(InputStream stream) {
try {
- ObjectMapper mapper = new ObjectMapper();
- ObjectNode jsonTree = (ObjectNode) mapper.readTree(stream);
+ ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
JsonNode flow = jsonTree.get("flow_classifier");
- FlowClassifier flowClassifier = new FlowClassifierCodec().decode((ObjectNode) flow, this);
+ FlowClassifier flowClassifier = codec(FlowClassifier.class).decode((ObjectNode) flow, this);
Boolean issuccess = nullIsNotFound(get(FlowClassifierService.class).createFlowClassifier(flowClassifier),
- FLOW_CLASSIFIER_NOT_FOUND);
+ FLOW_CLASSIFIER_NOT_FOUND);
return Response.status(OK).entity(issuccess.toString()).build();
} catch (IOException ex) {
log.error("Exception while creating flow classifier {}.", ex.toString());
@@ -139,9 +136,9 @@ public class FlowClassifierWebResource extends AbstractWebResource {
JsonNode jsonTree = mapper().readTree(stream);
JsonNode flow = jsonTree.get("flow_classifier");
- FlowClassifier flowClassifier = new FlowClassifierCodec().decode((ObjectNode) flow, this);
+ FlowClassifier flowClassifier = codec(FlowClassifier.class).decode((ObjectNode) flow, this);
Boolean result = nullIsNotFound(get(FlowClassifierService.class).updateFlowClassifier(flowClassifier),
- FLOW_CLASSIFIER_NOT_FOUND);
+ FLOW_CLASSIFIER_NOT_FOUND);
return Response.status(OK).entity(result.toString()).build();
} catch (IOException e) {
log.error("Update flow classifier failed because of exception {}.", e.toString());
@@ -161,7 +158,7 @@ public class FlowClassifierWebResource extends AbstractWebResource {
log.debug("Deletes flow classifier by identifier {}.", id);
FlowClassifierId flowClassifierId = FlowClassifierId.of(id);
Boolean issuccess = nullIsNotFound(get(FlowClassifierService.class).removeFlowClassifier(flowClassifierId),
- FLOW_CLASSIFIER_NOT_FOUND);
+ FLOW_CLASSIFIER_NOT_FOUND);
}
}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortChainWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortChainWebResource.java
index db12bcc7..e7b908b7 100644
--- a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortChainWebResource.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortChainWebResource.java
@@ -15,7 +15,6 @@
*/
package org.onosproject.vtnweb.resources;
-import static javax.ws.rs.core.Response.Status.NOT_FOUND;
import static javax.ws.rs.core.Response.Status.OK;
import static org.onlab.util.Tools.nullIsNotFound;
@@ -37,11 +36,11 @@ import org.onosproject.rest.AbstractWebResource;
import org.onosproject.vtnrsc.PortChain;
import org.onosproject.vtnrsc.PortChainId;
import org.onosproject.vtnrsc.portchain.PortChainService;
-import org.onosproject.vtnweb.web.PortChainCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
@@ -52,7 +51,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
public class PortChainWebResource extends AbstractWebResource {
private final Logger log = LoggerFactory.getLogger(PortChainWebResource.class);
- private final PortChainService service = get(PortChainService.class);
public static final String PORT_CHAIN_NOT_FOUND = "Port chain not found";
public static final String PORT_CHAIN_ID_EXIST = "Port chain exists";
public static final String PORT_CHAIN_ID_NOT_EXIST = "Port chain does not exist with identifier";
@@ -65,10 +63,15 @@ public class PortChainWebResource extends AbstractWebResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getPortChains() {
- Iterable<PortChain> portChains = service.getPortChains();
- ObjectNode result = new ObjectMapper().createObjectNode();
- result.set("port_chains", new PortChainCodec().encode(portChains, this));
- return ok(result).build();
+ Iterable<PortChain> portChains = get(PortChainService.class).getPortChains();
+ ObjectNode result = mapper().createObjectNode();
+ ArrayNode portChainEntry = result.putArray("port_chains");
+ if (portChains != null) {
+ for (final PortChain portChain : portChains) {
+ portChainEntry.add(codec(PortChain.class).encode(portChain, this));
+ }
+ }
+ return ok(result.toString()).build();
}
/**
@@ -82,14 +85,11 @@ public class PortChainWebResource extends AbstractWebResource {
@Produces(MediaType.APPLICATION_JSON)
public Response getPortPain(@PathParam("chain_id") String id) {
- if (!service.exists(PortChainId.of(id))) {
- return Response.status(NOT_FOUND).entity(PORT_CHAIN_NOT_FOUND).build();
- }
- PortChain portChain = nullIsNotFound(service.getPortChain(PortChainId.of(id)),
+ PortChain portChain = nullIsNotFound(get(PortChainService.class).getPortChain(PortChainId.of(id)),
PORT_CHAIN_NOT_FOUND);
- ObjectNode result = new ObjectMapper().createObjectNode();
- result.set("port_chain", new PortChainCodec().encode(portChain, this));
- return ok(result).build();
+ ObjectNode result = mapper().createObjectNode();
+ result.set("port_chain", codec(PortChain.class).encode(portChain, this));
+ return ok(result.toString()).build();
}
/**
@@ -105,8 +105,10 @@ public class PortChainWebResource extends AbstractWebResource {
public Response createPortChain(InputStream stream) {
try {
ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
- PortChain portChain = codec(PortChain.class).decode(jsonTree, this);
- Boolean issuccess = nullIsNotFound(service.createPortChain(portChain), PORT_CHAIN_NOT_FOUND);
+ JsonNode port = jsonTree.get("port_chain");
+ PortChain portChain = codec(PortChain.class).decode((ObjectNode) port, this);
+ Boolean issuccess = nullIsNotFound(get(PortChainService.class).createPortChain(portChain),
+ PORT_CHAIN_NOT_FOUND);
return Response.status(OK).entity(issuccess.toString()).build();
} catch (IOException e) {
log.error("Exception while creating port chain {}.", e.toString());
@@ -129,8 +131,10 @@ public class PortChainWebResource extends AbstractWebResource {
final InputStream stream) {
try {
ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
- PortChain portChain = codec(PortChain.class).decode(jsonTree, this);
- Boolean result = nullIsNotFound(service.updatePortChain(portChain), PORT_CHAIN_NOT_FOUND);
+ JsonNode port = jsonTree.get("port_chain");
+ PortChain portChain = codec(PortChain.class).decode((ObjectNode) port, this);
+ Boolean result = nullIsNotFound(get(PortChainService.class).updatePortChain(portChain),
+ PORT_CHAIN_NOT_FOUND);
return Response.status(OK).entity(result.toString()).build();
} catch (IOException e) {
log.error("Update port chain failed because of exception {}.", e.toString());
@@ -149,7 +153,8 @@ public class PortChainWebResource extends AbstractWebResource {
log.debug("Deletes port chain by identifier {}.", id);
PortChainId portChainId = PortChainId.of(id);
- Boolean issuccess = nullIsNotFound(service.removePortChain(portChainId), PORT_CHAIN_NOT_FOUND);
+ Boolean issuccess = nullIsNotFound(get(PortChainService.class).removePortChain(portChainId),
+ PORT_CHAIN_NOT_FOUND);
if (!issuccess) {
log.debug("Port Chain identifier {} does not exist", id);
}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairGroupWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairGroupWebResource.java
index 69daad37..dc5328a2 100644
--- a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairGroupWebResource.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairGroupWebResource.java
@@ -16,7 +16,6 @@
package org.onosproject.vtnweb.resources;
-import static javax.ws.rs.core.Response.Status.NOT_FOUND;
import static javax.ws.rs.core.Response.Status.OK;
import static org.onlab.util.Tools.nullIsNotFound;
@@ -38,11 +37,12 @@ import org.onosproject.rest.AbstractWebResource;
import org.onosproject.vtnrsc.PortPairGroup;
import org.onosproject.vtnrsc.PortPairGroupId;
import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
-import org.onosproject.vtnweb.web.PortPairGroupCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
@@ -53,7 +53,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
public class PortPairGroupWebResource extends AbstractWebResource {
private final Logger log = LoggerFactory.getLogger(PortPairGroupWebResource.class);
- private final PortPairGroupService service = get(PortPairGroupService.class);
public static final String PORT_PAIR_GROUP_NOT_FOUND = "Port pair group not found";
public static final String PORT_PAIR_GROUP_ID_EXIST = "Port pair group exists";
public static final String PORT_PAIR_GROUP_ID_NOT_EXIST = "Port pair group does not exist with identifier";
@@ -66,10 +65,15 @@ public class PortPairGroupWebResource extends AbstractWebResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getPortPairGroups() {
- Iterable<PortPairGroup> portPairGroups = service.getPortPairGroups();
- ObjectNode result = new ObjectMapper().createObjectNode();
- result.set("port_pair_groups", new PortPairGroupCodec().encode(portPairGroups, this));
- return ok(result).build();
+ Iterable<PortPairGroup> portPairGroups = get(PortPairGroupService.class).getPortPairGroups();
+ ObjectNode result = mapper().createObjectNode();
+ ArrayNode portPairGroupEntry = result.putArray("port_pair_groups");
+ if (portPairGroups != null) {
+ for (final PortPairGroup portPairGroup : portPairGroups) {
+ portPairGroupEntry.add(codec(PortPairGroup.class).encode(portPairGroup, this));
+ }
+ }
+ return ok(result.toString()).build();
}
/**
@@ -82,17 +86,13 @@ public class PortPairGroupWebResource extends AbstractWebResource {
@Path("{group_id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getPortPairGroup(@PathParam("group_id") String id) {
-
- if (!service.exists(PortPairGroupId.of(id))) {
- return Response.status(NOT_FOUND)
- .entity(PORT_PAIR_GROUP_NOT_FOUND).build();
- }
- PortPairGroup portPairGroup = nullIsNotFound(service.getPortPairGroup(PortPairGroupId.of(id)),
+ PortPairGroup portPairGroup = nullIsNotFound(get(PortPairGroupService.class)
+ .getPortPairGroup(PortPairGroupId.of(id)),
PORT_PAIR_GROUP_NOT_FOUND);
- ObjectNode result = new ObjectMapper().createObjectNode();
- result.set("port_pair_group", new PortPairGroupCodec().encode(portPairGroup, this));
- return ok(result).build();
+ ObjectNode result = mapper().createObjectNode();
+ result.set("port_pair_group", codec(PortPairGroup.class).encode(portPairGroup, this));
+ return ok(result.toString()).build();
}
/**
@@ -108,10 +108,12 @@ public class PortPairGroupWebResource extends AbstractWebResource {
public Response createPortPairGroup(InputStream stream) {
try {
- ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode jsonTree = (ObjectNode) mapper.readTree(stream);
+ JsonNode port = jsonTree.get("port_pair_group");
- PortPairGroup portPairGroup = codec(PortPairGroup.class).decode(jsonTree, this);
- Boolean issuccess = nullIsNotFound(service.createPortPairGroup(portPairGroup),
+ PortPairGroup portPairGroup = codec(PortPairGroup.class).decode((ObjectNode) port, this);
+ Boolean issuccess = nullIsNotFound(get(PortPairGroupService.class).createPortPairGroup(portPairGroup),
PORT_PAIR_GROUP_NOT_FOUND);
return Response.status(OK).entity(issuccess.toString()).build();
} catch (IOException e) {
@@ -134,9 +136,12 @@ public class PortPairGroupWebResource extends AbstractWebResource {
public Response updatePortPairGroup(@PathParam("group_id") String id,
final InputStream stream) {
try {
- ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
- PortPairGroup portPairGroup = codec(PortPairGroup.class).decode(jsonTree, this);
- Boolean isSuccess = nullIsNotFound(service.updatePortPairGroup(portPairGroup), PORT_PAIR_GROUP_NOT_FOUND);
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode jsonTree = (ObjectNode) mapper.readTree(stream);
+ JsonNode port = jsonTree.get("port_pair_group");
+ PortPairGroup portPairGroup = codec(PortPairGroup.class).decode((ObjectNode) port, this);
+ Boolean isSuccess = nullIsNotFound(get(PortPairGroupService.class).updatePortPairGroup(portPairGroup),
+ PORT_PAIR_GROUP_NOT_FOUND);
return Response.status(OK).entity(isSuccess.toString()).build();
} catch (IOException e) {
log.error("Update port pair group failed because of exception {}.", e.toString());
@@ -154,7 +159,7 @@ public class PortPairGroupWebResource extends AbstractWebResource {
public void deletePortPairGroup(@PathParam("group_id") String id) {
log.debug("Deletes port pair group by identifier {}.", id);
PortPairGroupId portPairGroupId = PortPairGroupId.of(id);
- Boolean issuccess = nullIsNotFound(service.removePortPairGroup(portPairGroupId),
+ Boolean issuccess = nullIsNotFound(get(PortPairGroupService.class).removePortPairGroup(portPairGroupId),
PORT_PAIR_GROUP_NOT_FOUND);
if (!issuccess) {
log.debug("Port pair group identifier {} does not exist", id);
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairWebResource.java
index b9012898..4ed8ecd8 100644
--- a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairWebResource.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairWebResource.java
@@ -16,7 +16,6 @@
package org.onosproject.vtnweb.resources;
-import static javax.ws.rs.core.Response.Status.NOT_FOUND;
import static javax.ws.rs.core.Response.Status.OK;
import static org.onlab.util.Tools.nullIsNotFound;
@@ -38,12 +37,10 @@ import org.onosproject.rest.AbstractWebResource;
import org.onosproject.vtnrsc.PortPair;
import org.onosproject.vtnrsc.PortPairId;
import org.onosproject.vtnrsc.portpair.PortPairService;
-import org.onosproject.vtnweb.web.PortPairCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -54,7 +51,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
public class PortPairWebResource extends AbstractWebResource {
private final Logger log = LoggerFactory.getLogger(PortPairWebResource.class);
- private final PortPairService service = get(PortPairService.class);
public static final String PORT_PAIR_NOT_FOUND = "Port pair not found";
public static final String PORT_PAIR_ID_EXIST = "Port pair exists";
public static final String PORT_PAIR_ID_NOT_EXIST = "Port pair does not exist with identifier";
@@ -67,12 +63,12 @@ public class PortPairWebResource extends AbstractWebResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getPortPairs() {
- Iterable<PortPair> portPairs = service.getPortPairs();
- ObjectNode result = new ObjectMapper().createObjectNode();
+ Iterable<PortPair> portPairs = get(PortPairService.class).getPortPairs();
+ ObjectNode result = mapper().createObjectNode();
ArrayNode portPairEntry = result.putArray("port_pairs");
if (portPairs != null) {
for (final PortPair portPair : portPairs) {
- portPairEntry.add(new PortPairCodec().encode(portPair, this));
+ portPairEntry.add(codec(PortPair.class).encode(portPair, this));
}
}
return ok(result.toString()).build();
@@ -88,13 +84,10 @@ public class PortPairWebResource extends AbstractWebResource {
@Path("{pair_id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getPortPair(@PathParam("pair_id") String id) {
-
- if (!service.exists(PortPairId.of(id))) {
- return Response.status(NOT_FOUND).entity(PORT_PAIR_NOT_FOUND).build();
- }
- PortPair portPair = nullIsNotFound(service.getPortPair(PortPairId.of(id)), PORT_PAIR_NOT_FOUND);
- ObjectNode result = new ObjectMapper().createObjectNode();
- result.set("port_pair", new PortPairCodec().encode(portPair, this));
+ PortPair portPair = nullIsNotFound(get(PortPairService.class).getPortPair(PortPairId.of(id)),
+ PORT_PAIR_NOT_FOUND);
+ ObjectNode result = mapper().createObjectNode();
+ result.set("port_pair", codec(PortPair.class).encode(portPair, this));
return ok(result.toString()).build();
}
@@ -110,11 +103,11 @@ public class PortPairWebResource extends AbstractWebResource {
@Produces(MediaType.APPLICATION_JSON)
public Response createPortPair(InputStream stream) {
try {
- ObjectMapper mapper = new ObjectMapper();
- ObjectNode jsonTree = (ObjectNode) mapper.readTree(stream);
+ ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
JsonNode port = jsonTree.get("port_pair");
- PortPair portPair = new PortPairCodec().decode((ObjectNode) port, this);
- Boolean isSuccess = nullIsNotFound(service.createPortPair(portPair), PORT_PAIR_NOT_FOUND);
+ PortPair portPair = codec(PortPair.class).decode((ObjectNode) port, this);
+ Boolean isSuccess = nullIsNotFound(get(PortPairService.class).createPortPair(portPair),
+ PORT_PAIR_NOT_FOUND);
return Response.status(OK).entity(isSuccess.toString()).build();
} catch (IOException e) {
log.error("Exception while creating port pair {}.", e.toString());
@@ -136,11 +129,11 @@ public class PortPairWebResource extends AbstractWebResource {
public Response updatePortPair(@PathParam("pair_id") String id,
final InputStream stream) {
try {
- ObjectMapper mapper = new ObjectMapper();
- ObjectNode jsonTree = (ObjectNode) mapper.readTree(stream);
+ ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
JsonNode port = jsonTree.get("port_pair");
- PortPair portPair = new PortPairCodec().decode((ObjectNode) port, this);
- Boolean isSuccess = nullIsNotFound(service.updatePortPair(portPair), PORT_PAIR_NOT_FOUND);
+ PortPair portPair = codec(PortPair.class).decode((ObjectNode) port, this);
+ Boolean isSuccess = nullIsNotFound(get(PortPairService.class).updatePortPair(portPair),
+ PORT_PAIR_NOT_FOUND);
return Response.status(OK).entity(isSuccess.toString()).build();
} catch (IOException e) {
log.error("Update port pair failed because of exception {}.", e.toString());
@@ -158,7 +151,7 @@ public class PortPairWebResource extends AbstractWebResource {
public void deletePortPair(@PathParam("pair_id") String id) {
PortPairId portPairId = PortPairId.of(id);
- Boolean isSuccess = nullIsNotFound(service.removePortPair(portPairId), PORT_PAIR_NOT_FOUND);
+ Boolean isSuccess = nullIsNotFound(get(PortPairService.class).removePortPair(portPairId), PORT_PAIR_NOT_FOUND);
if (!isSuccess) {
log.debug("Port pair identifier {} does not exist", id);
}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/VtnCodecRegistrator.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/VtnCodecRegistrator.java
new file mode 100644
index 00000000..e2defe59
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/VtnCodecRegistrator.java
@@ -0,0 +1,56 @@
+/*
+ * 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.vtnweb.web;
+
+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.onosproject.codec.CodecService;
+import org.onosproject.vtnrsc.FlowClassifier;
+import org.onosproject.vtnrsc.PortChain;
+import org.onosproject.vtnrsc.PortPair;
+import org.onosproject.vtnrsc.PortPairGroup;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation of the JSON codec brokering service for VTN app.
+ */
+@Component(immediate = true)
+public class VtnCodecRegistrator {
+
+ private static Logger log = LoggerFactory.getLogger(VtnCodecRegistrator.class);
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CodecService codecService;
+
+ @Activate
+ public void activate() {
+ codecService.registerCodec(PortPair.class, new PortPairCodec());
+ codecService.registerCodec(PortPairGroup.class, new PortPairGroupCodec());
+ codecService.registerCodec(FlowClassifier.class, new FlowClassifierCodec());
+ codecService.registerCodec(PortChain.class, new PortChainCodec());
+
+ log.info("Started");
+ }
+
+ @Deactivate
+ public void deactivate() {
+ log.info("Stopped");
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/FlowClassifierResourceTest.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/FlowClassifierResourceTest.java
index be645be0..db08d7c4 100644
--- a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/FlowClassifierResourceTest.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/FlowClassifierResourceTest.java
@@ -40,11 +40,13 @@ import org.onlab.osgi.ServiceDirectory;
import org.onlab.osgi.TestServiceDirectory;
import org.onlab.packet.IpPrefix;
import org.onlab.rest.BaseResource;
+import org.onosproject.codec.CodecService;
import org.onosproject.vtnrsc.FlowClassifier;
import org.onosproject.vtnrsc.FlowClassifierId;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.VirtualPortId;
import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService;
+import org.onosproject.vtnweb.web.SfcCodecContext;
import com.eclipsesource.json.JsonObject;
import com.sun.jersey.api.client.ClientResponse;
@@ -192,8 +194,11 @@ public class FlowClassifierResourceTest extends VtnResourceTest {
*/
@Before
public void setUpTest() {
- ServiceDirectory testDirectory = new TestServiceDirectory().add(FlowClassifierService.class,
- flowClassifierService);
+ SfcCodecContext context = new SfcCodecContext();
+
+ ServiceDirectory testDirectory = new TestServiceDirectory()
+ .add(FlowClassifierService.class, flowClassifierService)
+ .add(CodecService.class, context.codecManager());
BaseResource.setServiceDirectory(testDirectory);
}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortChainResourceTest.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortChainResourceTest.java
new file mode 100644
index 00000000..3cb2c83f
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortChainResourceTest.java
@@ -0,0 +1,247 @@
+/*
+ * 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.vtnweb.resources;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+import javax.ws.rs.core.MediaType;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onlab.rest.BaseResource;
+import org.onosproject.codec.CodecService;
+import org.onosproject.vtnrsc.FlowClassifierId;
+import org.onosproject.vtnrsc.PortChain;
+import org.onosproject.vtnrsc.PortChainId;
+import org.onosproject.vtnrsc.PortPairGroupId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.portchain.PortChainService;
+import org.onosproject.vtnweb.web.SfcCodecContext;
+
+import com.eclipsesource.json.JsonObject;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.UniformInterfaceException;
+import com.sun.jersey.api.client.WebResource;
+
+/**
+ * Unit tests for port chain REST APIs.
+ */
+public class PortChainResourceTest extends VtnResourceTest {
+
+ final PortChainService portChainService = createMock(PortChainService.class);
+
+ PortChainId portChainId1 = PortChainId.of("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae");
+ TenantId tenantId1 = TenantId.tenantId("d382007aa9904763a801f68ecf065cf5");
+ private final List<PortPairGroupId> portPairGroupList1 = Lists.newArrayList();
+ private final List<FlowClassifierId> flowClassifierList1 = Lists.newArrayList();
+
+
+ final MockPortChain portChain1 = new MockPortChain(portChainId1, tenantId1, "portChain1",
+ "Mock port chain", portPairGroupList1,
+ flowClassifierList1);
+
+ /**
+ * Mock class for a port chain.
+ */
+ private static class MockPortChain 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;
+
+ public MockPortChain(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 boolean exactMatch(PortChain portChain) {
+ return this.equals(portChain) &&
+ Objects.equals(this.portChainId, portChain.portChainId()) &&
+ Objects.equals(this.tenantId, portChain.tenantId());
+ }
+ }
+
+ /**
+ * Sets up the global values for all the tests.
+ */
+ @Before
+ public void setUpTest() {
+ SfcCodecContext context = new SfcCodecContext();
+ ServiceDirectory testDirectory = new TestServiceDirectory()
+ .add(PortChainService.class, portChainService)
+ .add(CodecService.class, context.codecManager());
+ BaseResource.setServiceDirectory(testDirectory);
+
+ }
+
+ /**
+ * Cleans up.
+ */
+ @After
+ public void tearDownTest() {
+ }
+
+ /**
+ * Tests the result of the rest api GET when there are no port chains.
+ */
+ @Test
+ public void testPortChainsEmpty() {
+
+ expect(portChainService.getPortChains()).andReturn(null).anyTimes();
+ replay(portChainService);
+ final WebResource rs = resource();
+ final String response = rs.path("port_chains").get(String.class);
+ assertThat(response, is("{\"port_chains\":[]}"));
+ }
+
+ /**
+ * Tests the result of a rest api GET for port chain id.
+ */
+ @Test
+ public void testGetPortChainId() {
+
+ final Set<PortChain> portChains = new HashSet<>();
+ portChains.add(portChain1);
+
+ expect(portChainService.exists(anyObject())).andReturn(true).anyTimes();
+ expect(portChainService.getPortChain(anyObject())).andReturn(portChain1).anyTimes();
+ replay(portChainService);
+
+ final WebResource rs = resource();
+ final String response = rs.path("port_chains/1278dcd4-459f-62ed-754b-87fc5e4a6751").get(String.class);
+ final JsonObject result = JsonObject.readFrom(response);
+ assertThat(result, notNullValue());
+ }
+
+ /**
+ * Tests that a fetch of a non-existent port chain object throws an exception.
+ */
+ @Test
+ public void testBadGet() {
+ expect(portChainService.getPortChain(anyObject()))
+ .andReturn(null).anyTimes();
+ replay(portChainService);
+ WebResource rs = resource();
+ try {
+ rs.path("port_chains/78dcd363-fc23-aeb6-f44b-56dc5aafb3ae").get(String.class);
+ fail("Fetch of non-existent port chain did not throw an exception");
+ } catch (UniformInterfaceException ex) {
+ assertThat(ex.getMessage(),
+ containsString("returned a response status of"));
+ }
+ }
+
+ /**
+ * Tests creating a port chain with POST.
+ */
+ @Test
+ public void testPost() {
+
+ expect(portChainService.createPortChain(anyObject()))
+ .andReturn(true).anyTimes();
+ replay(portChainService);
+
+ WebResource rs = resource();
+ InputStream jsonStream = PortChainResourceTest.class.getResourceAsStream("post-PortChain.json");
+
+ ClientResponse response = rs.path("port_chains")
+ .type(MediaType.APPLICATION_JSON_TYPE)
+ .post(ClientResponse.class, jsonStream);
+ assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
+ }
+
+ /**
+ * Tests deleting a port chain.
+ */
+ @Test
+ public void testDelete() {
+ expect(portChainService.removePortChain(anyObject()))
+ .andReturn(true).anyTimes();
+ replay(portChainService);
+
+ WebResource rs = resource();
+
+ String location = "port_chains/1278dcd4-459f-62ed-754b-87fc5e4a6751";
+
+ ClientResponse deleteResponse = rs.path(location)
+ .type(MediaType.APPLICATION_JSON_TYPE)
+ .delete(ClientResponse.class);
+ assertThat(deleteResponse.getStatus(),
+ is(HttpURLConnection.HTTP_NO_CONTENT));
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairGroupResourceTest.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairGroupResourceTest.java
new file mode 100644
index 00000000..c13f2141
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairGroupResourceTest.java
@@ -0,0 +1,234 @@
+/*
+ * 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.vtnweb.resources;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+import javax.ws.rs.core.MediaType;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onlab.rest.BaseResource;
+import org.onosproject.codec.CodecService;
+import org.onosproject.vtnrsc.PortPairGroup;
+import org.onosproject.vtnrsc.PortPairGroupId;
+import org.onosproject.vtnrsc.PortPairId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
+import org.onosproject.vtnweb.web.SfcCodecContext;
+
+import com.eclipsesource.json.JsonObject;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.UniformInterfaceException;
+import com.sun.jersey.api.client.WebResource;
+/**
+ * Unit tests for port pair group REST APIs.
+ */
+public class PortPairGroupResourceTest extends VtnResourceTest {
+
+ final PortPairGroupService portPairGroupService = createMock(PortPairGroupService.class);
+
+ PortPairGroupId portPairGroupId1 = PortPairGroupId.of("4512d643-24fc-4fae-af4b-321c5e2eb3d1");
+ TenantId tenantId1 = TenantId.tenantId("d382007aa9904763a801f68ecf065cf5");
+ private final List<PortPairId> portPairList1 = Lists.newArrayList();
+
+ final MockPortPairGroup portPairGroup1 = new MockPortPairGroup(portPairGroupId1, tenantId1, "portPairGroup1",
+ "Mock port pair group", portPairList1);
+
+ /**
+ * Mock class for a port pair group.
+ */
+ private static class MockPortPairGroup implements PortPairGroup {
+
+ private final PortPairGroupId portPairGroupId;
+ private final TenantId tenantId;
+ private final String name;
+ private final String description;
+ private final List<PortPairId> portPairList;
+
+ public MockPortPairGroup(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 boolean exactMatch(PortPairGroup portPairGroup) {
+ return this.equals(portPairGroup) &&
+ Objects.equals(this.portPairGroupId, portPairGroup.portPairGroupId()) &&
+ Objects.equals(this.tenantId, portPairGroup.tenantId());
+ }
+ }
+
+ /**
+ * Sets up the global values for all the tests.
+ */
+ @Before
+ public void setUpTest() {
+ SfcCodecContext context = new SfcCodecContext();
+ ServiceDirectory testDirectory = new TestServiceDirectory()
+ .add(PortPairGroupService.class, portPairGroupService)
+ .add(CodecService.class, context.codecManager());
+ BaseResource.setServiceDirectory(testDirectory);
+
+ }
+
+ /**
+ * Cleans up.
+ */
+ @After
+ public void tearDownTest() {
+ }
+
+ /**
+ * Tests the result of the rest api GET when there are no port pair groups.
+ */
+ @Test
+ public void testPortPairGroupsEmpty() {
+
+ expect(portPairGroupService.getPortPairGroups()).andReturn(null).anyTimes();
+ replay(portPairGroupService);
+ final WebResource rs = resource();
+ final String response = rs.path("port_pair_groups").get(String.class);
+ assertThat(response, is("{\"port_pair_groups\":[]}"));
+ }
+
+ /**
+ * Tests the result of a rest api GET for port pair group id.
+ */
+ @Test
+ public void testGetPortPairGroupId() {
+
+ final Set<PortPairGroup> portPairGroups = new HashSet<>();
+ portPairGroups.add(portPairGroup1);
+
+ expect(portPairGroupService.exists(anyObject())).andReturn(true).anyTimes();
+ expect(portPairGroupService.getPortPairGroup(anyObject())).andReturn(portPairGroup1).anyTimes();
+ replay(portPairGroupService);
+
+ final WebResource rs = resource();
+ final String response = rs.path("port_pair_groups/4512d643-24fc-4fae-af4b-321c5e2eb3d1").get(String.class);
+ final JsonObject result = JsonObject.readFrom(response);
+ assertThat(result, notNullValue());
+ }
+
+ /**
+ * Tests that a fetch of a non-existent port pair group object throws an exception.
+ */
+ @Test
+ public void testBadGet() {
+ expect(portPairGroupService.getPortPairGroup(anyObject()))
+ .andReturn(null).anyTimes();
+ replay(portPairGroupService);
+ WebResource rs = resource();
+ try {
+ rs.path("port_pair_groups/78dcd363-fc23-aeb6-f44b-56dc5aafb3ae").get(String.class);
+ fail("Fetch of non-existent port pair group did not throw an exception");
+ } catch (UniformInterfaceException ex) {
+ assertThat(ex.getMessage(),
+ containsString("returned a response status of"));
+ }
+ }
+
+ /**
+ * Tests creating a port pair group with POST.
+ */
+ @Test
+ public void testPost() {
+
+ expect(portPairGroupService.createPortPairGroup(anyObject()))
+ .andReturn(true).anyTimes();
+ replay(portPairGroupService);
+
+ WebResource rs = resource();
+ InputStream jsonStream = PortPairGroupResourceTest.class.getResourceAsStream("post-PortPairGroup.json");
+
+ ClientResponse response = rs.path("port_pair_groups")
+ .type(MediaType.APPLICATION_JSON_TYPE)
+ .post(ClientResponse.class, jsonStream);
+ assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
+ }
+
+ /**
+ * Tests deleting a port pair group.
+ */
+ @Test
+ public void testDelete() {
+ expect(portPairGroupService.removePortPairGroup(anyObject()))
+ .andReturn(true).anyTimes();
+ replay(portPairGroupService);
+
+ WebResource rs = resource();
+
+ String location = "port_pair_groups/4512d643-24fc-4fae-af4b-321c5e2eb3d1";
+
+ ClientResponse deleteResponse = rs.path(location)
+ .type(MediaType.APPLICATION_JSON_TYPE)
+ .delete(ClientResponse.class);
+ assertThat(deleteResponse.getStatus(),
+ is(HttpURLConnection.HTTP_NO_CONTENT));
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairResourceTest.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairResourceTest.java
index 271904cc..36014ec5 100644
--- a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairResourceTest.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairResourceTest.java
@@ -39,10 +39,12 @@ import org.junit.Test;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.osgi.TestServiceDirectory;
import org.onlab.rest.BaseResource;
+import org.onosproject.codec.CodecService;
import org.onosproject.vtnrsc.PortPair;
import org.onosproject.vtnrsc.PortPairId;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.portpair.PortPairService;
+import org.onosproject.vtnweb.web.SfcCodecContext;
import com.eclipsesource.json.JsonObject;
import com.sun.jersey.api.client.ClientResponse;
@@ -129,7 +131,10 @@ public class PortPairResourceTest extends VtnResourceTest {
*/
@Before
public void setUpTest() {
- ServiceDirectory testDirectory = new TestServiceDirectory().add(PortPairService.class, portPairService);
+
+ SfcCodecContext context = new SfcCodecContext();
+ ServiceDirectory testDirectory = new TestServiceDirectory().add(PortPairService.class, portPairService)
+ .add(CodecService.class, context.codecManager());
BaseResource.setServiceDirectory(testDirectory);
}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/SfcCodecContext.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/SfcCodecContext.java
index fe9d7995..c56a4fcb 100644
--- a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/SfcCodecContext.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/SfcCodecContext.java
@@ -15,15 +15,10 @@
*/
package org.onosproject.vtnweb.web;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.CodecService;
import org.onosproject.codec.JsonCodec;
-import org.onosproject.vtnrsc.FlowClassifier;
-import org.onosproject.vtnrsc.PortChain;
-import org.onosproject.vtnrsc.PortPair;
-import org.onosproject.vtnrsc.PortPairGroup;
+import org.onosproject.codec.impl.CodecManager;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -33,17 +28,16 @@ import com.fasterxml.jackson.databind.ObjectMapper;
public class SfcCodecContext implements CodecContext {
private final ObjectMapper mapper = new ObjectMapper();
- private final Map<Class<?>, JsonCodec> codecs = new ConcurrentHashMap<>();
+ private final CodecManager codecManager = new CodecManager();
+ private final VtnCodecRegistrator manager = new VtnCodecRegistrator();
/**
* Constructs a new mock codec context.
*/
public SfcCodecContext() {
- codecs.clear();
- registerCodec(PortPair.class, new PortPairCodec());
- registerCodec(PortChain.class, new PortChainCodec());
- registerCodec(PortPairGroup.class, new PortPairGroupCodec());
- registerCodec(FlowClassifier.class, new FlowClassifierCodec());
+ codecManager.activate();
+ manager.codecService = codecManager;
+ manager.activate();
}
@Override
@@ -58,20 +52,17 @@ public class SfcCodecContext implements CodecContext {
return null;
}
+ @Override
+ public <T> JsonCodec<T> codec(Class<T> entityClass) {
+ return codecManager.getCodec(entityClass);
+ }
+
/**
- * Registers the specified JSON codec for the given entity class.
+ * Get the codec manager.
*
- * @param entityClass entity class
- * @param codec JSON codec
- * @param <T> entity type
+ * @return instance of codec manager
*/
- public <T> void registerCodec(Class<T> entityClass, JsonCodec<T> codec) {
- codecs.putIfAbsent(entityClass, codec);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public <T> JsonCodec<T> codec(Class<T> entityClass) {
- return codecs.get(entityClass);
+ public CodecService codecManager() {
+ return codecManager;
}
}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortChain.json b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortChain.json
new file mode 100644
index 00000000..488e290f
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortChain.json
@@ -0,0 +1,15 @@
+{"port_pair": {
+ "id": "1278dcd4-459f-62ed-754b-87fc5e4a6751",
+ "name": "PC2",
+ "tenant_id": "d382007aa9904763a801f68ecf065cf5",
+ "description": "Two flows and two port-pair-groups",
+ "flow_classifiers": [
+ "456a4a34-2e9c-14ae-37fb-765feae2eb05",
+ "4a334cd4-fe9c-4fae-af4b-321c5e2eb051"
+ ],
+ "port_pair_groups": [
+ "4512d643-24fc-4fae-af4b-321c5e2eb3d1",
+ "4a634d49-76dc-4fae-af4b-321c5e23d651"
+ ]
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortPairGroup.json b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortPairGroup.json
new file mode 100644
index 00000000..f6a888d9
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortPairGroup.json
@@ -0,0 +1,11 @@
+{"port_pair_group": {
+ "id": "4512d643-24fc-4fae-af4b-321c5e2eb3d1",
+ "name": "portPairGroup1",
+ "tenant_id": "d382007aa9904763a801f68ecf065cf5",
+ "description": "Mock port pair group",
+ "port_pairs": [
+ "875dfeda-43ed-23fe-454b-764feab2c342",
+ "78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae"
+ ]
+}
+}