[ONOS-3835] Install load balanced classifier rules

Change-Id: I585a83021dbf2aff6a65dd43944a1f6979b33ead
diff --git a/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/FlowClassifierInstallerService.java b/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/FlowClassifierInstallerService.java
index fddcf4d..9a66ffa 100644
--- a/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/FlowClassifierInstallerService.java
+++ b/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/FlowClassifierInstallerService.java
@@ -1,10 +1,24 @@
+/*
+ * Copyright 2016 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.installer;
 
+import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.NshServicePathId;
-import org.onosproject.net.flowobjective.Objective.Operation;
-import org.onosproject.vtnrsc.FlowClassifier;
+import org.onosproject.vtnrsc.FiveTuple;
 import org.onosproject.vtnrsc.PortChain;
-import org.onosproject.vtnrsc.PortPair;
 
 /**
  * Abstraction of an entity which installs flow classification rules in ovs.
@@ -12,29 +26,38 @@
 public interface FlowClassifierInstallerService {
 
     /**
-     * Install Flow-Classifier.
+     * Install flow classifier.
      *
      * @param portChain port-chain
-     * @param nshSpiId nsh spi-id
+     * @param nshSpiId service path index identifier
      */
-    void installFlowClassifier(PortChain portChain, NshServicePathId nshSpiId);
+    ConnectPoint installFlowClassifier(PortChain portChain, NshServicePathId nshSpiId);
 
     /**
-     * Uninstall Flow-Classifier.
+     * Uninstall flow classifier.
      *
      * @param portChain port-chain
-     * @param nshSpiId nsh spi-id
+     * @param nshSpiId service path index identifier
      */
-    void unInstallFlowClassifier(PortChain portChain, NshServicePathId nshSpiId);
+    ConnectPoint unInstallFlowClassifier(PortChain portChain, NshServicePathId nshSpiId);
 
     /**
-     * Prepare forwarding object for flow classifier.
+     * Install load balanced flow classifier.
      *
-     * @param flowClassifier flow classifier
-     * @param portPair port pair
-     * @param nshSpiId nsh spi id
-     * @param type forwarding objective operation type
+     * @param portChain port-chain
+     * @param fiveTuple five tuple packet information
+     * @param nshSpiId service path index identifier
      */
-    void prepareFlowClassification(FlowClassifier flowClassifier, PortPair portPair, NshServicePathId nshSpiId,
-                                   Operation type);
+    ConnectPoint installLoadBalancedFlowClassifier(PortChain portChain, FiveTuple fiveTuple,
+                                                   NshServicePathId nshSpiId);
+
+    /**
+     * Uninstall load balanced flow classifier.
+     *
+     * @param portChain port-chain
+     * @param fiveTuple five tuple packet information
+     * @param nshSpiId service path index identifier
+     */
+    ConnectPoint unInstallLoadBalancedFlowClassifier(PortChain portChain, FiveTuple fiveTuple,
+                                                     NshServicePathId nshSpiId);
 }
diff --git a/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/impl/FlowClassifierInstallerImpl.java b/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/impl/FlowClassifierInstallerImpl.java
index caebbd9..70d1d21 100644
--- a/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/impl/FlowClassifierInstallerImpl.java
+++ b/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/impl/FlowClassifierInstallerImpl.java
@@ -15,20 +15,29 @@
  */
 package org.onosproject.sfc.installer.impl;
 
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.Service;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SI;
+import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SPI;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+
 import org.onlab.osgi.DefaultServiceDirectory;
 import org.onlab.osgi.ServiceDirectory;
 import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.IpPrefix;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.TpPort;
 import org.onlab.packet.VlanId;
 import org.onosproject.core.ApplicationId;
+import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Host;
 import org.onosproject.net.HostId;
+import org.onosproject.net.NshServiceIndex;
 import org.onosproject.net.NshServicePathId;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
@@ -46,9 +55,9 @@
 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.net.host.HostService;
 import org.onosproject.sfc.installer.FlowClassifierInstallerService;
+import org.onosproject.vtnrsc.FiveTuple;
 import org.onosproject.vtnrsc.FlowClassifier;
 import org.onosproject.vtnrsc.FlowClassifierId;
 import org.onosproject.vtnrsc.PortChain;
@@ -64,48 +73,20 @@
 import org.onosproject.vtnrsc.virtualport.VirtualPortService;
 import org.slf4j.Logger;
 
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SI;
-import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SPI;
-import static org.slf4j.LoggerFactory.getLogger;
-
 /**
  * Provides flow classifier installer implementation.
  */
-@Component(immediate = true)
-@Service
 public class FlowClassifierInstallerImpl implements FlowClassifierInstallerService {
-
     private final Logger log = getLogger(getClass());
 
-    @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 DriverService driverService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected DeviceService deviceService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected HostService hostService;
-
     protected FlowObjectiveService flowObjectiveService;
     protected ApplicationId appId;
 
@@ -114,8 +95,8 @@
     private static final String FLOW_CLASSIFIER_ID_NOT_NULL = "Flow-Classifier-Id cannot be null";
     private static final String PORT_CHAIN_NOT_NULL = "Port-Chain cannot be null";
     private static final int NULL = 0;
-    private static final int L3FWD_PRIORITY = 0xffff;
-    private static final int NSH_SI_ID = 0xff;
+    private static final int FLOW_CLASSIFIER_PRIORITY = 0x7fff;
+    private static final short NSH_SI_ID = 0xff;
 
     /**
      * Default constructor.
@@ -126,40 +107,102 @@
     /**
      * Explicit constructor.
      *
-     * @param appId Application ID.
+     * @param appId application id.
      */
     public FlowClassifierInstallerImpl(ApplicationId appId) {
         this.appId = checkNotNull(appId, "ApplicationId can not be null");
         ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
         this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class);
+        this.driverService = serviceDirectory.get(DriverService.class);
+        this.deviceService = serviceDirectory.get(DeviceService.class);
+        this.hostService = serviceDirectory.get(HostService.class);
+        this.virtualPortService = serviceDirectory.get(VirtualPortService.class);
+        this.vtnRscService = serviceDirectory.get(VtnRscService.class);
+        this.portPairService = serviceDirectory.get(PortPairService.class);
+        this.portPairGroupService = serviceDirectory.get(PortPairGroupService.class);
+        this.flowClassifierService = serviceDirectory.get(FlowClassifierService.class);
     }
 
     @Override
