OF-overlay PolicyEnforcer tests, refactoring 05/41005/8
authorKonstantin Blagov <kblagov@cisco.com>
Tue, 28 Jun 2016 14:43:49 +0000 (16:43 +0200)
committerKonstantin Blagov <kblagov@cisco.com>
Thu, 7 Jul 2016 15:41:43 +0000 (17:41 +0200)
Change-Id: I59d42d2da28b4bfba00bdbced052dfb775fbecc2
Signed-off-by: Konstantin Blagov <kblagov@cisco.com>
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/policyenforcer/PolicyEnforcer.java
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/ChainAction.java
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/MapperUtilsTest.java
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/policyenforcer/PolicyEnforcerTest.java

index 11a872effcad5eb6fff1733ee4f848094b9ab3f7..6712cd455e0450eb48b9ed50f32707ce745f3de4 100755 (executable)
@@ -56,6 +56,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.ta
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTable;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
@@ -144,9 +145,9 @@ import com.google.common.collect.Table.Cell;
 public class PolicyEnforcer extends FlowTable {
 
     private static final Logger LOG = LoggerFactory.getLogger(PolicyEnforcer.class);
-    public static short TABLE_ID;
-    private static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction gotoEgressNatInstruction;
-    private static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction gotoExternalInstruction;
+    private static short TABLE_ID;
+    private static Instruction gotoEgressNatInstruction;
+    private static Instruction gotoExternalInstruction;
 
     public PolicyEnforcer(OfContext ctx, short tableId) {
         super(ctx);
@@ -598,8 +599,14 @@ public class PolicyEnforcer extends FlowTable {
                 if ((!(actionRefList.indexOf(actionRef) == (actionRefList.size() - 1)
                         && action.equals(SubjectFeatures.getAction(AllowActionDefinition.DEFINITION.getId()))))
                         && actionBuilderList != null) {
-                    actionBuilderList = action.updateAction(actionBuilderList, params, actionRef.getOrder(),
-                            netElements, ofWriter, ctx, direction);
+                    if (ctx.getDataBroker() != null) {
+                        actionBuilderList =
+                            action.updateAction(actionBuilderList, params, actionRef.getOrder(), netElements, ofWriter, ctx, direction);
+                    } else {
+                        LOG.error("DataBroket is null. Cannot update action {}",
+                            action.getActionDef().getName().getValue());
+                        return null;
+                    }
                 }
             }
         }
index f5bf7538a22746298055452123a5e5199eed239b..b241ee6eb04140a4ebab30c0b244247cf8e88a70 100755 (executable)
@@ -286,9 +286,11 @@ public class ChainAction extends Action {
 
     public static ServiceFunctionPath getSfcPath(SfcName chainName) {
         ServiceFunctionPaths paths = SfcProviderServicePathAPI.readAllServiceFunctionPaths();
-        for (ServiceFunctionPath path : paths.getServiceFunctionPath()) {
-            if (path.getServiceChainName().equals(chainName)) {
-                return path;
+        if (paths != null) {
+            for (ServiceFunctionPath path : paths.getServiceFunctionPath()) {
+                if (path.getServiceChainName().equals(chainName)) {
+                    return path;
+                }
             }
         }
         return null;
index fefcecd65aa00ec0952c816d2c5ca1548500e3c2..280f8434dc0e225c8d4cf1f5536b8464f76cace6 100644 (file)
@@ -13,6 +13,7 @@ import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTable;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils;\r
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager;\r
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.AllowAction;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.ChainAction;\r
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.Classifier;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;\r
@@ -50,6 +51,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ForwardingContextBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Policy;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.PolicyBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomain;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomainBuilder;\r
@@ -65,6 +67,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.SubjectFeatureInstancesBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelectorBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderNamedSelectorBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstance;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstanceBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstanceBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;\r
@@ -106,6 +109,7 @@ public abstract class MapperUtilsTest {
     protected static final ContextId CONTEXT_ID = new L3ContextId("ctxId");\r
     // Often used strings\r
     protected static final String ALLOW = "allow";\r
+    protected static final String CHAIN = "chain";\r
     protected static final String L2 = "L2";\r
     protected static final String OPENFLOW = "openflow:";\r
     protected static final String DROP_ALL = "dropAll";\r
@@ -121,35 +125,33 @@ public abstract class MapperUtilsTest {
     protected PolicyInfo policyInfo;\r
     protected FlowTable table;\r
 \r
-    protected FlowBuilder buildFlow(FlowId flowId, short tableId, Integer priority, Match match, Instructions instructions) {\r
-        FlowBuilder flowBuilder = FlowUtils.base(tableId);\r
-        flowBuilder.setId(flowId)\r
-                .setPriority(priority)\r
-                .setMatch(match)\r
-                .setInstructions(instructions);\r
-        return flowBuilder;\r
+    protected FlowBuilder buildFlow(FlowId flowId, short tableId, Integer priority, Match match,\r
+            Instructions instructions) {\r
+        return FlowUtils.base(tableId)\r
+            .setId(flowId)\r
+            .setPriority(priority)\r
+            .setMatch(match)\r
+            .setInstructions(instructions);\r
     }\r
 \r
     protected EndpointL3Builder buildL3Endpoint(Ipv4Address natIp, Ipv4Address ip, MacAddress mac, String l2bd) {\r
         Preconditions.checkNotNull(natIp);\r
         Preconditions.checkNotNull(ip);\r
         Preconditions.checkNotNull(mac);\r
-        EndpointL3Builder endpointL3Builder = new EndpointL3Builder();\r
-        NatAddressBuilder natAddressBuilder = new NatAddressBuilder();\r
-        natAddressBuilder.setNatAddress(new IpAddress(new Ipv4Address(natIp)));\r
-        endpointL3Builder.addAugmentation(NatAddress.class, natAddressBuilder.build());\r
-        endpointL3Builder.setIpAddress(new IpAddress(ip));\r
-        endpointL3Builder.setMacAddress(new MacAddress(mac));\r
+\r
+        NatAddress natAddress = new NatAddressBuilder().setNatAddress(new IpAddress(new Ipv4Address(natIp))).build();\r
+\r
+        EndpointL3Builder endpointL3Builder = new EndpointL3Builder().addAugmentation(NatAddress.class, natAddress)\r
+            .setIpAddress(new IpAddress(ip))\r
+            .setMacAddress(new MacAddress(mac));\r
         if (l2bd != null) {\r
             endpointL3Builder.setL2Context(new L2BridgeDomainId(l2bd));\r
         }\r
-        if(ip.equals(IPV4_0)) {\r
+        if (ip.equals(IPV4_0)) {\r
             endpointL3Builder.setNetworkContainment(SUBNET_0);\r
-        }\r
-        else if(ip.equals(IPV4_1)) {\r
+        } else if (ip.equals(IPV4_1)) {\r
             endpointL3Builder.setNetworkContainment(SUBNET_1);\r
-        }\r
-        else if(ip.equals(IPV4_2)) {\r
+        } else if (ip.equals(IPV4_2)) {\r
             endpointL3Builder.setNetworkContainment(SUBNET_2);\r
         }\r
         return endpointL3Builder;\r
@@ -159,13 +161,12 @@ public abstract class MapperUtilsTest {
         Preconditions.checkNotNull(natIp);\r
         Preconditions.checkNotNull(ip);\r
         Preconditions.checkNotNull(mac);\r
-        EndpointL3Builder endpointL3Builder = new EndpointL3Builder();\r
-        NatAddressBuilder natAddressBuilder = new NatAddressBuilder();\r
-        natAddressBuilder.setNatAddress(new IpAddress(new Ipv6Address(natIp)));\r
-        endpointL3Builder.addAugmentation(NatAddress.class, natAddressBuilder.build());\r
-        endpointL3Builder.setIpAddress(new IpAddress(ip));\r
 \r
-        endpointL3Builder.setMacAddress(new MacAddress(mac));\r
+        NatAddress natAddress = new NatAddressBuilder().setNatAddress(new IpAddress(new Ipv6Address(natIp))).build();\r
+\r
+        EndpointL3Builder endpointL3Builder = new EndpointL3Builder().addAugmentation(NatAddress.class, natAddress)\r
+            .setIpAddress(new IpAddress(ip))\r
+            .setMacAddress(new MacAddress(mac));\r
         if (l2bd != null) {\r
             endpointL3Builder.setL2Context(new L2BridgeDomainId(l2bd));\r
         }\r
@@ -173,186 +174,201 @@ public abstract class MapperUtilsTest {
     }\r
 \r
     public SegmentationBuilder buildSegmentation() {\r
-        SegmentationBuilder segmentationBuilder = new SegmentationBuilder();\r
-        segmentationBuilder.setSegmentationId(1);\r
-        return  segmentationBuilder;\r
+        return new SegmentationBuilder().setSegmentationId(1);\r
     }\r
 \r
     protected TenantBuilder buildTenant() {\r
-        TenantBuilder tenantBuilder = new TenantBuilder();\r
-        tenantBuilder.setId(TENANT_ID);\r
-        tenantBuilder.setForwardingContext(buildForwardingContext().build());\r
-        PolicyBuilder policyBuilder = new PolicyBuilder();\r
-        policyBuilder.setEndpointGroup(getEndpointGroups());\r
-        policyBuilder.setSubjectFeatureInstances(getSubjectFeatureInstances());\r
-        tenantBuilder.setPolicy(policyBuilder.build());\r
-        return tenantBuilder;\r
+        Policy policy = new PolicyBuilder().setEndpointGroup(getEndpointGroups())\r
+            .setSubjectFeatureInstances(getSubjectFeatureInstances())\r
+            .build();\r
+\r
+        return new TenantBuilder().setId(TENANT_ID)\r
+            .setForwardingContext(buildForwardingContext().build())\r
+            .setPolicy(policy);\r
+    }\r
+\r
+    protected TenantBuilder buildTenant(ActionInstance actionInstance) {\r
+        Policy policy = new PolicyBuilder().setEndpointGroup(getEndpointGroups())\r
+            .setSubjectFeatureInstances(getSubjectFeatureInstances(actionInstance))\r
+            .build();\r
+\r
+        return new TenantBuilder().setId(TENANT_ID)\r
+            .setForwardingContext(buildForwardingContext().build())\r
+            .setPolicy(policy);\r
     }\r
 \r
     protected IndexedTenant getTestIndexedTenant() {\r
         return new IndexedTenant(buildTenant().build());\r
     }\r
 \r
+    protected IndexedTenant getTestIndexedTenant(ActionInstance actionInstance) {\r
+        return new IndexedTenant(buildTenant(actionInstance).build());\r
+    }\r
+\r
     protected ForwardingContextBuilder buildForwardingContext() {\r
-        ForwardingContextBuilder forwardingContextBuilder = new ForwardingContextBuilder();\r
-        forwardingContextBuilder.setL2FloodDomain(getL2FloodDomainList(false));\r
-        forwardingContextBuilder.setL2BridgeDomain(getL2BridgeDomainList());\r
-        forwardingContextBuilder.setL3Context(getL3ContextList());\r
-        forwardingContextBuilder.setSubnet(getSubnetList());\r
-        return forwardingContextBuilder;\r
+        return new ForwardingContextBuilder().setL2FloodDomain(getL2FloodDomainList(false))\r
+            .setL2BridgeDomain(getL2BridgeDomainList())\r
+            .setL3Context(getL3ContextList())\r
+            .setSubnet(getSubnetList());\r
     }\r
 \r
     protected List<L3Context> getL3ContextList() {\r
-        List<L3Context> l3Contexts = new ArrayList<>();\r
-        L3ContextBuilder l3ContextBuilder = new L3ContextBuilder();\r
-        l3ContextBuilder.setId(L3C_ID);\r
-        l3Contexts.add(l3ContextBuilder.build());\r
-        return l3Contexts;\r
+        L3Context l3Context = new L3ContextBuilder().setId(L3C_ID).build();\r
+        return ImmutableList.of(l3Context);\r
     }\r
 \r
     protected List<L2BridgeDomain> getL2BridgeDomainList() {\r
-        List<L2BridgeDomain> l2BridgeDomains = new ArrayList<>();\r
-        L2BridgeDomainBuilder l2BridgeDomainBuilder = new L2BridgeDomainBuilder();\r
-        l2BridgeDomainBuilder.setId(L2BD_ID);\r
-        l2BridgeDomainBuilder.setParent(L3C_ID);\r
-        l2BridgeDomains.add(l2BridgeDomainBuilder.build());\r
-        return l2BridgeDomains;\r
+        L2BridgeDomain l2BridgeDomain = new L2BridgeDomainBuilder().setId(L2BD_ID).setParent(L3C_ID).build();\r
+        return ImmutableList.of(l2BridgeDomain);\r
     }\r
 \r
     protected List<L2FloodDomain> getL2FloodDomainList(boolean external) {\r
-        List<L2FloodDomain> l2FloodDomains = new ArrayList<>();\r
-        L2FloodDomainBuilder l2FloodDomainBuilder = new L2FloodDomainBuilder();\r
-        l2FloodDomainBuilder.setId(L2FD_ID);\r
+        L2FloodDomainBuilder l2FloodDomainBuilder = new L2FloodDomainBuilder().setId(L2FD_ID)\r
+            .setParent(new L2BridgeDomainId(L2BD_ID))\r
+            .addAugmentation(Segmentation.class, buildSegmentation().build());\r
         if (external) {\r
             l2FloodDomainBuilder.setId(L2_FD_ID_EXT);\r
         }\r
-        l2FloodDomainBuilder.setParent(new L2BridgeDomainId(L2BD_ID));\r
-        l2FloodDomainBuilder.addAugmentation(Segmentation.class, buildSegmentation().build());\r
-        l2FloodDomains.add(l2FloodDomainBuilder.build());\r
-        return l2FloodDomains;\r
+        return ImmutableList.of(l2FloodDomainBuilder.build());\r
     }\r
 \r
     protected List<L3Address> getL3AddressList(Ipv4Address l3IpAddress, L3ContextId l3ContextId) {\r
-        List<L3Address> l3Addresses = new ArrayList<>();\r
-        L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();\r
-        l3AddressBuilder.setIpAddress(new IpAddress(l3IpAddress));\r
-        l3AddressBuilder.setL3Context(new L3ContextId(l3ContextId));\r
-        l3Addresses.add(l3AddressBuilder.build());\r
-        return l3Addresses;\r
+        L3Address l3Address = new L3AddressBuilder().setIpAddress(new IpAddress(l3IpAddress))\r
+            .setL3Context(new L3ContextId(l3ContextId))\r
+            .build();\r
+        return ImmutableList.of(l3Address);\r
     }\r
 \r
     protected List<L3Address> getL3AddressList(Ipv6Address l3IpAddress) {\r
-        List<L3Address> l3Addresses = new ArrayList<>();\r
-        L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();\r
-        l3AddressBuilder.setIpAddress(new IpAddress(l3IpAddress));\r
-        l3Addresses.add(l3AddressBuilder.build());\r
-        return l3Addresses;\r
+        L3Address l3Address = new L3AddressBuilder().setIpAddress(new IpAddress(l3IpAddress)).build();\r
+        return ImmutableList.of(l3Address);\r
     }\r
 \r
     protected OfOverlayContextBuilder getOfOverlayContext(NodeConnectorId connector) {\r
-        OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();\r
-        ofOverlayContextBuilder.setNodeConnectorId(connector);\r
-        ofOverlayContextBuilder.setNodeId(NODE_ID);\r
-        return ofOverlayContextBuilder;\r
+        return new OfOverlayContextBuilder().setNodeConnectorId(connector).setNodeId(NODE_ID);\r
     }\r
 \r
     protected EndpointBuilder buildEndpoint(Ipv4Address l3IpAddress, MacAddress mac, NodeConnectorId connector) {\r
-        EndpointBuilder endpointBuilder = new EndpointBuilder();\r
-        endpointBuilder.setTenant(TENANT_ID);\r
-        endpointBuilder.setL3Address(getL3AddressList(l3IpAddress, L3C_ID));\r
-        endpointBuilder.setMacAddress(new MacAddress(mac));\r
-        endpointBuilder.setL2Context(new L2BridgeDomainId(L2BD_ID));\r
-        endpointBuilder.setEndpointGroup(ENDPOINT_GROUP_0);\r
-        endpointBuilder.addAugmentation(OfOverlayContext.class, getOfOverlayContext(connector).build());\r
-        if(l3IpAddress.equals(IPV4_0)) {\r
+        EndpointBuilder endpointBuilder = new EndpointBuilder().setTenant(TENANT_ID)\r
+            .setL3Address(getL3AddressList(l3IpAddress, L3C_ID))\r
+            .setMacAddress(new MacAddress(mac))\r
+            .setL2Context(new L2BridgeDomainId(L2BD_ID))\r
+            .setEndpointGroup(ENDPOINT_GROUP_0)\r
+            .addAugmentation(OfOverlayContext.class, getOfOverlayContext(connector).build());\r
+        if (l3IpAddress.equals(IPV4_0)) {\r
             endpointBuilder.setNetworkContainment(SUBNET_0);\r
-        }\r
-        else if(l3IpAddress.equals(IPV4_1)) {\r
+        } else if (l3IpAddress.equals(IPV4_1)) {\r
             endpointBuilder.setNetworkContainment(SUBNET_1);\r
-        }\r
-        else if(l3IpAddress.equals(IPV4_2)) {\r
+        } else if (l3IpAddress.equals(IPV4_2)) {\r
             endpointBuilder.setNetworkContainment(SUBNET_2);\r
         }\r
         return endpointBuilder;\r
     }\r
 \r
     protected EndpointBuilder buildEndpoint(Ipv6Address l3IpAddress, MacAddress mac, NodeConnectorId connector) {\r
-        EndpointBuilder endpointBuilder = new EndpointBuilder();\r
-        endpointBuilder.setTenant(TENANT_ID);\r
-        endpointBuilder.setL3Address(getL3AddressList(l3IpAddress));\r
-        endpointBuilder.setMacAddress(new MacAddress(mac));\r
-        endpointBuilder.setL2Context(new L2BridgeDomainId(L2BD_ID));\r
-        endpointBuilder.setEndpointGroup(ENDPOINT_GROUP_0);\r
-        endpointBuilder.addAugmentation(OfOverlayContext.class, getOfOverlayContext(connector).build());\r
-        endpointBuilder.setNetworkContainment(NET_DOMAIN_ID);\r
-        return endpointBuilder;\r
+        return new EndpointBuilder().setTenant(TENANT_ID)\r
+            .setL3Address(getL3AddressList(l3IpAddress))\r
+            .setMacAddress(new MacAddress(mac))\r
+            .setL2Context(new L2BridgeDomainId(L2BD_ID))\r
+            .setEndpointGroup(ENDPOINT_GROUP_0)\r
+            .setNetworkContainment(NET_DOMAIN_ID)\r
+            .addAugmentation(OfOverlayContext.class, getOfOverlayContext(connector).build());\r
     }\r
 \r
     public List<EndpointGroup> getEndpointGroups() {\r
         return ImmutableList.of(\r
                 new EndpointGroupBuilder().setId(ENDPOINT_GROUP_0)\r
-                        .setNetworkDomain(SUBNET_0)\r
-                        .setConsumerNamedSelector(ImmutableList.of(new ConsumerNamedSelectorBuilder()\r
-                                .setName(new SelectorName("cns1")).setContract(ImmutableList.of(CONTRACT_ID)).build()))\r
-                        .build(),\r
+                    .setNetworkDomain(SUBNET_0)\r
+                    .setConsumerNamedSelector(ImmutableList.of(new ConsumerNamedSelectorBuilder()\r
+                        .setName(new SelectorName("cns1")).setContract(ImmutableList.of(CONTRACT_ID)).build()))\r
+                    .build(),\r
                 new EndpointGroupBuilder().setId(ENDPOINT_GROUP_1)\r
-                        .setNetworkDomain(SUBNET_1)\r
-                        .setProviderNamedSelector(ImmutableList.of(new ProviderNamedSelectorBuilder()\r
-                                .setName(new SelectorName("pns1")).setContract(ImmutableList.of(CONTRACT_ID)).build()))\r
-                        .build());\r
+                    .setNetworkDomain(SUBNET_1)\r
+                    .setProviderNamedSelector(ImmutableList.of(new ProviderNamedSelectorBuilder()\r
+                        .setName(new SelectorName("pns1")).setContract(ImmutableList.of(CONTRACT_ID)).build()))\r
+                    .build());\r
     }\r
 \r
     protected SubjectFeatureInstances getSubjectFeatureInstances() {\r
         SubjectFeatureInstancesBuilder builder = new SubjectFeatureInstancesBuilder();\r
-        return builder.setClassifierInstance(ImmutableList.of(new ClassifierInstanceBuilder()\r
-                .setName(new ClassifierName("tcp_dst_80"))\r
-                .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())\r
-                .setParameterValue(ImmutableList.of(new ParameterValueBuilder().setName(new ParameterName("destport"))\r
-                        .setIntValue(80L)        // Endpoint\r
-\r
-                        .build(), new ParameterValueBuilder().setName(new ParameterName("proto"))\r
-                        .setIntValue(6L)\r
-                        .build()))\r
-                .build(), new ClassifierInstanceBuilder().setName(new ClassifierName(TCP_SRC))\r
-                .setClassifierDefinitionId(Classifier.L4_CL.getId())\r
-                .setParameterValue(ImmutableList.of(new ParameterValueBuilder().setName(new ParameterName("sourceport"))\r
-                        .setIntValue(80L)\r
-                        .build(), new ParameterValueBuilder().setName(new ParameterName("proto"))\r
-                        .setIntValue(6L)\r
-                        .build()))\r
-                .build(), new ClassifierInstanceBuilder().setName(new ClassifierName("ether_type"))\r
-                .setClassifierDefinitionId(Classifier.ETHER_TYPE_CL.getId())\r
-                .setParameterValue(ImmutableList.of(new ParameterValueBuilder()\r
-                        .setName(new ParameterName("ethertype"))\r
-                        .setIntValue(FlowUtils.IPv4)\r
-                        .build()))\r
+        return builder.setClassifierInstance(ImmutableList.of(\r
+                new ClassifierInstanceBuilder().setName(new ClassifierName("tcp_dst_80"))\r
+                    .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())\r
+                    .setParameterValue(ImmutableList.of(\r
+                            new ParameterValueBuilder().setName(new ParameterName("destport"))\r
+                                .setIntValue(80L) // Endpoint\r
+\r
+                                .build(),\r
+                            new ParameterValueBuilder().setName(new ParameterName("proto")).setIntValue(6L).build()))\r
+                    .build(),\r
+                new ClassifierInstanceBuilder().setName(new ClassifierName(TCP_SRC))\r
+                    .setClassifierDefinitionId(Classifier.L4_CL.getId())\r
+                    .setParameterValue(ImmutableList.of(\r
+                            new ParameterValueBuilder().setName(new ParameterName("sourceport"))\r
+                                .setIntValue(80L)\r
+                                .build(),\r
+                            new ParameterValueBuilder().setName(new ParameterName("proto")).setIntValue(6L).build()))\r
+                    .build(),\r
+                new ClassifierInstanceBuilder().setName(new ClassifierName("ether_type"))\r
+                    .setClassifierDefinitionId(Classifier.ETHER_TYPE_CL.getId())\r
+                    .setParameterValue(ImmutableList.of(new ParameterValueBuilder()\r
+                        .setName(new ParameterName("ethertype")).setIntValue(FlowUtils.IPv4).build()))\r
+                    .build()))\r
+            .setActionInstance(ImmutableList.of(new ActionInstanceBuilder().setName(new ActionName("allow"))\r
+                .setActionDefinitionId(new AllowAction().getId())\r
                 .build()))\r
-                .setActionInstance(ImmutableList.of(new ActionInstanceBuilder().setName(new ActionName("allow"))\r
-                        .setActionDefinitionId(new AllowAction().getId())\r
-                        .build()))\r
-                .build();\r
+            .build();\r
+    }\r
+\r
+    protected SubjectFeatureInstances getSubjectFeatureInstances(ActionInstance actionInstance) {\r
+        SubjectFeatureInstancesBuilder builder = new SubjectFeatureInstancesBuilder();\r
+        return builder.setClassifierInstance(ImmutableList.of(\r
+                new ClassifierInstanceBuilder().setName(new ClassifierName("tcp_dst_80"))\r
+                    .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())\r
+                    .setParameterValue(ImmutableList.of(\r
+                            new ParameterValueBuilder().setName(new ParameterName("destport"))\r
+                                .setIntValue(80L) // Endpoint\r
+\r
+                                .build(),\r
+                            new ParameterValueBuilder().setName(new ParameterName("proto")).setIntValue(6L).build()))\r
+                    .build(),\r
+                new ClassifierInstanceBuilder().setName(new ClassifierName(TCP_SRC))\r
+                    .setClassifierDefinitionId(Classifier.L4_CL.getId())\r
+                    .setParameterValue(ImmutableList.of(\r
+                            new ParameterValueBuilder().setName(new ParameterName("sourceport"))\r
+                                .setIntValue(80L)\r
+                                .build(),\r
+                            new ParameterValueBuilder().setName(new ParameterName("proto")).setIntValue(6L).build()))\r
+                    .build(),\r
+                new ClassifierInstanceBuilder().setName(new ClassifierName("ether_type"))\r
+                    .setClassifierDefinitionId(Classifier.ETHER_TYPE_CL.getId())\r
+                    .setParameterValue(ImmutableList.of(new ParameterValueBuilder()\r
+                        .setName(new ParameterName("ethertype")).setIntValue(FlowUtils.IPv4).build()))\r
+                    .build()))\r
+            .setActionInstance(ImmutableList.of(actionInstance))\r
+            .build();\r
     }\r
 \r
     protected List<Subnet> getSubnetList() {\r
         return ImmutableList.of(\r
                 new SubnetBuilder().setId(SUBNET_0)\r
-                        .setParent(L2FD_ID)\r
-                        .setIpPrefix(new IpPrefix(new Ipv4Prefix("10.0.1.0/24")))\r
-                        .setVirtualRouterIp(new IpAddress(new Ipv4Address("10.0.1.1")))\r
-                        .build(),\r
+                    .setParent(L2FD_ID)\r
+                    .setIpPrefix(new IpPrefix(new Ipv4Prefix("10.0.1.0/24")))\r
+                    .setVirtualRouterIp(new IpAddress(new Ipv4Address("10.0.1.1")))\r
+                    .build(),\r
                 new SubnetBuilder().setId(SUBNET_1)\r
-                        .setParent(L2FD_ID)\r
-                        .setIpPrefix(new IpPrefix(new Ipv4Prefix("10.0.0.0/24")))\r
-                        .setVirtualRouterIp(new IpAddress(new Ipv4Address("10.0.0.1")))\r
-                        .build(),\r
+                    .setParent(L2FD_ID)\r
+                    .setIpPrefix(new IpPrefix(new Ipv4Prefix("10.0.0.0/24")))\r
+                    .setVirtualRouterIp(new IpAddress(new Ipv4Address("10.0.0.1")))\r
+                    .build(),\r
                 new SubnetBuilder().setId(SUBNET_2)\r
-                        .setParent(L2BD_ID)\r
-                        .setIpPrefix(new IpPrefix(new Ipv4Prefix("10.0.2.0/24")))\r
-                        .setVirtualRouterIp(new IpAddress(new Ipv4Address("10.0.2.1")))\r
-                        .build(),\r
+                    .setParent(L2BD_ID)\r
+                    .setIpPrefix(new IpPrefix(new Ipv4Prefix("10.0.2.0/24")))\r
+                    .setVirtualRouterIp(new IpAddress(new Ipv4Address("10.0.2.1")))\r
+                    .build(),\r
                 new SubnetBuilder().setId(SUBNET_EXT)\r
-                        .setParent(L2_FD_ID_EXT)\r
-                        .setIpPrefix(new IpPrefix(new Ipv4Prefix("192.168.111.0/24")))\r
-                        .build());\r
+                    .setParent(L2_FD_ID_EXT)\r
+                    .setIpPrefix(new IpPrefix(new Ipv4Prefix("192.168.111.0/24")))\r
+                    .build());\r
     }\r
 }\r
index ca6c6eb9fa8ecd8a3077e06bf4a6cb4670bd7089..e11a76bfebe9a7fbeb0e3af0de172499e0d545e7 100755 (executable)
@@ -11,20 +11,23 @@ package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforc
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.when;
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.applyActionIns;
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.instructions;
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxOutputRegAction;
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.opendaylight.groupbasedpolicy.api.sf.ChainActionDefinition;
 import org.opendaylight.groupbasedpolicy.dto.ConditionGroup;
 import org.opendaylight.groupbasedpolicy.dto.EgKey;
 import org.opendaylight.groupbasedpolicy.dto.PolicyInfo;
@@ -38,6 +41,15 @@ import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMa
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.MapperUtilsTest;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.MockSwitchManager;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.AllowAction;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.ChainAction;
+import org.opendaylight.sfc.provider.api.SfcProviderServicePathAPI;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfcName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfpName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPaths;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPathsBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPathBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
@@ -48,6 +60,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionMatcherName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder;
@@ -61,6 +74,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.condition.matchers.ConditionMatcherBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.Condition;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.ConditionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.PolicyBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ContractBuilder;
@@ -71,6 +86,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ProviderMatchersBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.Rule;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.RuleBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstanceBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
@@ -90,201 +107,251 @@ import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
 @RunWith(PowerMockRunner.class)
-@PrepareForTest({PolicyManager.class})
+@PrepareForTest({PolicyManager.class, SfcProviderServicePathAPI.class})
 public class PolicyEnforcerTest extends MapperUtilsTest {
 
-    //TODO (att: kblagov) XXX needs redesign
-    private final int sameEpgFlows = 1;
-    private final int allowTunnelFlows = 1;
-    private final int layer4flowsIPv4 = 1;
-    private final int layer4flowsIPv6 = 1;
+    private static final String SFC_CHAIN = "sfc-chain";
     private static final String TCP_DST = "tcp_dst_80";
+    private static final int sameEpgFlows = 1;
+    private static final int allowTunnelFlows = 1;
+    private static final int layer4flowsIPv4 = 1;
+    private static final int layer4flowsIPv6 = 1;
 
-    private NodeConnectorId tunnelId =
-            new NodeConnectorId(NODE_ID.getValue() + ":42");
+    private NodeConnectorId tunnelId = new NodeConnectorId(NODE_ID.getValue() + ":42");
     private NodeConnectorId nodeConnector = new NodeConnectorId(NODE_ID.getValue() + CONNECTOR_0);
+
+    // custom mock instances to avoid downcasting of parent's fields
+    private MockEndpointManager endpointManagerMock;
+    private MockPolicyManager policyManagerMock;
+    private MockSwitchManager switchManagerMock;
+    private MockOfContext ctxMock;
+
+    private ActionInstance allowActionInstance;
+    private ActionInstance chainActionInstance;
+
     @Before
-    public void setup() throws Exception {
+    public void init() {
         PowerMockito.stub(PowerMockito.method(PolicyManager.class, "setSfcTableOffset")).toReturn(true);
 
-        endpointManager = new MockEndpointManager();
-        policyManager = new MockPolicyManager(endpointManager);
-        switchManager = new MockSwitchManager();
-        ctx = new MockOfContext(null,
-                             policyManager,
-                             switchManager,
-                             endpointManager,
-                             null);
-        table = new PolicyEnforcer(ctx, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER());
-
-        ((MockSwitchManager)switchManager).addSwitch(
-                NODE_ID,
-                tunnelId,
-                Collections.<NodeConnectorId>emptySet(),
-                new OfOverlayNodeConfigBuilder().setTunnel(
-                        ImmutableList.of(new TunnelBuilder().setIp(new IpAddress(new Ipv4Address("1.2.3.4")))
+        endpointManagerMock = new MockEndpointManager();
+        policyManagerMock = new MockPolicyManager(endpointManagerMock);
+        switchManagerMock = new MockSwitchManager();
+        ctxMock = new MockOfContext(null, policyManagerMock, switchManagerMock, endpointManagerMock, null);
+        table = new PolicyEnforcer(ctxMock, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER());
+
+        ServiceFunctionPath path = new ServiceFunctionPathBuilder().setName(new SfpName("sfp-name"))
+            .setServiceChainName(new SfcName(SFC_CHAIN))
+            .setSymmetric(true)
+            .build();
+        ServiceFunctionPaths paths =
+                new ServiceFunctionPathsBuilder().setServiceFunctionPath(ImmutableList.of(path)).build();
+
+        PowerMockito.mockStatic(SfcProviderServicePathAPI.class);
+        when(SfcProviderServicePathAPI.readAllServiceFunctionPaths()).thenReturn(paths);
+
+        allowActionInstance = new ActionInstanceBuilder().setName(new ActionName("allow"))
+            .setActionDefinitionId(new AllowAction().getId())
+            .build();
+
+        ParameterValue pv = new ParameterValueBuilder().setName(new ParameterName(ChainActionDefinition.SFC_CHAIN_NAME))
+            .setStringValue(SFC_CHAIN)
+            .build();
+        chainActionInstance = new ActionInstanceBuilder().setName(new ActionName("chain"))
+            .setActionDefinitionId(new ChainAction().getId())
+            .setParameterValue(ImmutableList.of(pv))
+            .build();
+
+        switchManagerMock
+            .addSwitch(NODE_ID, tunnelId,
+                    Collections
+                        .emptySet(),
+                    new OfOverlayNodeConfigBuilder()
+                        .setTunnel(ImmutableList.of(new TunnelBuilder().setIp(new IpAddress(new Ipv4Address("1.2.3.4")))
                             .setTunnelType(TunnelTypeVxlan.class)
                             .setNodeConnectorId(tunnelId)
-                            .build())).build());
+                            .build()))
+                        .build());
     }
 
     @Test
-    public void testSameEg() throws Exception {
+    public void test_SameEg() throws Exception {
         EndpointBuilder ep1Builder = buildEndpoint(IPV4_0, MAC_0, nodeConnector);
         ep1Builder.setEndpointGroup(ENDPOINT_GROUP_0);
         ep1Builder.setL2Context(L2BD_ID);
         Endpoint ep1 = ep1Builder.build();
-        ((MockEndpointManager)endpointManager).addEndpoint(ep1);
-        EndpointBuilder ep2Builder = buildEndpoint(IPV4_1,MAC_1, nodeConnector);
+        endpointManagerMock.addEndpoint(ep1);
+        EndpointBuilder ep2Builder = buildEndpoint(IPV4_1, MAC_1, nodeConnector);
         ep2Builder.setEndpointGroup(ENDPOINT_GROUP_1);
         ep2Builder.setL2Context(L2BD_ID);
         Endpoint ep2 = ep2Builder.build();
-        ((MockEndpointManager)endpointManager).addEndpoint(ep2);
-        ((MockOfContext)ctx).addTenant(buildTenant().setPolicy(new PolicyBuilder(buildTenant().getPolicy())
+        endpointManagerMock.addEndpoint(ep2);
+        ctxMock.addTenant(buildTenant().setPolicy(new PolicyBuilder(buildTenant().getPolicy())
             .setContract(ImmutableList.of(baseContract(null).build())).build()).build());
 
         ofWriter = new OfWriter();
         table.sync(ep1, ofWriter);
-        assertTrue(!ofWriter.getTableForNode(NODE_ID, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())
+
+        assertTrue(!ofWriter.getTableForNode(NODE_ID, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER())
             .getFlow()
             .isEmpty());
+
         int count = 0;
-        HashMap<String, Flow> flowMap = new HashMap<>();
-        for (Flow f : ofWriter.getTableForNode(NODE_ID, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow()) {
-            flowMap.put(f.getId().getValue(), f);
+        for (Flow f : ofWriter.getTableForNode(NODE_ID, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER())
+            .getFlow()) {
             if (isAllowSameEpg(f)) {
-                count += 1;
+                count++;
             }
         }
         assertEquals(sameEpgFlows, count);
+
         int totalFlows = sameEpgFlows + allowTunnelFlows + layer4flowsIPv4 + layer4flowsIPv6;
-        assertEquals(totalFlows, ofWriter.getTableForNode(NODE_ID, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())
-            .getFlow()
-            .size());
+        assertEquals(totalFlows, ofWriter
+            .getTableForNode(NODE_ID, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow().size());
     }
 
     @Test
-    public void testDifferentEg() throws Exception {
+    public void test_DifferentEg() throws Exception {
         int totalFlows = sameEpgFlows + allowTunnelFlows;
-        assertEquals(totalFlows, doTestDifferentEg(ImmutableList.of(baseSubject(null).build())));
+        assertEquals(totalFlows, doTestDifferentEg(ImmutableList.of(baseSubject(null).build()), allowActionInstance));
         // one layer4 flow for each direction
         totalFlows = sameEpgFlows + allowTunnelFlows + (2 * layer4flowsIPv4) + (2 * layer4flowsIPv6);
-        assertEquals(totalFlows, doTestDifferentEg(ImmutableList.of(baseSubject(Direction.Bidirectional).build())));
+        assertEquals(totalFlows,
+                doTestDifferentEg(ImmutableList.of(baseSubject(Direction.Bidirectional).build()), allowActionInstance));
         totalFlows = sameEpgFlows + allowTunnelFlows + layer4flowsIPv4 + layer4flowsIPv6;
-        assertEquals(totalFlows, doTestDifferentEg(ImmutableList.of(baseSubject(Direction.In).build())));
-        assertEquals(totalFlows, doTestDifferentEg(ImmutableList.of(baseSubject(Direction.Out).build())));
+        assertEquals(totalFlows,
+                doTestDifferentEg(ImmutableList.of(baseSubject(Direction.In).build()), allowActionInstance));
+        assertEquals(totalFlows,
+                doTestDifferentEg(ImmutableList.of(baseSubject(Direction.Out).build()), allowActionInstance));
     }
 
     @Test
-    public void doTestRule() throws Exception {
-        Rule rule1 = new RuleBuilder().setActionRef(
-                ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build()))
-            .setClassifierRef(
-                    createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC,
-                            Direction.In)))
+    public void test_Rules() throws Exception {
+        Rule rule1 = new RuleBuilder()
+            .setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build()))
+            .setClassifierRef(createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC, Direction.In)))
             .build();
-        Rule rule2 = new RuleBuilder().setActionRef(
-                ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build()))
-            .setClassifierRef(
-                    createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC,
-                            Direction.Out)))
+        Rule rule2 = new RuleBuilder()
+            .setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build()))
+            .setClassifierRef(createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC, Direction.Out)))
             .build();
-        Rule rule3 = new RuleBuilder().setActionRef(
-                ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build()))
-            .setClassifierRef(
-                    createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC,
-                            Direction.Out, "ether_type", Direction.In)))
+        Rule rule3 = new RuleBuilder()
+            .setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build()))
+            .setClassifierRef(createClassifierRefs(
+                    ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC, Direction.Out, "ether_type", Direction.In)))
             .build();
-        Rule rule4 = new RuleBuilder().setActionRef(
-                ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build()))
-            .setClassifierRef(
-                    createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, "tcp_dst_90",
-                            Direction.In)))
+        Rule rule4 = new RuleBuilder()
+            .setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build()))
+            .setClassifierRef(createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, "tcp_dst_90", Direction.In)))
             .build();
 
         int totalFlows = sameEpgFlows + allowTunnelFlows + layer4flowsIPv4 + layer4flowsIPv6;
         assertEquals(totalFlows,
-                doTestDifferentEg(ImmutableList.of(createSubject("s1", ImmutableList.of(rule1)))));
+                doTestDifferentEg(ImmutableList.of(createSubject("s1", ImmutableList.of(rule1))), allowActionInstance));
         // one layer4 flow for each direction
         totalFlows = sameEpgFlows + allowTunnelFlows + (2 * layer4flowsIPv4) + (2 * layer4flowsIPv6);
         assertEquals(totalFlows,
-                doTestDifferentEg(ImmutableList.of(createSubject("s2", ImmutableList.of(rule2)))));
-         // only one ether_type for out direction
+                doTestDifferentEg(ImmutableList.of(createSubject("s2", ImmutableList.of(rule2))), allowActionInstance));
+        // only one ether_type for out direction
         totalFlows = sameEpgFlows + allowTunnelFlows + (2 * layer4flowsIPv4) + layer4flowsIPv6;
         assertEquals(totalFlows,
-                doTestDifferentEg(ImmutableList.of(createSubject("s3", ImmutableList.of(rule3)))));
+                doTestDifferentEg(ImmutableList.of(createSubject("s3", ImmutableList.of(rule3))), allowActionInstance));
         totalFlows = sameEpgFlows + allowTunnelFlows;
         assertEquals(totalFlows,
-                doTestDifferentEg(ImmutableList.of(createSubject("s4", ImmutableList.of(rule4)))));
+                doTestDifferentEg(ImmutableList.of(createSubject("s4", ImmutableList.of(rule4))), allowActionInstance));
+    }
+
+    @Test
+    public void test_Rules_ChainAction() throws Exception {
+        Rule rule1 = new RuleBuilder()
+            .setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(CHAIN)).build()))
+            .setClassifierRef(createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC, Direction.In)))
+            .build();
+        Rule rule2 = new RuleBuilder()
+            .setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(CHAIN)).build()))
+            .setClassifierRef(createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC, Direction.Out)))
+            .build();
+        Rule rule3 = new RuleBuilder()
+            .setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(CHAIN)).build()))
+            .setClassifierRef(createClassifierRefs(
+                    ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC, Direction.Out, "ether_type", Direction.In)))
+            .build();
+        Rule rule4 = new RuleBuilder()
+            .setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(CHAIN)).build()))
+            .setClassifierRef(createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, "tcp_dst_90", Direction.In)))
+            .build();
+
+        assertEquals(2,
+                doTestDifferentEg(ImmutableList.of(createSubject("s1", ImmutableList.of(rule1))), chainActionInstance));
+        assertEquals(2,
+                doTestDifferentEg(ImmutableList.of(createSubject("s2", ImmutableList.of(rule2))), chainActionInstance));
+        assertEquals(2,
+                doTestDifferentEg(ImmutableList.of(createSubject("s3", ImmutableList.of(rule3))), chainActionInstance));
+        assertEquals(2,
+                doTestDifferentEg(ImmutableList.of(createSubject("s4", ImmutableList.of(rule4))), chainActionInstance));
     }
 