-    public void installFlowClassifier(PortChain portChain, NshServicePathId nshSpiId) {
+    public ConnectPoint installFlowClassifier(PortChain portChain, NshServicePathId nshSpiId) {
         checkNotNull(portChain, PORT_CHAIN_NOT_NULL);
-        processFlowClassifier(portChain, nshSpiId, Objective.Operation.ADD);
-    }
-
-    @Override
-    public void unInstallFlowClassifier(PortChain portChain, NshServicePathId nshSpiId) {
-        checkNotNull(portChain, PORT_CHAIN_NOT_NULL);
-        processFlowClassifier(portChain, nshSpiId, Objective.Operation.REMOVE);
-    }
-
-    public void processFlowClassifier(PortChain portChain, NshServicePathId nshSpiId, Objective.Operation type) {
-
-        // get the portPairGroup
+        // Get the portPairGroup
         List<PortPairGroupId> llPortPairGroupIdList = portChain.portPairGroups();
         ListIterator<PortPairGroupId> portPairGroupIdListIterator = llPortPairGroupIdList.listIterator();
         PortPairGroupId portPairGroupId = portPairGroupIdListIterator.next();
         PortPairGroup portPairGroup = portPairGroupService.getPortPairGroup(portPairGroupId);
         List<PortPairId> llPortPairIdList = portPairGroup.portPairs();
 
-        // get port pair
+        // Get port pair
         ListIterator<PortPairId> portPairListIterator = llPortPairIdList.listIterator();
         PortPairId portPairId = portPairListIterator.next();
         PortPair portPair = portPairService.getPortPair(portPairId);
 
+        return processFlowClassifier(portChain, portPair, nshSpiId, null, Objective.Operation.ADD);
+    }
+
+    @Override
+    public ConnectPoint unInstallFlowClassifier(PortChain portChain, NshServicePathId nshSpiId) {
+        checkNotNull(portChain, PORT_CHAIN_NOT_NULL);
+        // Get the portPairGroup
+        List<PortPairGroupId> llPortPairGroupIdList = portChain.portPairGroups();
+        ListIterator<PortPairGroupId> portPairGroupIdListIterator = llPortPairGroupIdList.listIterator();
+        PortPairGroupId portPairGroupId = portPairGroupIdListIterator.next();
+        PortPairGroup portPairGroup = portPairGroupService.getPortPairGroup(portPairGroupId);
+        List<PortPairId> llPortPairIdList = portPairGroup.portPairs();
+
+        // Get port pair
+        ListIterator<PortPairId> portPairListIterator = llPortPairIdList.listIterator();
+        PortPairId portPairId = portPairListIterator.next();
+        PortPair portPair = portPairService.getPortPair(portPairId);
+
+        return processFlowClassifier(portChain, portPair, nshSpiId, null, Objective.Operation.REMOVE);
+    }
+
+    @Override
+    public ConnectPoint installLoadBalancedFlowClassifier(PortChain portChain, FiveTuple fiveTuple,
+                                                          NshServicePathId nshSpiId) {
+        checkNotNull(portChain, PORT_CHAIN_NOT_NULL);
+
+        // Get the load balanced path
+        List<PortPairId> portPairs = portChain.getLoadBalancePath(fiveTuple);
+
+        // Get the first port pair
+        ListIterator<PortPairId> portPairListIterator = portPairs.listIterator();
+        PortPairId portPairId = portPairListIterator.next();
+        PortPair portPair = portPairService.getPortPair(portPairId);
+
+        return processFlowClassifier(portChain, portPair, nshSpiId, fiveTuple, Objective.Operation.ADD);
+    }
+
+    @Override
+    public ConnectPoint unInstallLoadBalancedFlowClassifier(PortChain portChain, FiveTuple fiveTuple,
+                                                            NshServicePathId nshSpiId) {
+        checkNotNull(portChain, PORT_CHAIN_NOT_NULL);
+        // Get the load balanced path
+        List<PortPairId> portPairs = portChain.getLoadBalancePath(fiveTuple);
+
+        // Get the first port pair
+        ListIterator<PortPairId> portPairListIterator = portPairs.listIterator();
+        PortPairId portPairId = portPairListIterator.next();
+        PortPair portPair = portPairService.getPortPair(portPairId);
+
+        return processFlowClassifier(portChain, portPair, nshSpiId, fiveTuple, Objective.Operation.REMOVE);
+    }
+
+    public ConnectPoint processFlowClassifier(PortChain portChain, PortPair portPair, NshServicePathId nshSpiId,
+                                              FiveTuple fiveTuple, Objective.Operation type) {
+
+        DeviceId deviceIdfromPortPair = vtnRscService.getSfToSffMaping(VirtualPortId.portId(portPair.ingress()));
+        MacAddress srcMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.ingress())).macAddress();
+        Host host = hostService.getHost(HostId.hostId(srcMacAddress));
+        PortNumber port = host.location().port();
+
+        DeviceId deviceId = deviceIdfromPortPair;
+
+        // Vxlan tunnel port for NSH header(Vxlan + NSH).
+        TpPort nshDstPort = TpPort.tpPort(6633);
+
         FlowClassifierInstallerService flowclassifierinstallerService;
         // get flow classifiers
         List<FlowClassifierId> llFlowClassifierList = portChain.flowClassifiers();