-    private int doTestDifferentEg(List<Subject> subjects) throws Exception {
+    private int doTestDifferentEg(List<Subject> subjects, ActionInstance actionInstance) throws Exception {
         EndpointBuilder ep1Builder = buildEndpoint(IPV4_0, MAC_0, nodeConnector);
         ep1Builder.setEndpointGroup(ENDPOINT_GROUP_0);
         ep1Builder.setL2Context(L2BD_ID);
         Endpoint ep1 = ep1Builder.build();
-        ((MockEndpointManager)endpointManager).addEndpoint(ep1);
+        endpointManagerMock.addEndpoint(ep1);
         EndpointBuilder ep2Builder = buildEndpoint(IPV4_1, MAC_1, nodeConnector);
         ep2Builder.setEndpointGroup(ENDPOINT_GROUP_1);
         ep2Builder.setL2Context(L2BD_ID);
         Endpoint ep2 = ep2Builder.build();
-        ((MockEndpointManager)endpointManager).addEndpoint(ep2);
-        ((MockOfContext)ctx).addTenant(buildTenant().setPolicy(new PolicyBuilder(buildTenant().getPolicy())
-            .setContract(ImmutableList.of(baseContract(subjects).build())).build()).build());
+        endpointManagerMock.addEndpoint(ep2);
+
+        TenantBuilder tb = buildTenant(actionInstance);
+        ctxMock.addTenant(tb.setPolicy(
+                new PolicyBuilder(tb.getPolicy()).setContract(ImmutableList.of(baseContract(subjects).build())).build())
+            .build());
 
         ofWriter = new OfWriter();
         table.sync(ep1, ofWriter);
-        assertTrue(!ofWriter.getTableForNode(NODE_ID, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())
+
+        assertTrue(!ofWriter.getTableForNode(NODE_ID, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER())
             .getFlow()
             .isEmpty());
+
         int count = 0;
-        for (Flow f : ofWriter.getTableForNode(NODE_ID, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow()) {
+        for (Flow f : ofWriter.getTableForNode(NODE_ID, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER())
+            .getFlow()) {
             if (isAllowSameEpg(f)) {
-                count += 1;
+                count++;
             } else if (f.getMatch() != null && Objects.equals(tunnelId, f.getMatch().getInPort())) {
                 assertEquals(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))), f.getInstructions());
-                count += 1;
-            } else if (f.getMatch() != null
-                    && f.getMatch().getEthernetMatch() != null
-                    && Objects.equals(FlowUtils.IPv4, f.getMatch()
-                        .getEthernetMatch()
-                        .getEthernetType()
-                        .getType()
-                        .getValue())
+                count++;
+            } else if (f.getMatch() != null && f.getMatch().getEthernetMatch() != null
+                    && Objects.equals(FlowUtils.IPv4,
+                            f.getMatch().getEthernetMatch().getEthernetType().getType().getValue())
                     && f.getMatch().getIpMatch() != null
                     && Objects.equals((short) 6, f.getMatch().getIpMatch().getIpProtocol())
                     && f.getMatch().getLayer4Match() != null
                     && (Objects.equals(new PortNumber(80),
-                            ((TcpMatch) f.getMatch().getLayer4Match()).getTcpSourcePort()) || Objects.equals(
-                            new PortNumber(80),
-                            ((TcpMatch) f.getMatch().getLayer4Match()).getTcpDestinationPort()))) {
-                count += 1;
-            } else if (f.getMatch() != null
-                    && f.getMatch().getEthernetMatch() != null
-                    && Objects.equals(FlowUtils.IPv6, f.getMatch()
-                        .getEthernetMatch()
-                        .getEthernetType()
-                        .getType()
-                        .getValue())
+                            ((TcpMatch) f.getMatch().getLayer4Match()).getTcpSourcePort())
+                            || Objects.equals(new PortNumber(80),
+                                    ((TcpMatch) f.getMatch().getLayer4Match()).getTcpDestinationPort()))) {
+                count++;
+            } else if (f.getMatch() != null && f.getMatch().getEthernetMatch() != null
+                    && Objects.equals(FlowUtils.IPv6,
+                            f.getMatch().getEthernetMatch().getEthernetType().getType().getValue())
                     && f.getMatch().getIpMatch() != null
                     && Objects.equals((short) 6, f.getMatch().getIpMatch().getIpProtocol())
                     && f.getMatch().getLayer4Match() != null
                     && (Objects.equals(new PortNumber(80),
-                            ((TcpMatch) f.getMatch().getLayer4Match()).getTcpSourcePort()) || Objects.equals(
-                            new PortNumber(80),
-                            ((TcpMatch) f.getMatch().getLayer4Match()).getTcpDestinationPort()))) {
-                count += 1;
+                            ((TcpMatch) f.getMatch().getLayer4Match()).getTcpSourcePort())
+                            || Objects.equals(new PortNumber(80),
+                                    ((TcpMatch) f.getMatch().getLayer4Match()).getTcpDestinationPort()))) {
+                count++;
             }
         }
         return count;
     }
 
     @Test