@@ -168,61 +211,76 @@
         while (flowClassifierListIterator.hasNext()) {
             FlowClassifierId flowclassifierId = flowClassifierListIterator.next();
             FlowClassifier flowClassifier = flowClassifierService.getFlowClassifier(flowclassifierId);
-            prepareFlowClassification(flowClassifier, portPair, nshSpiId, type);
+
+            if ((flowClassifier.srcPort() != null) && (!flowClassifier.srcPort().portId().isEmpty())) {
+                deviceId = vtnRscService.getSfToSffMaping(flowClassifier.srcPort());
+            }
+
+            // Build Traffic selector.
+            TrafficSelector.Builder selector = packTrafficSelector(flowClassifier, fiveTuple);
+
+            if (fiveTuple == null) {
+                // Send the packet to controller
+                TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+                treatment.setOutput(PortNumber.CONTROLLER);
+                sendServiceFunctionClassifier(selector, treatment, deviceId, type);
+            } else if (deviceId.equals(deviceIdfromPortPair)) {
+                // classifier and source device are in the same OVS. So directly send packet to first port pair
+                TrafficTreatment.Builder treatment = packTrafficTreatment(deviceId, port, nshDstPort,
+                                                                          nshSpiId, flowClassifier, true);
+                // Build forwarding objective and send to OVS.
+                sendServiceFunctionClassifier(selector, treatment, deviceId, type);
+            } else {
+                // classifier and source device are not in the same OVS. Send packet on vlan Tunnel
+                TrafficTreatment.Builder treatment = packTrafficTreatment(deviceId, port, nshDstPort,
+                                                                          nshSpiId, flowClassifier, false);
+                // Build forwarding objective and send to OVS.
+                sendServiceFunctionClassifier(selector, treatment, deviceId, type);
+
+                // At the other device get the packet from vlan and send to first port pair
+                TrafficSelector.Builder selectorDst = DefaultTrafficSelector.builder();
+                selectorDst.matchVlanId((VlanId.vlanId(Short.parseShort((vtnRscService
+                        .getL3vni(flowClassifier.tenantId()).toString())))));
+                TrafficTreatment.Builder treatmentDst = DefaultTrafficTreatment.builder();
+                Host hostDst = hostService.getHost(HostId.hostId(srcMacAddress));
+                treatmentDst.setOutput(hostDst.location().port());
+                sendServiceFunctionClassifier(selectorDst, treatmentDst, deviceIdfromPortPair, type);
+            }
         }
-    }
-
-    @Override
-    public void prepareFlowClassification(FlowClassifier flowClassifier, PortPair portPair, NshServicePathId nshSpi,
-                                          Operation type) {
-        DeviceId deviceId = null;
-        // device id if virtual ports are set in flow classifier.
-        DeviceId deviceIdfromFc = null;
-        // device id if port pair is used to fetch device id.
-        DeviceId deviceIdfromPp = null;
-        MacAddress srcMacAddress = null;
-        // Vxlan tunnel port for NSH header(Vxlan + NSH).
-        TpPort nshDstPort = TpPort.tpPort(6633);
-
-        if ((flowClassifier.srcPort() != null) && (!flowClassifier.srcPort().portId().isEmpty())) {
-            deviceIdfromFc = vtnRscService.getSfToSffMaping(flowClassifier.srcPort());
-            deviceId = deviceIdfromFc;
-        } else {
-            deviceIdfromPp = vtnRscService.getSfToSffMaping(VirtualPortId.portId(portPair.ingress()));
-            srcMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.egress())).macAddress();
-            deviceId = deviceIdfromPp;
-        }
-
-        // Build Traffic selector.
-        TrafficSelector.Builder selector = packTrafficSelector(flowClassifier);
-
-        // Build traffic treatment.
-        TrafficTreatment.Builder treatment = packTrafficTreatment(deviceId, srcMacAddress, nshDstPort, deviceIdfromFc,
-                                                                  deviceIdfromPp, nshSpi, flowClassifier);
-
-        // Build forwarding objective and send to OVS.
-        sendServiceFunctionForwarder(selector, treatment, deviceId, type);
+        return host.location();
     }
 
     /**
      * Pack Traffic selector.
      *
      * @param flowClassifier flow-classifier
+     * @param fiveTuple five tuple info for the packet
      * @return traffic selector
      */