-    public void testConditions() throws Exception {
+    public void test_Conditions() throws Exception {
         Condition cond1 = new ConditionBuilder().setName(new ConditionName("cond1")).build();
         Condition cond2 = new ConditionBuilder().setName(new ConditionName("cond2")).build();
 
@@ -293,42 +360,41 @@ public class PolicyEnforcerTest extends MapperUtilsTest {
         ep1Builder.setL2Context(L2BD_ID);
         ep1Builder.setCondition(ImmutableList.of(cond1.getName())).build();
         Endpoint ep1 = ep1Builder.build();
-        ((MockEndpointManager)endpointManager).addEndpoint(ep1);
-        EndpointBuilder ep2Builder = buildEndpoint(IPV4_1,MAC_1, nodeConnector);
+        endpointManagerMock.addEndpoint(ep1);
+        EndpointBuilder ep2Builder = buildEndpoint(IPV4_1, MAC_1, nodeConnector);
         ep2Builder.setEndpointGroup(ENDPOINT_GROUP_1);
         ep2Builder.setL2Context(L2BD_ID);
         ep2Builder.setCondition(ImmutableList.of(cond1.getName(), cond2.getName())).build();
         Endpoint ep2 = ep2Builder.build();
-        ((MockEndpointManager)endpointManager).addEndpoint(ep2);
-
-        TenantBuilder tb = buildTenant().setPolicy(new PolicyBuilder(buildTenant().getPolicy()).setContract(
-                ImmutableList.of(new ContractBuilder().setId(CONTRACT_ID)
-                    .setSubject(ImmutableList.of(baseSubject(Direction.Out).build()))
-                    .setClause(
-                            ImmutableList.of(new ClauseBuilder().setName(new ClauseName("test"))
-                                .setSubjectRefs(ImmutableList.of(new SubjectName("s1")))
-                                .setConsumerMatchers(
-                                        new ConsumerMatchersBuilder().setConditionMatcher(
-                                                ImmutableList.of(new ConditionMatcherBuilder().setName(
-                                                        new ConditionMatcherName("m1"))
-                                                    .setCondition(ImmutableList.of(cond1, cond2))
-                                                    .setMatchType(MatchType.Any)
-                                                    .build())).build())
-                                .setProviderMatchers(
-                                        new ProviderMatchersBuilder().setConditionMatcher(
-                                                ImmutableList.of(new ConditionMatcherBuilder().setName(
-                                                        new ConditionMatcherName("m2"))
-                                                    .setCondition(ImmutableList.of(cond1, cond2))
-                                                    .setMatchType(MatchType.All)
-                                                    .build())).build())
+        endpointManagerMock.addEndpoint(ep2);
+
+        TenantBuilder tb = buildTenant().setPolicy(new PolicyBuilder(buildTenant().getPolicy())
+            .setContract(ImmutableList.of(new ContractBuilder().setId(CONTRACT_ID)
+                .setSubject(ImmutableList.of(baseSubject(Direction.Out).build()))
+                .setClause(ImmutableList.of(new ClauseBuilder().setName(new ClauseName("test"))
+                    .setSubjectRefs(ImmutableList.of(new SubjectName("s1")))
+                    .setConsumerMatchers(new ConsumerMatchersBuilder().setConditionMatcher(
+                            ImmutableList.of(new ConditionMatcherBuilder().setName(new ConditionMatcherName("m1"))
+                                .setCondition(ImmutableList.of(cond1, cond2))
+                                .setMatchType(MatchType.Any)
                                 .build()))
-                    .build())).build());
-        ((MockOfContext)ctx).addTenant(tb.build());
+                        .build())
+                    .setProviderMatchers(new ProviderMatchersBuilder()
+                        .setConditionMatcher(
+                                ImmutableList.of(new ConditionMatcherBuilder().setName(new ConditionMatcherName("m2"))
+                                    .setCondition(ImmutableList.of(cond1, cond2))
+                                    .setMatchType(MatchType.All)
+                                    .build()))
+                        .build())
+                    .build()))
+                .build()))
+            .build());
+        ctxMock.addTenant(tb.build());
 
-        PolicyInfo policy = ctx.getCurrentPolicy();
-        List<ConditionName> ep1c = endpointManager.getConditionsForEndpoint(ep1);
+        PolicyInfo policy = ctxMock.getCurrentPolicy();
+        List<ConditionName> ep1c = endpointManagerMock.getConditionsForEndpoint(ep1);
         ConditionGroup cg1 = policy.getEgCondGroup(new EgKey(tb.getId(), ep1.getEndpointGroup()), ep1c);
-        List<ConditionName> ep2c = endpointManager.getConditionsForEndpoint(ep2);
+        List<ConditionName> ep2c = endpointManagerMock.getConditionsForEndpoint(ep2);
         ConditionGroup cg2 = policy.getEgCondGroup(new EgKey(tb.getId(), ep2.getEndpointGroup()), ep2c);
         int cg1Id = OrdinalFactory.getCondGroupOrdinal(cg1);
         int cg2Id = OrdinalFactory.getCondGroupOrdinal(cg2);
@@ -348,17 +414,15 @@ public class PolicyEnforcerTest extends MapperUtilsTest {
         int dropAllFlow = 1;
         int arpFlows = 1;
         int totalFlows = sameEpgFlows + allowTunnelFlows + layer4flowsIPv4 + layer4flowsIPv6 + arpFlows + dropAllFlow;
-        assertEquals(totalFlows, ofWriter.getTableForNode(NODE_ID, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())
-            .getFlow()
-            .size());
-        HashMap<String, Flow> flowMap = new HashMap<>();
-        for (Flow f : ofWriter.getTableForNode(NODE_ID, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow()) {
-            flowMap.put(f.getId().getValue(), f);
+        assertEquals(totalFlows, ofWriter
+            .getTableForNode(NODE_ID, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow().size());
+        for (Flow f : ofWriter.getTableForNode(NODE_ID, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER())
+            .getFlow()) {
             if (f.getMatch() != null && f.getMatch().getEthernetMatch() != null) {
                 count++;
             }
         }
-        //flows with ether_type match
+        // flows with ether_type match
         totalFlows = layer4flowsIPv4 + layer4flowsIPv6 + arpFlows;
         assertEquals(totalFlows, count);
     }
@@ -368,8 +432,8 @@ public class PolicyEnforcerTest extends MapperUtilsTest {
         // (these register values don't have to be equal)
         boolean res = false;
         if (flow != null && flow.getMatch() != null) {
-            GeneralAugMatchNodesNodeTableFlow genAug = flow.getMatch().getAugmentation(
-                    GeneralAugMatchNodesNodeTableFlow.class);
+            GeneralAugMatchNodesNodeTableFlow genAug =
+                    flow.getMatch().getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);
             if (genAug != null) {
                 List<ExtensionList> extensions = genAug.getExtensionList();
                 if (extensions != null && extensions.size() == 2) {
@@ -379,7 +443,8 @@ public class PolicyEnforcerTest extends MapperUtilsTest {
                         Class<? extends ExtensionKey> extensionKey = extensionList.getExtensionKey();
                         Extension extension = extensionList.getExtension();
                         if (extensionKey != null && extension != null) {
-                            NxAugMatchNodesNodeTableFlow nxAugMatch = extension.getAugmentation(NxAugMatchNodesNodeTableFlow.class);
+                            NxAugMatchNodesNodeTableFlow nxAugMatch =
+                                    extension.getAugmentation(NxAugMatchNodesNodeTableFlow.class);
                             if (nxAugMatch != null && nxAugMatch.getNxmNxReg() != null) {
                                 if (extensionKey.equals(NxmNxReg0Key.class)) {
                                     reg0 = nxAugMatch.getNxmNxReg().getValue();
@@ -398,9 +463,8 @@ public class PolicyEnforcerTest extends MapperUtilsTest {
         return res;
     }
 
-    protected ContractBuilder baseContract(List<Subject> subjects) {
+    private ContractBuilder baseContract(List<Subject> subjects) {
         ContractBuilder contractBuilder = new ContractBuilder().setId(CONTRACT_ID).setSubject(subjects);
-        // TODO refactor
         if (subjects == null) {
             return contractBuilder.setClause(ImmutableList.of(new ClauseBuilder().setName(new ClauseName("test"))
                 .setSubjectRefs(ImmutableList.of(new SubjectName("s1")))
@@ -410,31 +474,26 @@ public class PolicyEnforcerTest extends MapperUtilsTest {
         for (Subject subject : subjects) {
             subjectNames.add(subject.getName());
         }
-        return contractBuilder.setClause(ImmutableList.of(new ClauseBuilder().setName(new ClauseName("test"))
-            .setSubjectRefs(subjectNames)
-            .build()));
+        return contractBuilder.setClause(ImmutableList
+            .of(new ClauseBuilder().setName(new ClauseName("test")).setSubjectRefs(subjectNames).build()));
     }
 
-    protected SubjectBuilder baseSubject(Direction direction) {
-        return new SubjectBuilder()
-            .setName(new SubjectName("s1"))
+    private SubjectBuilder baseSubject(Direction direction) {
+        return new SubjectBuilder().setName(new SubjectName("s1"))
             .setRule(ImmutableList.of(new RuleBuilder()
-                .setActionRef(ImmutableList.of(new ActionRefBuilder()
-                    .setName(new ActionName(ALLOW))
-                    .build()))
-                .setClassifierRef(ImmutableList.of(new ClassifierRefBuilder()
-                    .setName(new ClassifierName(TCP_DST))
+                .setActionRef(ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build()))
+                .setClassifierRef(ImmutableList.of(new ClassifierRefBuilder().setName(new ClassifierName(TCP_DST))
                     .setDirection(direction)
                     .setInstanceName(new ClassifierName(TCP_DST))
                     .build()))
                 .build()));
     }
 
-    protected Subject createSubject(String name, List<Rule> rules){
+    private Subject createSubject(String name, List<Rule> rules) {
         return new SubjectBuilder().setName(new SubjectName(name)).setRule(rules).build();
     }
 
-    protected List<ClassifierRef> createClassifierRefs(Map<String, Direction> refNamesAndDirections) {
+    private List<ClassifierRef> createClassifierRefs(Map<String, Direction> refNamesAndDirections) {
         List<ClassifierRef> refs = new ArrayList<>();
         for (String refName : refNamesAndDirections.keySet()) {
             refs.add(new ClassifierRefBuilder().setName(new ClassifierName(refName))