-    public TrafficSelector.Builder packTrafficSelector(FlowClassifier flowClassifier) {
+    public TrafficSelector.Builder packTrafficSelector(FlowClassifier flowClassifier, FiveTuple fiveTuple) {
+
         TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
 
         if ((flowClassifier.srcIpPrefix() != null) && (flowClassifier.srcIpPrefix().prefixLength() != 0)) {
             selector.matchIPSrc(flowClassifier.srcIpPrefix());
+        } else if (fiveTuple != null && fiveTuple.ipSrc() != null) {
+            selector.matchIPSrc(IpPrefix.valueOf(fiveTuple.ipSrc(), 24));
         }
 
         if ((flowClassifier.dstIpPrefix() != null) && (flowClassifier.dstIpPrefix().prefixLength() != 0)) {
             selector.matchIPDst(flowClassifier.dstIpPrefix());
+        } else if (fiveTuple != null && fiveTuple.ipDst() != null) {
+            selector.matchIPDst(IpPrefix.valueOf(fiveTuple.ipDst(), 24));
         }
 
         if ((flowClassifier.protocol() != null) && (!flowClassifier.protocol().isEmpty())) {
-            selector.add(Criteria.matchIPProtocol(Short.parseShort(flowClassifier.protocol())));
+            if (flowClassifier.protocol().equalsIgnoreCase("TCP")) {
+                selector.add(Criteria.matchIPProtocol(IPv4.PROTOCOL_TCP));
+            } else if (flowClassifier.protocol().equalsIgnoreCase("UDP")) {
+                selector.add(Criteria.matchIPProtocol(IPv4.PROTOCOL_UDP));
+            }
+        } else if (fiveTuple != null && fiveTuple.protocol() != 0) {
+            selector.add(Criteria.matchIPProtocol(fiveTuple.protocol()));
         }
 
         if (((flowClassifier.etherType() != null) && (!flowClassifier.etherType().isEmpty()))
@@ -234,24 +292,38 @@
             }
         }
 
-        List<TpPort> srcPortRange = new LinkedList<>();
-        List<TpPort> dstPortRange = new LinkedList<>();
-        if ((flowClassifier.minSrcPortRange() != 0) && flowClassifier.maxSrcPortRange() != 0
-                && flowClassifier.minDstPortRange() != 0 && flowClassifier.maxDstPortRange() != 0) {
-
-            for (int port = flowClassifier.minSrcPortRange(); port <= flowClassifier.maxSrcPortRange(); port++) {
-                srcPortRange.add(TpPort.tpPort(port));
-            }
-            for (int port = flowClassifier.minDstPortRange(); port <= flowClassifier.maxDstPortRange(); port++) {
-                dstPortRange.add(TpPort.tpPort(port));
-            }
+        if ((flowClassifier.srcPort() != null) && (!flowClassifier.srcPort().portId().isEmpty())) {
+            VirtualPortId vPortId = VirtualPortId.portId(flowClassifier.srcPort().portId());
+            MacAddress macAddress = virtualPortService.getPort(vPortId).macAddress();
+            Host host = hostService.getHost(HostId.hostId(macAddress));
+            selector.matchInPort(host.location().port());
         }
 
-        for (TpPort inPort : srcPortRange) {
-            selector.matchUdpSrc(inPort);
-        }
-        for (TpPort outPort : dstPortRange) {
-            selector.matchUdpDst(outPort);
+        // Take the port information from five tuple only when the protocol is TCP.
+        if (fiveTuple != null && fiveTuple.protocol() == IPv4.PROTOCOL_TCP) {
+            selector.matchTcpSrc(TpPort.tpPort((int) fiveTuple.portSrc().toLong()));
+            selector.matchTcpDst(TpPort.tpPort((int) fiveTuple.portDst().toLong()));
+        } else {
+            // For udp packets take the port information from flow classifier
+            List<TpPort> srcPortRange = new LinkedList<>();
+            List<TpPort> dstPortRange = new LinkedList<>();
+            if ((flowClassifier.minSrcPortRange() != 0) && flowClassifier.maxSrcPortRange() != 0
+                    && flowClassifier.minDstPortRange() != 0 && flowClassifier.maxDstPortRange() != 0) {
+
+                for (int port = flowClassifier.minSrcPortRange(); port <= flowClassifier.maxSrcPortRange(); port++) {
+                    srcPortRange.add(TpPort.tpPort(port));
+                }
+                for (int port = flowClassifier.minDstPortRange(); port <= flowClassifier.maxDstPortRange(); port++) {
+                    dstPortRange.add(TpPort.tpPort(port));
+                }
+            }
+
+            for (TpPort inPort : srcPortRange) {
+                selector.matchUdpSrc(inPort);
+            }
+            for (TpPort outPort : dstPortRange) {
+                selector.matchUdpDst(outPort);
+            }
         }
         return selector;
     }
@@ -260,26 +332,23 @@
      * Pack traffic treatment.
      *
      * @param deviceId device id
-     * @param srcMacAddress source mac-address
      * @param nshDstPort vxlan tunnel port for nsh header
-     * @param deviceIdfromFc device id if virtual ports are set in flow classifier.
-     * @param deviceIdfromPp device id if port pair is used to fetch device id.
      * @param nshSpi nsh spi
      * @param flowClassifier flow-classifier
      * @return traffic treatment
      */
-    public TrafficTreatment.Builder packTrafficTreatment(DeviceId deviceId, MacAddress srcMacAddress,
-                                               TpPort nshDstPort, DeviceId deviceIdfromFc, DeviceId deviceIdfromPp,
-                                               NshServicePathId nshSpi, FlowClassifier flowClassifier) {
+    public TrafficTreatment.Builder packTrafficTreatment(DeviceId deviceId, PortNumber port,
+                                                         TpPort nshDstPort, NshServicePathId nshSpi,
+                                                         FlowClassifier flowClassifier, boolean isSameOvs) {
+
         TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
 
-        Host host = hostService.getHost(HostId.hostId(srcMacAddress));
-        PortNumber port = host.location().port();
-        if (deviceIdfromPp != null) {
+        if (isSameOvs) {
             treatmentBuilder.setOutput(port);
-        } else if (deviceIdfromFc != null) {
-            treatmentBuilder.setVlanId((VlanId.vlanId(Short.parseShort((vtnRscService.getL3vni(flowClassifier
-                    .tenantId()).toString())))));
+        } else {
+            treatmentBuilder.setVlanId((VlanId.vlanId(Short.parseShort((vtnRscService
+                    .getL3vni(flowClassifier.tenantId()).toString())))));
+            treatmentBuilder.setUdpDst(nshDstPort);
         }
 
         // Set NSH
@@ -290,7 +359,6 @@
 
         treatmentBuilder.extension(nspIdTreatment, deviceId);
         treatmentBuilder.extension(nsiIdTreatment, deviceId);
-        treatmentBuilder.setUdpDst(nshDstPort);
 
         try {
             nspIdTreatment.setPropertyValue("nshSpi", nshSpi);
@@ -298,10 +366,11 @@
             log.error("Failed to get extension instruction to set Nsh Spi Id {}", deviceId);
         }
         try {
-            nsiIdTreatment.setPropertyValue("nshSi", NSH_SI_ID);
+            nsiIdTreatment.setPropertyValue("nshSi", NshServiceIndex.of(NSH_SI_ID));
         } catch (Exception e) {
             log.error("Failed to get extension instruction to set Nsh Si Id {}", deviceId);
         }
+
         return treatmentBuilder;
     }
 
@@ -313,11 +382,13 @@
      * @param deviceId device id
      * @param type operation type
      */
-    public void sendServiceFunctionForwarder(TrafficSelector.Builder selector, TrafficTreatment.Builder treatment,
-            DeviceId deviceId, Objective.Operation type) {
+    public void sendServiceFunctionClassifier(TrafficSelector.Builder selector, TrafficTreatment.Builder treatment,
+                                              DeviceId deviceId, Objective.Operation type) {
+        log.info("Sending flow to service function classifier. Selector {}, Treatment {}",
+                 selector.toString(), treatment.toString());
         ForwardingObjective.Builder objective = DefaultForwardingObjective.builder().withTreatment(treatment.build())
                 .withSelector(selector.build()).fromApp(appId).makePermanent().withFlag(Flag.VERSATILE)
-                .withPriority(L3FWD_PRIORITY);
+                .withPriority(FLOW_CLASSIFIER_PRIORITY);
 
         if (type.equals(Objective.Operation.ADD)) {
             log.debug("flowClassifierRules-->ADD");
diff --git a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/installer/impl/FlowClassifierInstallerImplTest.java b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/installer/impl/FlowClassifierInstallerImplTest.java
new file mode 100644
index 0000000..86b3e50
--- /dev/null
+++ b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/installer/impl/FlowClassifierInstallerImplTest.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright 2016 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.installer.impl;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.NshServicePathId;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.driver.DriverService;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.host.HostServiceAdapter;
+import org.onosproject.sfc.util.FlowClassifierAdapter;
+import org.onosproject.sfc.util.FlowObjectiveAdapter;
+import org.onosproject.sfc.util.MockDriverHandler;
+import org.onosproject.sfc.util.PortPairAdapter;
+import org.onosproject.sfc.util.PortPairGroupAdapter;
+import org.onosproject.sfc.util.VirtualPortAdapter;
+import org.onosproject.sfc.util.VtnRscAdapter;
+import org.onosproject.vtnrsc.AllowedAddressPair;
+import org.onosproject.vtnrsc.BindingHostId;
+import org.onosproject.vtnrsc.DefaultFlowClassifier;
+import org.onosproject.vtnrsc.DefaultPortChain;
+import org.onosproject.vtnrsc.DefaultPortPair;
+import org.onosproject.vtnrsc.DefaultPortPairGroup;
+import org.onosproject.vtnrsc.DefaultVirtualPort;
+import org.onosproject.vtnrsc.FixedIp;
+import org.onosproject.vtnrsc.FlowClassifier;
+import org.onosproject.vtnrsc.FlowClassifierId;
+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.SecurityGroup;
+import org.onosproject.vtnrsc.SubnetId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.VirtualPort;
+import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService;
+import org.onosproject.vtnrsc.portpair.PortPairService;
+import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
+import org.onosproject.vtnrsc.service.VtnRscService;
+import org.onosproject.vtnrsc.virtualport.VirtualPortService;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
+public class FlowClassifierInstallerImplTest {
+
+    FlowObjectiveService flowObjectiveService = new FlowObjectiveAdapter();
+    DeviceService deviceService = new DeviceServiceAdapter();
+    HostService hostService = new HostServiceAdapter();
+    VirtualPortService virtualPortService = new VirtualPortAdapter();
+    VtnRscService vtnRscService = new VtnRscAdapter();
+    PortPairService portPairService = new PortPairAdapter();
+    PortPairGroupService portPairGroupService = new PortPairGroupAdapter();
+    FlowClassifierService flowClassifierService = new FlowClassifierAdapter();
+
+    final DriverService driverService = createMock(DriverService.class);
+
+    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> portPairGroups = new LinkedList<PortPairGroupId>();
+    final List<FlowClassifierId> flowClassifiers = new LinkedList<FlowClassifierId>();
+    PortPairGroupId portPairGroupId1 = PortPairGroupId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae");
+    PortPairGroupId portPairGroupId2 = PortPairGroupId.of("73343531-fc23-aeb6-f44b-56dc5e2fb3af");
+
+    PortPairId portPairId1 = PortPairId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae");
+    PortPairId portPairId2 = PortPairId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae");
+
+    FlowClassifierId flowClassifierId1 = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae");
+    FlowClassifierId flowClassifierId2 = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3af");
+
+    final String ppName = "PortPair";
+    final String ppDescription = "PortPair";
+    final String ingress = "d3333333-24fc-4fae-af4b-321c5e2eb3d1";
+    final String egress = "a4444444-4a56-2a6e-cd3a-9dee4e2ec345";
+
+
+    final String ppgName = "PortPairGroup";
+    final String ppgDescription = "PortPairGroup";
+    final List<PortPairId> portPairList = new LinkedList<PortPairId>();
+
+    VirtualPortId id1 = VirtualPortId.portId(ingress);
+    VirtualPortId id2 = VirtualPortId.portId("3414");
+
+    DeviceId deviceId = DeviceId.deviceId("of:000000000000001");
+
+    final DriverHandler driverHandler = new MockDriverHandler();
+
+    private PortPair createPortPair(PortPairId  ppId) {
+        DefaultPortPair.Builder portPairBuilder = new DefaultPortPair.Builder();
+        PortPair portPair = portPairBuilder.setId(ppId).setName(ppName).setTenantId(tenantId)
+                .setDescription(ppDescription).setIngress(ingress).setEgress(egress).build();
+        return portPair;
+    }
+
+    private PortPairGroup createPortPairGroup(PortPairGroupId ppgId) {
+
+        portPairList.clear();
+        // Create same two port-pair-group objects.
+        portPairList.add(portPairId1);
+        portPairList.add(portPairId2);
+
+        DefaultPortPairGroup.Builder portPairGroupBuilder = new DefaultPortPairGroup.Builder();
+        PortPairGroup portPairGroup = portPairGroupBuilder.setId(ppgId).setTenantId(tenantId)
+                .setName(ppgName).setDescription(ppgDescription).setPortPairs(portPairList).build();
+
+        return portPairGroup;
+
+    }
+
+    private PortChain createPortChain() {
+
+        portPairGroups.clear();
+        flowClassifiers.clear();
+        // create list of Port Pair Groups.
+
+        portPairGroups.add(portPairGroupId1);
+        portPairGroups.add(portPairGroupId2);
+        // create list of Flow classifiers.
+        flowClassifiers.add(flowClassifierId1);
+        flowClassifiers.add(flowClassifierId2);
+
+        DefaultPortChain.Builder portChainBuilder = new DefaultPortChain.Builder();
+        final PortChain portChain = portChainBuilder.setId(portChainId).setTenantId(tenantId).setName(name)
+                .setDescription(description).setPortPairGroups(portPairGroups).setFlowClassifiers(flowClassifiers)
+                .build();
+
+        return portChain;
+    }
+
+    private FlowClassifier createFlowClassifier(FlowClassifierId id) {
+        final String name = "FlowClassifier1";
+        final String description = "FlowClassifier1";
+        final String ethType = "IPv4";
+        final String protocol = "tcp";
+        final int minSrcPortRange = 5;
+        final int maxSrcPortRange = 10;
+        final int minDstPortRange = 5;
+        final int maxDstPortRange = 10;
+        final TenantId tenantId = TenantId.tenantId("1");
+        final IpPrefix srcIpPrefix = IpPrefix.valueOf("0.0.0.0/0");
+        final IpPrefix dstIpPrefix = IpPrefix.valueOf("10.10.10.10/0");
+        final VirtualPortId virtualSrcPort = id1;
+        final VirtualPortId virtualDstPort = id2;
+
+        DefaultFlowClassifier.Builder flowClassifierBuilder = new DefaultFlowClassifier.Builder();
+        final FlowClassifier flowClassifier = flowClassifierBuilder.setFlowClassifierId(id)
+                .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();
+        return flowClassifier;
+    }
+
+    private VirtualPort createVirtualPort() {
+        Set<FixedIp> fixedIps;
+        Map<String, String> propertyMap;
+        Set<AllowedAddressPair> allowedAddressPairs;
+        Set<SecurityGroup> securityGroups = Sets.newHashSet();
+
+        String macAddressStr = "fa:12:3e:56:ee:a2";
+        String ipAddress = "10.1.1.1";
+        String tenantNetworkId = "1234567";
+        String subnet = "1212";
+        String hostIdStr = "fa:e2:3e:56:ee:a2";
+        String deviceOwner = "james";
+        propertyMap = Maps.newHashMap();
+        propertyMap.putIfAbsent("deviceOwner", deviceOwner);
+
+        TenantNetworkId networkId = TenantNetworkId.networkId(tenantNetworkId);
+        MacAddress macAddress = MacAddress.valueOf(macAddressStr);
+        BindingHostId bindingHostId = BindingHostId.bindingHostId(hostIdStr);
+        FixedIp fixedIp = FixedIp.fixedIp(SubnetId.subnetId(subnet),
+                                          IpAddress.valueOf(ipAddress));
+        fixedIps = Sets.newHashSet();
+        fixedIps.add(fixedIp);
+
+        allowedAddressPairs = Sets.newHashSet();
+        AllowedAddressPair allowedAddressPair = AllowedAddressPair
+                .allowedAddressPair(IpAddress.valueOf(ipAddress),
+                                    MacAddress.valueOf(macAddressStr));
+        allowedAddressPairs.add(allowedAddressPair);
+
+        VirtualPort d1 = new DefaultVirtualPort(id1, networkId, true,
+                                                propertyMap,
+                                                VirtualPort.State.ACTIVE,
+                                                macAddress, tenantId, deviceId,
+                                                fixedIps, bindingHostId,
+                                                allowedAddressPairs,
+                                                securityGroups);
+        return d1;
+    }
+
+    @Test
+    public void testInstallFlowClassifier() {
+
+        ApplicationId appId = new DefaultApplicationId(1, "test");
+        FlowClassifierInstallerImpl flowClassifierInstaller = new FlowClassifierInstallerImpl();
+        flowClassifierInstaller.virtualPortService = virtualPortService;
+        flowClassifierInstaller.vtnRscService = vtnRscService;
+        flowClassifierInstaller.portPairService = portPairService;
+        flowClassifierInstaller.portPairGroupService = portPairGroupService;
+        flowClassifierInstaller.flowClassifierService = flowClassifierService;
+        flowClassifierInstaller.driverService = driverService;
+        flowClassifierInstaller.deviceService = deviceService;
+        flowClassifierInstaller.hostService = hostService;
+        flowClassifierInstaller.flowObjectiveService = flowObjectiveService;
+        flowClassifierInstaller.appId = appId;
+
+        final PortChain portChain = createPortChain();
+        NshServicePathId nshSpiId = NshServicePathId.of(10);
+
+        portPairGroupService.createPortPairGroup(createPortPairGroup(portPairGroupId1));
+        portPairGroupService.createPortPairGroup(createPortPairGroup(portPairGroupId2));
+        portPairService.createPortPair(createPortPair(portPairId1));
+        portPairService.createPortPair(createPortPair(portPairId2));
+        FlowClassifier fc1 = createFlowClassifier(flowClassifierId1);
+        FlowClassifier fc2 = createFlowClassifier(flowClassifierId2);
+        flowClassifierService.createFlowClassifier(fc1);
+        flowClassifierService.createFlowClassifier(fc2);
+
+        List<VirtualPort> virtualPortList = Lists.newArrayList();
+        virtualPortList.add(createVirtualPort());
+        virtualPortService.createPorts(virtualPortList);
+
+        expect(driverService.createHandler(deviceId)).andReturn(driverHandler).anyTimes();
+        replay(driverService);
+
+        ConnectPoint connectPoint = flowClassifierInstaller.installFlowClassifier(portChain, nshSpiId);
+
+        assertThat(connectPoint, is(HostLocation.NONE));
+    }
+}
\ No newline at end of file
diff --git a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowClassifierManagerTestImpl.java b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowClassifierAdapter.java
similarity index 96%
rename from apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowClassifierManagerTestImpl.java
rename to apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowClassifierAdapter.java
index fe5babb..305bd03 100644
--- a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowClassifierManagerTestImpl.java
+++ b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowClassifierAdapter.java
@@ -28,7 +28,7 @@
 /**
  * Provides implementation of the Flow Classifier Service.
  */
-public class FlowClassifierManagerTestImpl implements FlowClassifierService {
+public class FlowClassifierAdapter implements FlowClassifierService {
 
     private final ConcurrentMap<FlowClassifierId, FlowClassifier> flowClassifierStore = new ConcurrentHashMap<>();
 
diff --git a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowObjectiveServiceTestImpl.java b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowObjectiveAdapter.java
similarity index 83%
rename from apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowObjectiveServiceTestImpl.java
rename to apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowObjectiveAdapter.java
index 9da9ee9..11f3667 100644
--- a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowObjectiveServiceTestImpl.java
+++ b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowObjectiveAdapter.java
@@ -16,16 +16,17 @@
 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.FlowObjectiveService;
 import org.onosproject.net.flowobjective.ForwardingObjective;
 import org.onosproject.net.flowobjective.NextObjective;
 
 /**
  * Testing version of implementation on FlowObjectiveService.
  */
-public class FlowObjectiveServiceTestImpl implements FlowObjectiveService {
+public class FlowObjectiveAdapter implements FlowObjectiveService {
 
+    private ForwardingObjective forwardingObjective;
     @Override
     public void filter(DeviceId deviceId, FilteringObjective filteringObjective) {
 
@@ -33,7 +34,7 @@
 
     @Override
     public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
-
+        this.forwardingObjective = forwardingObjective;
     }
 
     @Override
@@ -50,4 +51,8 @@
     public void initPolicy(String policy) {
 
     }
+
+    public ForwardingObjective forwardingObjective() {
+        return forwardingObjective;
+    }
 }
diff --git a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/MockDriverHandler.java b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/MockDriverHandler.java
new file mode 100644
index 0000000..08aea73
--- /dev/null
+++ b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/MockDriverHandler.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2016 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.behaviour.ExtensionSelectorResolver;
+import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
+import org.onosproject.net.driver.Behaviour;
+import org.onosproject.net.driver.Driver;
+import org.onosproject.net.driver.DriverData;
+import org.onosproject.net.driver.DriverHandler;
+
+public class MockDriverHandler implements DriverHandler {
+
+    @Override
+    public Driver driver() {
+        return null;
+    }
+
+    @Override
+    public DriverData data() {
+        return null;
+    }
+
+    @Override
+    public <T extends Behaviour> T behaviour(Class<T> behaviourClass) {
+        if (behaviourClass == ExtensionSelectorResolver.class) {
+            return (T) new MockExtensionSelectorResolver();
+        } else if (behaviourClass == ExtensionTreatmentResolver.class) {
+            return (T) new MockExtensionTreatmentResolver();
+        }
+        return null;
+    }
+
+    @Override
+    public <T> T get(Class<T> serviceClass) {
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/MockExtensionSelector.java b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/MockExtensionSelector.java
new file mode 100644
index 0000000..2dde927
--- /dev/null
+++ b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/MockExtensionSelector.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2016 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.List;
+
+import org.onosproject.net.flow.criteria.ExtensionSelector;
+import org.onosproject.net.flow.criteria.ExtensionSelectorType;
+import org.onosproject.net.flow.instructions.ExtensionPropertyException;
+
+public class MockExtensionSelector implements ExtensionSelector {
+
+    @Override
+    public <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException {
+    }
+
+    @Override
+    public <T> T getPropertyValue(String key) throws ExtensionPropertyException {
+        return null;
+    }
+
+    @Override
+    public List<String> getProperties() {
+        return null;
+    }
+
+    @Override
+    public byte[] serialize() {
+        return null;
+    }
+
+    @Override
+    public void deserialize(byte[] data) {
+    }
+
+    @Override
+    public ExtensionSelectorType type() {
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/MockExtensionSelectorResolver.java b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/MockExtensionSelectorResolver.java
new file mode 100644
index 0000000..7583708
--- /dev/null
+++ b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/MockExtensionSelectorResolver.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2016 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.behaviour.ExtensionSelectorResolver;
+import org.onosproject.net.driver.DriverData;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.flow.criteria.ExtensionSelector;
+import org.onosproject.net.flow.criteria.ExtensionSelectorType;
+
+public class MockExtensionSelectorResolver implements ExtensionSelectorResolver {
+
+    @Override
+    public DriverHandler handler() {
+        return null;
+    }
+
+    @Override
+    public void setHandler(DriverHandler handler) {
+    }
+
+    @Override
+    public DriverData data() {
+        return null;
+    }
+
+    @Override
+    public void setData(DriverData data) {
+    }
+
+    @Override
+    public ExtensionSelector getExtensionSelector(ExtensionSelectorType type) {
+        return new MockExtensionSelector();
+    }
+}
\ No newline at end of file
diff --git a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/MockExtensionTreatment.java b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/MockExtensionTreatment.java
new file mode 100644
index 0000000..f28d5dd
--- /dev/null
+++ b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/MockExtensionTreatment.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2016 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.List;
+
+import org.onosproject.net.flow.instructions.ExtensionPropertyException;
+import org.onosproject.net.flow.instructions.ExtensionTreatment;
+import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
+
+public class MockExtensionTreatment implements ExtensionTreatment {
+
+    @Override
+    public <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException {
+    }
+
+    @Override
+    public <T> T getPropertyValue(String key) throws ExtensionPropertyException {
+        return null;
+    }
+
+    @Override
+    public List<String> getProperties() {
+        return null;
+    }
+
+    @Override
+    public byte[] serialize() {
+        return null;
+    }
+
+    @Override
+    public void deserialize(byte[] data) {
+    }
+
+    @Override
+    public ExtensionTreatmentType type() {
+        return null;
+    }
+
+}
\ No newline at end of file
diff --git a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/MockExtensionTreatmentResolver.java b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/MockExtensionTreatmentResolver.java
new file mode 100644
index 0000000..b9a0d0d
--- /dev/null
+++ b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/MockExtensionTreatmentResolver.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2016 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.behaviour.ExtensionTreatmentResolver;
+import org.onosproject.net.driver.DriverData;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.flow.instructions.ExtensionTreatment;
+import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
+
+public class MockExtensionTreatmentResolver implements ExtensionTreatmentResolver {
+
+    @Override
+    public DriverHandler handler() {
+        return null;
+    }
+
+    @Override
+    public void setHandler(DriverHandler handler) {
+    }
+
+    @Override
+    public DriverData data() {
+        return null;
+    }
+
+    @Override
+    public void setData(DriverData data) {
+    }
+
+    @Override
+    public ExtensionTreatment getExtensionInstruction(ExtensionTreatmentType type) {
+        return new MockExtensionTreatment();
+    }
+
+}
\ No newline at end of file
diff --git a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortChainManagerTestImpl.java b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortChainAdapter.java
similarity index 98%
rename from apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortChainManagerTestImpl.java
rename to apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortChainAdapter.java
index 4a3ba03..c76b2e6 100644
--- a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortChainManagerTestImpl.java
+++ b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortChainAdapter.java
@@ -29,7 +29,7 @@
 /**
  * Provides implementation of the portChainService.
  */
-public class PortChainManagerTestImpl
+public class PortChainAdapter
             extends AbstractListenerManager<PortChainEvent, PortChainListener>
             implements PortChainService {
 
diff --git a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairManagerTestImpl.java b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairAdapter.java
similarity index 97%
rename from apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairManagerTestImpl.java
rename to apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairAdapter.java
index aff5882..1a526b4 100644
--- a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairManagerTestImpl.java
+++ b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairAdapter.java
@@ -27,7 +27,7 @@
 /**
  * Provides implementation of the portPairService.
  */
-public class PortPairManagerTestImpl implements PortPairService {
+public class PortPairAdapter implements PortPairService {
 
     private ConcurrentMap<PortPairId, PortPair> portPairStore = new ConcurrentHashMap<>();
 
diff --git a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairGroupManagerTestImpl.java b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairGroupAdapter.java
similarity index 96%
rename from apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairGroupManagerTestImpl.java
rename to apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairGroupAdapter.java
index ba31cd6..6e3de44 100644
--- a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairGroupManagerTestImpl.java
+++ b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairGroupAdapter.java
@@ -27,7 +27,7 @@
 /**
  * Provides implementation of the portPairGroupService.
  */
-public class PortPairGroupManagerTestImpl implements PortPairGroupService {
+public class PortPairGroupAdapter implements PortPairGroupService {
 
     private ConcurrentMap<PortPairGroupId, PortPairGroup> portPairGroupStore = new ConcurrentHashMap<>();
 
diff --git a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortManagerTestImpl.java b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortAdapter.java
similarity index 96%
rename from apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortManagerTestImpl.java
rename to apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortAdapter.java
index de056a7..6570c97 100644
--- a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortManagerTestImpl.java
+++ b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortAdapter.java
@@ -31,7 +31,7 @@
 /**
  * Provides implementation of the VirtualPort APIs.
  */
-public class VirtualPortManagerTestImpl implements VirtualPortService {
+public class VirtualPortAdapter implements VirtualPortService {
 
     protected ConcurrentMap<VirtualPortId, VirtualPort> vPortStore = new ConcurrentHashMap<>();
 
diff --git a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VtnRscManagerTestImpl.java b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VtnRscAdapter.java
similarity index 93%
rename from apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VtnRscManagerTestImpl.java
rename to apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VtnRscAdapter.java
index 4c761e9..1179dc0 100644
--- a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VtnRscManagerTestImpl.java
+++ b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VtnRscAdapter.java
@@ -31,7 +31,7 @@
 /**
  * Provides implementation of the VtnRsc service.
  */
-public class VtnRscManagerTestImpl implements VtnRscService {
+public class VtnRscAdapter implements VtnRscService {
     @Override
     public void addListener(VtnRscListener listener) {
     }
@@ -62,13 +62,12 @@
 
     @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");
+        return DeviceId.deviceId("of:000000000000001");
     }
 
     @Override
diff --git a/core/api/src/test/java/org/onosproject/net/host/HostServiceAdapter.java b/core/api/src/test/java/org/onosproject/net/host/HostServiceAdapter.java
index 0fad54a..a1aa93b 100644
--- a/core/api/src/test/java/org/onosproject/net/host/HostServiceAdapter.java
+++ b/core/api/src/test/java/org/onosproject/net/host/HostServiceAdapter.java
@@ -15,15 +15,21 @@
  */
 package org.onosproject.net.host;
 
+import java.util.Set;
+
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
+import org.onosproject.net.Annotations;
 import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultHost;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Host;
 import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.provider.ProviderId;
 
-import java.util.Set;
+import com.google.common.collect.Sets;
 
 /**
  * Test adapter for host service.
@@ -41,7 +47,13 @@
 
     @Override
     public Host getHost(HostId hostId) {
-        return null;
+        ProviderId providerId = ProviderId.NONE;
+        MacAddress mac =  MacAddress.valueOf("fa:12:3e:56:ee:a2");
+        VlanId vlan = VlanId.NONE;
+        HostLocation location =  HostLocation.NONE;
+        Set<IpAddress> ips = Sets.newHashSet();
+        Annotations annotations = null;
+        return new DefaultHost(providerId, hostId, mac, vlan, location, ips, annotations);
     }
 
     @Override