Merge "chain resolution improved in ios-xe renderer"
authorMartin Sunal <msunal@cisco.com>
Tue, 19 Jul 2016 13:11:50 +0000 (13:11 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 19 Jul 2016 13:11:50 +0000 (13:11 +0000)
renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyManagerImpl.java
renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/PolicyManagerUtil.java
renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/ServiceChainingUtil.java
renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/PolicyWriter.java
renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/PolicyWriterUtil.java
renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyManagerImplTest.java
renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/PolicyManagerUtilTest.java
renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/ServiceChainingUtilTest.java

index 5934b02a21da778289c74fafc9096e99c1c0aea9..bfb4ee16afdf0f74da3328ee339737d3dcdb1d81 100644 (file)
@@ -11,15 +11,19 @@ package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager;
 import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Create;
 import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Delete;
 
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -47,12 +51,6 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.AsyncFunction;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
 public class PolicyManagerImpl implements PolicyManager {
 
     private static final Logger LOG = LoggerFactory.getLogger(PolicyManagerImpl.class);
@@ -72,12 +70,12 @@ public class PolicyManagerImpl implements PolicyManager {
                                                 final long version) {
         final ListenableFuture<Optional<Status>> result;
         if (dataBefore == null && dataAfter != null) {
-            result = syncPolicy(dataAfter, Create);
+            result = syncEndpoints(dataAfter, Create);
         } else if (dataBefore != null && dataAfter == null) {
-            result = syncPolicy(dataBefore, Delete);
+            result = syncEndpoints(dataBefore, Delete);
         } else {
-            syncPolicy(dataBefore, Delete);
-            syncPolicy(dataAfter, Create);
+            syncEndpoints(dataBefore, Delete);
+            syncEndpoints(dataAfter, Create);
             result = Futures.immediateFuture(Optional.empty());
         }
 
@@ -95,7 +93,7 @@ public class PolicyManagerImpl implements PolicyManager {
         });
     }
 
-    private ListenableFuture<Optional<Status>> syncPolicy(final Configuration dataAfter, DsAction action) {
+    private ListenableFuture<Optional<Status>> syncEndpoints(final Configuration dataAfter, DsAction action) {
         if (dataAfter.getRendererEndpoints() == null
                 || dataAfter.getRendererEndpoints().getRendererEndpoint() == null) {
             LOG.debug("no configuration obtained - skipping");
@@ -115,7 +113,7 @@ public class PolicyManagerImpl implements PolicyManager {
             }
             final List<AddressEndpointWithLocation> endpointsWithLocation = dataAfter.getEndpoints()
                     .getAddressEndpointWithLocation();
-            final InstanceIdentifier mountpointIid = PolicyManagerUtil.getAbsoluteLocationMountpoint(rendererEndpoint, endpointsWithLocation);
+            final InstanceIdentifier mountpointIid = PolicyManagerUtil.getMountpointIidFromAbsoluteLocation(rendererEndpoint, endpointsWithLocation);
             final DataBroker mountpoint = nodeManager.getNodeMountPoint(mountpointIid);
             if (mountpoint == null) {
                 final String info = String.format("no data-broker for mount-point [%s] available", mountpointIid);
@@ -123,14 +121,14 @@ public class PolicyManagerImpl implements PolicyManager {
                 continue;
             }
             // Generate policy writer key - policy map name, composed from base value, interface name and node id
-            final String interfaceName = PolicyManagerUtil.getInterfaceNameForPolicyMap(rendererEndpoint, endpointsWithLocation);
+            final String interfaceName = PolicyManagerUtil.getInterfaceNameFromAbsoluteLocation(rendererEndpoint, endpointsWithLocation);
             final NodeId nodeId = nodeManager.getNodeIdByMountpointIid(mountpointIid);
             if (interfaceName == null || nodeId == null) {
                 LOG.warn("Cannot compose policy-map, missing value. Interface: {}, NodeId: {}", interfaceName, nodeId);
                 continue;
             }
             final String policyMapName = BASE_POLICY_MAP_NAME.concat(interfaceName);
-            final String policyWriterKey = policyMapName.concat(nodeId.getValue());
+            final String policyWriterKey = policyMapName.concat("-" + nodeId.getValue());
             // Find appropriate writer
             PolicyWriter policyWriter = policyWriterPerDeviceCache.get(policyWriterKey);
             if (policyWriter == null) {
@@ -162,7 +160,7 @@ public class PolicyManagerImpl implements PolicyManager {
                             StatusUtil.assembleNotConfigurableRendererEPForPeer(context, peerEndpoint, info));
                     continue;
                 }
-                PolicyManagerUtil.syncPolicyEntities(sourceSgt, destinationSgt, context, dataAfter, peerEndpoint,
+                PolicyManagerUtil.syncResolvedPolicy(sourceSgt, destinationSgt, context, dataAfter, peerEndpoint,
                         dataBroker, action);
             }
         }
index 5280daee4e63a64b90179bf22bfb88201d14cae0..2d0ff18f756e2df4af96324985f3ecf3c9afaac5 100644 (file)
@@ -12,16 +12,21 @@ import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.ma
 import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Create;
 import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Delete;
 
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import com.google.common.base.Preconditions;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.groupbasedpolicy.api.sf.ChainActionDefinition;
 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyConfigurationContext;
 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.ActionCase;
 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308.ClassNameType;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308.PolicyActionType;
@@ -34,7 +39,7 @@ import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.ServicePolicy;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.ServicePolicyBuilder;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.TypeBuilder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.type.ServiceChain;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.type.ServiceChain.Direction;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.type.ServiceChainBuilder;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMapBuilder;
@@ -63,6 +68,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
@@ -70,6 +77,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroup;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.actions.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.Classifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.resolved.rules.ResolvedRule;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.AddressEndpointWithLocationAug;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
@@ -81,30 +89,68 @@ public class PolicyManagerUtil {
 
     private static final Logger LOG = LoggerFactory.getLogger(PolicyManagerUtil.class);
 
-    public static void syncPolicyEntities(final Sgt sourceSgt, final Sgt destinationSgt, final PolicyConfigurationContext context,
+    /**
+     * Main method which looks for all actions specified in rules between two endpoints. Whichever action has been found,
+     * it is resolved. Only chain action is supported for now.
+     *
+     * @param sourceSgt      - security group tag of source endpoint
+     * @param destinationSgt - security group tag of destination endpoint
+     * @param context        - stores policy writer and info about not configurable rules
+     * @param dataAfter      - new data, used to found appropriate rule group
+     * @param peerEndpoint   - contains info about rule groups between endpoint pairs
+     * @param dataBroker     - data provider for odl controller
+     * @param action         - required action crate/delete
+     */
+    public static void syncResolvedPolicy(final Sgt sourceSgt, final Sgt destinationSgt, final PolicyConfigurationContext context,
                                           final Configuration dataAfter, final PeerEndpoint peerEndpoint,
                                           final DataBroker dataBroker, final PolicyManagerImpl.DsAction action) {
-        // Action
-        final Map<PolicyManagerImpl.ActionCase, Action> actionMap = PolicyManagerUtil.getActionInDirection(dataAfter, peerEndpoint);
-        if (actionMap == null || actionMap.isEmpty()) {
+        // Find actions from acquired data
+        final Map<ActionCase, ActionInDirection> actionMap = PolicyManagerUtil.getActionInDirection(dataAfter, peerEndpoint);
+        if (actionMap.isEmpty()) {
             LOG.debug("no usable action found for EP-sgt[{}] | peerEP-sgt[{}]",
                     sourceSgt, destinationSgt);
             return;
         }
 
-        // TODO allow action not supported
-
-        // Resolve chain action - create
-        if (actionMap.containsKey(PolicyManagerImpl.ActionCase.CHAIN) && action.equals(Create)) {
+        // Chain action
+        if (actionMap.containsKey(ActionCase.CHAIN) && action.equals(Create)) {
             ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, context,
                     dataBroker);
         }
-        if (actionMap.containsKey(PolicyManagerImpl.ActionCase.CHAIN) && action.equals(Delete)) {
-            ServiceChainingUtil.removeChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap,
+        if (actionMap.containsKey(ActionCase.CHAIN) && action.equals(Delete)) {
+            ServiceChainingUtil.resolveRemovedChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap,
                     context.getPolicyWriter());
         }
     }
 
+    /**
+     * According to info from {@link RuleGroupWithRendererEndpointParticipation} (composite key) finds appropriate subject
+     *
+     * @param data                       - contains all rule groups
+     * @param ruleGroupWithParticipation - contains info about how to find right rule group
+     * @return rule group if found, null otherwise
+     */
+    @Nullable
+    private static RuleGroup findRuleGroup(final Configuration data,
+                                           final RuleGroupWithRendererEndpointParticipation ruleGroupWithParticipation) {
+        final TenantId tenantId = ruleGroupWithParticipation.getTenantId();
+        final ContractId contractId = ruleGroupWithParticipation.getContractId();
+        final SubjectName subjectName = ruleGroupWithParticipation.getSubjectName();
+        for (RuleGroup ruleGroup : data.getRuleGroups().getRuleGroup()) {
+            if (!ruleGroup.getTenantId().equals(tenantId)) {
+                continue;
+            }
+            if (!ruleGroup.getContractId().equals(contractId)) {
+                continue;
+            }
+            if (ruleGroup.getSubjectName().equals(subjectName)) {
+                return ruleGroup;
+            }
+        }
+        return null;
+    }
+
+    @Nullable
     public static Sgt findSgtTag(final AddressEndpointKey endpointKey,
                                  final List<AddressEndpointWithLocation> endpointsWithLocation) {
         if (endpointKey == null || endpointsWithLocation == null) {
@@ -120,43 +166,35 @@ public class PolicyManagerUtil {
         return augmentation.getSgt();
     }
 
-    static Match createSecurityGroupMatch(final int sourceTag, final int destinationTag) {
-        final SecurityGroupBuilder sgBuilder = new SecurityGroupBuilder();
-        final Source source = new SourceBuilder().setTag(sourceTag).build();
-        final Destination destination = new DestinationBuilder().setTag(destinationTag).build();
-        sgBuilder.setDestination(destination)
-                .setSource(source);
-        final SecurityGroup securityGroup = sgBuilder.build();
-        final MatchBuilder matchBuilder = new MatchBuilder();
-        matchBuilder.setSecurityGroup(securityGroup);
-        return matchBuilder.build();
-    }
-
-    static ClassMap createClassMap(final String classMapName, final Match match) {
-        final ClassMapBuilder cmBuilder = new ClassMapBuilder();
-        cmBuilder.setName(classMapName)
-                .setKey(new ClassMapKey(classMapName))
-                .setPrematch(ClassMap.Prematch.MatchAll)
-                .setMatch(match);
-        return cmBuilder.build();
-    }
+    public static ServicePolicy createServicePolicy(final String chainName, final Direction direction) {
+        // Service Chain
+        final ServiceChainBuilder serviceChainBuilder = new ServiceChainBuilder();
+        serviceChainBuilder.setName(chainName) // Same as the policy map name
+                .setDirection(direction);
+        // Service policy
+        final TypeBuilder typeBuilder = new TypeBuilder();
+        typeBuilder.setServiceChain(serviceChainBuilder.build());
+        // Service Policy
+        ServicePolicyBuilder servicePolicyBuilder = new ServicePolicyBuilder();
+        servicePolicyBuilder.setType(typeBuilder.build());
 
-    static TenantId getTenantId(final PeerEndpoint peer) {
-        for (RuleGroupWithRendererEndpointParticipation ruleGroup :
-                peer.getRuleGroupWithRendererEndpointParticipation()) {
-            if (ruleGroup.getTenantId() != null) {
-                return ruleGroup.getTenantId();
-            }
-        }
-        return null;
+        return servicePolicyBuilder.build();
     }
 
-    static String generateClassMapName(final int sourceTag, final int destinationTag) {
-        return "srcTag" + sourceTag + "_dstTag" + destinationTag;
+    public static PolicyMap createPolicyMap(final String policyMapName, final Set<Class> policyMapEntries) {
+        // TODO maybe could be better to create also class-default entry with pass-through value than not to create any default entry at all
+        // Construct policy map
+        final List<Class> policyMapEntriesList = new ArrayList<>(policyMapEntries);
+        final PolicyMapBuilder policyMapBuilder = new PolicyMapBuilder();
+        policyMapBuilder.setName(policyMapName)
+                .setKey(new PolicyMapKey(policyMapName))
+                .setType(PolicyMap.Type.ServiceChain)
+                .setXmlClass(policyMapEntriesList);
+        return policyMapBuilder.build();
     }
 
     static Class createPolicyEntry(final String policyClassName, final RenderedServicePath renderedPath,
-                                   final PolicyManagerImpl.ActionCase actionCase) {
+                                   final ActionCase actionCase) {
         // Forward Case
         final ForwardCaseBuilder forwardCaseBuilder = new ForwardCaseBuilder();
         if (actionCase.equals(CHAIN) && renderedPath != null) {
@@ -186,36 +224,86 @@ public class PolicyManagerUtil {
         return policyClassBuilder.build();
     }
 
-    public static PolicyMap createPolicyMap(final String policyMapName, final Set<Class> policyMapEntries) {
-        // TODO maybe could be better to create also class-default entry with pass-through value than not to create any default entry at all
-        final List<Class> policyMapEntriesList = new ArrayList<>(policyMapEntries);
+    static Match createSecurityGroupMatch(final int sourceTag, final int destinationTag) {
+        final SecurityGroupBuilder sgBuilder = new SecurityGroupBuilder();
+        final Source source = new SourceBuilder().setTag(sourceTag).build();
+        final Destination destination = new DestinationBuilder().setTag(destinationTag).build();
+        sgBuilder.setDestination(destination)
+                .setSource(source);
+        final SecurityGroup securityGroup = sgBuilder.build();
+        final MatchBuilder matchBuilder = new MatchBuilder();
+        matchBuilder.setSecurityGroup(securityGroup);
+        return matchBuilder.build();
+    }
 
-        // Construct policy map
-        final PolicyMapBuilder policyMapBuilder = new PolicyMapBuilder();
-        policyMapBuilder.setName(policyMapName)
-                .setKey(new PolicyMapKey(policyMapName))
-                .setType(PolicyMap.Type.ServiceChain)
-                .setXmlClass(policyMapEntriesList);
-        return policyMapBuilder.build();
+    static ClassMap createClassMap(final String classMapName, final Match match) {
+        final ClassMapBuilder cmBuilder = new ClassMapBuilder();
+        cmBuilder.setName(classMapName)
+                .setKey(new ClassMapKey(classMapName))
+                .setPrematch(ClassMap.Prematch.MatchAll)
+                .setMatch(match);
+        return cmBuilder.build();
     }
 
-    public static ServicePolicy createServicePolicy(final String chainName, final ServiceChain.Direction direction) {
-        // Service Chain
-        final ServiceChainBuilder serviceChainBuilder = new ServiceChainBuilder();
-        serviceChainBuilder.setName(chainName) // Same as the policy map name
-                .setDirection(direction);
-        // Service policy
-        final TypeBuilder typeBuilder = new TypeBuilder();
-        typeBuilder.setServiceChain(serviceChainBuilder.build());
-        // Service Policy
-        ServicePolicyBuilder servicePolicyBuilder = new ServicePolicyBuilder();
-        servicePolicyBuilder.setType(typeBuilder.build());
+    /**
+     * Constructs {@link ActionInDirection} object with {@link ActionCase} as a key. ActionInDirection object contains
+     * info about action, participation and rule direction.
+     *
+     * @param data - used for finding rule's rule group
+     * @param peer - contains {@link RuleGroupWithRendererEndpointParticipation}
+     * @return map with actionCase/ActionInDirection entries, empty map if no rule is found
+     */
+    @Nonnull
+    private static Map<ActionCase, ActionInDirection> getActionInDirection(final Configuration data,
+                                                                           final PeerEndpoint peer) {
+        final Set<ResolvedRule> rulesInDirection = new HashSet<>();
+        EndpointPolicyParticipation participation = null;
+        HasDirection.Direction direction = null;
+        // Find all rules in desired direction
+        for (RuleGroupWithRendererEndpointParticipation ruleGroupKey :
+                peer.getRuleGroupWithRendererEndpointParticipation()) {
+            participation = ruleGroupKey.getRendererEndpointParticipation();
+            final RuleGroup ruleGroup = findRuleGroup(data, ruleGroupKey);
+            if (ruleGroup == null || ruleGroup.getResolvedRule() == null) {
+                continue;
+            }
 
-        return servicePolicyBuilder.build();
+            for (ResolvedRule resolvedRule : ruleGroup.getResolvedRule()) {
+                if (resolvedRule == null) {
+                    continue;
+                }
+                if (resolvedRule.getClassifier() == null || resolvedRule.getAction() == null) {
+                    continue;
+                }
+                // TODO only first Classifier used
+                final Classifier classifier = resolvedRule.getClassifier().get(0);
+                direction = classifier.getDirection();
+                rulesInDirection.add(resolvedRule);
+            }
+        }
+        if (rulesInDirection.isEmpty()) {
+            return Collections.emptyMap();
+        }
+        // TODO use only first rule with ActionDefinitionID for now
+        final Map<ActionCase, ActionInDirection> result = new HashMap<>();
+        for (ResolvedRule resolvedRule : rulesInDirection) {
+            // TODO only first action used for now
+            final Action action = resolvedRule.getAction().get(0);
+            if (action.getActionDefinitionId() != null) {
+                final ActionDefinitionId actionDefinitionId = action.getActionDefinitionId();
+                // Currently only chain action is supported
+                if (actionDefinitionId.equals(ChainActionDefinition.ID)) {
+                    ActionInDirection actionInDirection = new ActionInDirection(action, participation, direction);
+                    result.put(ActionCase.CHAIN, actionInDirection);
+                    return result;
+                }
+            }
+        }
+        return Collections.emptyMap();
     }
 
-    public static InstanceIdentifier getAbsoluteLocationMountpoint(final RendererEndpoint endpoint,
-                                                                   final List<AddressEndpointWithLocation> endpointsWithLocation) {
+    public static InstanceIdentifier getMountpointIidFromAbsoluteLocation(final RendererEndpoint endpoint,
+                                                                          final List<AddressEndpointWithLocation> endpointsWithLocation) {
         if (endpointsWithLocation.isEmpty()) {
             return null;
         }
@@ -232,8 +320,8 @@ public class PolicyManagerUtil {
         return location.getExternalNodeMountPoint();
     }
 
-    public static String getInterfaceNameForPolicyMap(final RendererEndpoint endpoint,
-                                                      final List<AddressEndpointWithLocation> endpointsWithLocation) {
+    public static String getInterfaceNameFromAbsoluteLocation(final RendererEndpoint endpoint,
+                                                              final List<AddressEndpointWithLocation> endpointsWithLocation) {
         if (endpoint == null || endpointsWithLocation == null) {
             return null;
         }
@@ -250,63 +338,47 @@ public class PolicyManagerUtil {
         return location.getExternalNodeConnector();
     }
 
-
-    private static Map<PolicyManagerImpl.ActionCase, Action> getActionInDirection(final Configuration data, final PeerEndpoint peer) {
-        final Set<ResolvedRule> rulesInDirection = new HashSet<>();
-        // Find all rules in desired direction
-        for (RuleGroupWithRendererEndpointParticipation ruleGroupKey :
+    static TenantId getTenantId(final PeerEndpoint peer) {
+        for (RuleGroupWithRendererEndpointParticipation ruleGroup :
                 peer.getRuleGroupWithRendererEndpointParticipation()) {
-            final RuleGroup ruleGroup = findRuleGroup(data, ruleGroupKey);
-            if (ruleGroup == null || ruleGroup.getResolvedRule() == null) {
-                continue;
+            if (ruleGroup.getTenantId() != null) {
+                return ruleGroup.getTenantId();
             }
+        }
+        return null;
+    }
 
-            for (ResolvedRule resolvedRule : ruleGroup.getResolvedRule()) {
-                if (resolvedRule == null) {
-                    continue;
-                }
-                if (resolvedRule.getClassifier() == null || resolvedRule.getAction() == null) {
-                    continue;
-                }
-                rulesInDirection.add(resolvedRule);
-            }
+    static String generateClassMapName(final int sourceTag, final int destinationTag) {
+        return "srcTag" + sourceTag + "_dstTag" + destinationTag;
+    }
+
+    /**
+     * Action in Direction - wrapper class
+     */
+    static class ActionInDirection {
+
+        private final Action action;
+        private final EndpointPolicyParticipation participation;
+        private final HasDirection.Direction direction;
+
+        ActionInDirection(final Action action,
+                          final EndpointPolicyParticipation participation,
+                          final HasDirection.Direction direction) {
+            this.action = Preconditions.checkNotNull(action);
+            this.participation = Preconditions.checkNotNull(participation);
+            this.direction = Preconditions.checkNotNull(direction);
         }
-        if (rulesInDirection.isEmpty()) {
-            return null;
+
+        Action getAction() {
+            return action;
         }
-        // TODO use only first rule with ActionDefinitionID for now
-        final Map<PolicyManagerImpl.ActionCase, Action> result = new HashMap<>();
-        for (ResolvedRule resolvedRule : rulesInDirection) {
-            // TODO only first action used for now
-            final Action action = resolvedRule.getAction().get(0);
-            if (action.getActionDefinitionId() != null) {
-                final ActionDefinitionId actionDefinitionId = action.getActionDefinitionId();
-                // Currently only chain action is supported
-                if (actionDefinitionId.equals(ChainActionDefinition.ID)) {
-                    result.put(PolicyManagerImpl.ActionCase.CHAIN, action);
-                    return result;
-                }
-            }
+
+        EndpointPolicyParticipation getParticipation() {
+            return participation;
         }
-        return null;
-    }
 
-    private static RuleGroup findRuleGroup(final Configuration data,
-                                           final RuleGroupWithRendererEndpointParticipation ruleGroupWithParticipation) {
-        final TenantId tenantId = ruleGroupWithParticipation.getTenantId();
-        final ContractId contractId = ruleGroupWithParticipation.getContractId();
-        final SubjectName subjectName = ruleGroupWithParticipation.getSubjectName();
-        for (RuleGroup ruleGroup : data.getRuleGroups().getRuleGroup()) {
-            if (!ruleGroup.getTenantId().equals(tenantId)) {
-                continue;
-            }
-            if (!ruleGroup.getContractId().equals(contractId)) {
-                continue;
-            }
-            if (ruleGroup.getSubjectName().equals(subjectName)) {
-                return ruleGroup;
-            }
+        HasDirection.Direction getDirection() {
+            return direction;
         }
-        return null;
     }
 }
index cef2b124c916431cce3660c1fd682d2959848f48..cb1b37bc45200db0aa0f54bf16a87a86ef5bfd0e 100644 (file)
@@ -8,10 +8,28 @@
 
 package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util;
 
+import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.ActionCase;
+import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil.ActionInDirection;
+import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil.createClassMap;
+import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil.createPolicyEntry;
+import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil.createSecurityGroupMatch;
+import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil.generateClassMapName;
+import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil.getTenantId;
+import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction.In;
+import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction.Out;
+import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation.CONSUMER;
+import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation.PROVIDER;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.CheckedFuture;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
@@ -20,7 +38,6 @@ import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.P
 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl;
 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.NetconfTransactionCreator;
 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriter;
-import org.opendaylight.groupbasedpolicy.util.IetfModelCodec;
 import org.opendaylight.sfc.provider.api.SfcProviderRenderedPathAPI;
 import org.opendaylight.sfc.provider.api.SfcProviderServiceForwarderAPI;
 import org.opendaylight.sfc.provider.api.SfcProviderServicePathAPI;
@@ -47,7 +64,6 @@ import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev14070
 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.data.plane.locator.locator.type.Ip;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308.Native;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChainBuilder;
@@ -65,10 +81,11 @@ import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.serv
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.Services;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.ServicesBuilder;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.services.ServiceTypeChoice;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.services.service.type.choice.ServiceFunctionBuilder;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.services.service.type.choice.ServiceFunctionForwarderBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.actions.Action;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
@@ -76,59 +93,34 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
-
 public class ServiceChainingUtil {
 
     private static final Logger LOG = LoggerFactory.getLogger(ServiceChainingUtil.class);
     private static final String RSP_SUFFIX = "-gbp-rsp";
     private static final String RSP_REVERSED_SUFFIX = "-gbp-rsp-Reverse";
 
-    static ServiceFunctionPath getServicePath(final List<ParameterValue> params) {
-        if (params == null || params.isEmpty()) {
-            LOG.error("Cannot found service path, parameter value is null");
-            return null;
-        }
-        final Map<String, Object> paramsMap = new HashMap<>();
-        for (ParameterValue value : params) {
-            if (value.getName() == null)
-                continue;
-            if (value.getIntValue() != null) {
-                paramsMap.put(value.getName().getValue(), value.getIntValue());
-            } else if (value.getStringValue() != null) {
-                paramsMap.put(value.getName().getValue(), value.getStringValue());
-            }
-        }
-        String chainName = null;
-        for (String name : paramsMap.keySet()) {
-            if (name.equals(ChainActionDefinition.SFC_CHAIN_NAME)) {
-                chainName = (String) paramsMap.get(name);
-            }
-        }
-        if (chainName == null) {
-            LOG.error("Cannot found service path, chain name is null");
-            return null;
-        }
-        final ServiceFunctionPath serviceFunctionPath = findServiceFunctionPath(new SfcName(chainName));
-        if (serviceFunctionPath == null) {
-            LOG.error("Service function path not found for name {}", chainName);
-            return null;
-        }
-        return serviceFunctionPath;
-    }
-
+    /**
+     * According to input, creates class-maps ({@link ClassMap}) and entries into policy-map ({@link Class}). These
+     * components are created when particular RSP is build by SFC ios-xe renderer. If so, method continues by resolving
+     * first RSP hop in {@link this#resolveRemoteSfcComponents(RenderedServicePath, PolicyWriter)}.
+     *
+     * @param peerEndpoint   - peer endpoint, used to generate status and access to tenant ID
+     * @param sourceSgt      - security group tag of source endpoint
+     * @param destinationSgt - security group tag of destination endpoint
+     * @param actionMap      - contains all info to evaluate correct chain orientation according to endpoint participation
+     * @param context        - contains policy writer
+     * @param dataBroker     - to access odl datastore
+     */
     static void resolveNewChainAction(final PeerEndpoint peerEndpoint, final Sgt sourceSgt,
-                                      final Sgt destinationSgt, final Map<PolicyManagerImpl.ActionCase, Action> actionMap,
+                                      final Sgt destinationSgt, final Map<PolicyManagerImpl.ActionCase, ActionInDirection> actionMap,
                                       final PolicyConfigurationContext context, final DataBroker dataBroker) {
-        final List<Class> policyMapEntries = new ArrayList<>();
-        final Action action = actionMap.get(PolicyManagerImpl.ActionCase.CHAIN);
-        final ServiceFunctionPath servicePath = ServiceChainingUtil.getServicePath(action.getParameterValue());
+        final ActionInDirection actionInDirection = actionMap.get(ActionCase.CHAIN);
+        // Rule action + orientation
+        final Action action = actionInDirection.getAction();
+        final EndpointPolicyParticipation participation = actionInDirection.getParticipation();
+        final Direction direction = actionInDirection.getDirection();
+        // Get service function path
+        final ServiceFunctionPath servicePath = ServiceChainingUtil.findServicePathFromParameterValues(action.getParameterValue());
         if (servicePath == null || servicePath.getName() == null) {
             final String info = String.format("service-path not found (sourceSgt=%s, destinationSgt=%s)",
                     sourceSgt, destinationSgt);
@@ -142,123 +134,290 @@ public class ServiceChainingUtil {
             context.appendUnconfiguredRendererEP(StatusUtil.assembleNotConfigurableRendererEPForPeer(context, peerEndpoint, info));
             return;
         }
-        final RenderedServicePath directPath = ServiceChainingUtil.createRenderedPath(servicePath, tenantId, dataBroker);
-        // Rsp found, create class-map and policy-map entry
-        final String classMapName = PolicyManagerUtil.generateClassMapName(sourceSgt.getValue(), destinationSgt.getValue());
-        final Match match = PolicyManagerUtil.createSecurityGroupMatch(sourceSgt.getValue(), destinationSgt.getValue());
-        final ClassMap classMap = PolicyManagerUtil.createClassMap(classMapName, match);
-        policyMapEntries.add(PolicyManagerUtil.createPolicyEntry(classMapName, directPath, PolicyManagerImpl.ActionCase.CHAIN));
-        RenderedServicePath reversedPath = null;
+        RenderedServicePath renderedServicePath;
+        boolean sfcPartSuccessful = true;
+        // Symmetric chain - create direct or reversed rendered service path in corresponding direction
         if (servicePath.isSymmetric()) {
-            // symmetric path is in opposite direction. Roles of renderer and peer endpoint will invert
-            reversedPath = ServiceChainingUtil.createSymmetricRenderedPath(servicePath, directPath, tenantId, dataBroker);
-            // Reversed Rsp found, create class-map and policy-map entry in opposite direction
-            final String oppositeClassMapName = PolicyManagerUtil.generateClassMapName(destinationSgt.getValue(), sourceSgt.getValue());
-            final Match oppositeMatch = PolicyManagerUtil.createSecurityGroupMatch(destinationSgt.getValue(), sourceSgt.getValue());
-            final ClassMap oppositeClassMap = PolicyManagerUtil.createClassMap(oppositeClassMapName, oppositeMatch);
-            policyMapEntries.add(PolicyManagerUtil.createPolicyEntry(oppositeClassMapName, reversedPath, PolicyManagerImpl.ActionCase.CHAIN));
-            context.getPolicyWriter().cache(oppositeClassMap);
+            if ((participation.equals(PROVIDER) && direction.equals(Out)) ||
+                    (participation.equals(CONSUMER) && direction.equals(In))) {
+                renderedServicePath = ServiceChainingUtil.createRenderedPath(servicePath, tenantId, dataBroker);
+                // Rsp found, create class-map and policy-map entry
+                final String classMapName = generateClassMapName(sourceSgt.getValue(), destinationSgt.getValue());
+                final Match match = createSecurityGroupMatch(sourceSgt.getValue(), destinationSgt.getValue());
+                final ClassMap classMap = createClassMap(classMapName, match);
+                final Class policyMapEntry = createPolicyEntry(classMapName, renderedServicePath, ActionCase.CHAIN);
+                context.getPolicyWriter().cache(classMap);
+                context.getPolicyWriter().cache(policyMapEntry);
+                sfcPartSuccessful = resolveRemoteSfcComponents(renderedServicePath, context.getPolicyWriter());
+            } else {
+                // Direct path required if reversed has to be created
+                final RenderedServicePath directPath = ServiceChainingUtil.createRenderedPath(servicePath, tenantId, dataBroker);
+                // Create reversed path
+                renderedServicePath =
+                        ServiceChainingUtil.createReversedRenderedPath(servicePath, directPath, tenantId, dataBroker);
+                // Rsp found, create class-map and policy-map entry
+                final String classMapName = generateClassMapName(sourceSgt.getValue(), destinationSgt.getValue());
+                final Match match = createSecurityGroupMatch(sourceSgt.getValue(), destinationSgt.getValue());
+                final ClassMap classMap = createClassMap(classMapName, match);
+                final Class policyMapEntry = createPolicyEntry(classMapName, renderedServicePath, ActionCase.CHAIN);
+                context.getPolicyWriter().cache(classMap);
+                context.getPolicyWriter().cache(policyMapEntry);
+                sfcPartSuccessful = resolveRemoteSfcComponents(renderedServicePath, context.getPolicyWriter());
+            }
+        }
+        // Asymmetric chain - create direct path if corresponding direction or skip
+        else if ((participation.equals(PROVIDER) && direction.equals(Out)) ||
+                (participation.equals(CONSUMER) && direction.equals(In))) {
+            renderedServicePath = ServiceChainingUtil.createRenderedPath(servicePath, tenantId, dataBroker);
+            // Rsp found, create class-map and policy-map entry
+            final String classMapName = generateClassMapName(sourceSgt.getValue(), destinationSgt.getValue());
+            final Match match = createSecurityGroupMatch(sourceSgt.getValue(), destinationSgt.getValue());
+            final ClassMap classMap = createClassMap(classMapName, match);
+            final Class policyMapEntry = createPolicyEntry(classMapName, renderedServicePath, ActionCase.CHAIN);
+            context.getPolicyWriter().cache(classMap);
+            context.getPolicyWriter().cache(policyMapEntry);
+            sfcPartSuccessful = resolveRemoteSfcComponents(renderedServicePath, context.getPolicyWriter());
         }
         // Create appropriate service path && remote forwarder
-        final boolean sfcPartSuccessful = setSfcPart(servicePath, directPath, reversedPath, context.getPolicyWriter());
         if (!sfcPartSuccessful) {
             //TODO: extract resolved-rule name
             final String info = String.format("failed during sfc-part execution (sourceSgt=%s, destinationSgt=%s)",
                     sourceSgt, destinationSgt);
             //context.appendUnconfiguredRendererEP(StatusUtil.assembleNotConfigurableRendererEPForPeerAndAction(context, peerEndpoint, info));
-            return;
         }
-        context.getPolicyWriter().cache(classMap);
-        context.getPolicyWriter().cache(policyMapEntries);
     }
 
-    static void removeChainAction(final PeerEndpoint peerEndpoint, final Sgt sourceSgt, final Sgt destinationSgt,
-                                  final Map<PolicyManagerImpl.ActionCase, Action> actionMap, PolicyWriter policyWriter) {
-        final Action action = actionMap.get(PolicyManagerImpl.ActionCase.CHAIN);
-        final ServiceFunctionPath servicePath = ServiceChainingUtil.getServicePath(action.getParameterValue());
+    /**
+     * Removes class-map and policy-map entry in policy between endpoint pair. If necessary, method deletes remote SFC
+     * components.
+     *
+     * @param peerEndpoint    - contains info about tenant ID
+     * @param sourceSgt       - security group tag of source endpoint
+     * @param destinationSgt- security group tag of destination endpoint
+     * @param actionMap       - contains all info to evaluate correct chain orientation according to endpoint participation
+     * @param policyWriter    - used to access ios-xe capable device
+     */
+    static void resolveRemovedChainAction(final PeerEndpoint peerEndpoint, final Sgt sourceSgt, final Sgt destinationSgt,
+                                          final Map<ActionCase, ActionInDirection> actionMap, PolicyWriter policyWriter) {
+        final ActionInDirection actionInDirection = actionMap.get(ActionCase.CHAIN);
+        final Action action = actionInDirection.getAction();
+        final EndpointPolicyParticipation participation = actionInDirection.getParticipation();
+        final Direction direction = actionInDirection.getDirection();
+        final ServiceFunctionPath servicePath = ServiceChainingUtil.findServicePathFromParameterValues(action.getParameterValue());
         if (servicePath == null || servicePath.getName() == null) {
             return;
         }
-        final TenantId tenantId = PolicyManagerUtil.getTenantId(peerEndpoint);
+        final TenantId tenantId = getTenantId(peerEndpoint);
         if (tenantId == null) {
             return;
         }
-        // Cache class-maps, appropriate policy-map entries and service-path (if there are some created by gbp)
-        final List<Class> policyMapEntries = new ArrayList<>();
-        final String classMapName = PolicyManagerUtil.generateClassMapName(sourceSgt.getValue(), destinationSgt.getValue());
-        final ClassMap classMap = PolicyManagerUtil.createClassMap(classMapName, null);
-        policyWriter.cache(classMap);
-        policyMapEntries.add(PolicyManagerUtil.createPolicyEntry(classMapName, null, PolicyManagerImpl.ActionCase.CHAIN));
+        //Symmetric chain
+        if (servicePath.isSymmetric()) {
+            if ((participation.equals(PROVIDER) && direction.equals(Out)) ||
+                    (participation.equals(CONSUMER) && direction.equals(In))) {
+                // Cache class-maps, appropriate policy-map entries and service-chains
+                final String classMapName = PolicyManagerUtil.generateClassMapName(sourceSgt.getValue(), destinationSgt.getValue());
+                final ClassMap classMap = PolicyManagerUtil.createClassMap(classMapName, null);
+                final Class policyMapEntry = PolicyManagerUtil.createPolicyEntry(classMapName, null, PolicyManagerImpl.ActionCase.CHAIN);
+                policyWriter.cache(classMap);
+                policyWriter.cache(policyMapEntry);
 
-        final RspName rspName = generateRspName(servicePath, tenantId);
-        final RenderedServicePath renderedServicePath = SfcProviderRenderedPathAPI.readRenderedServicePath(rspName);
-        final ServiceFunctionForwarder firstHopSff = getFirstHopSff(renderedServicePath);
-        if (firstHopSff != null && firstHopSff.getIpMgmtAddress() != null &&
-                firstHopSff.getIpMgmtAddress().getIpv4Address() != null) {
-            final String sffMgmtIpValue = firstHopSff.getIpMgmtAddress().getIpv4Address().getValue();
-            if (sffMgmtIpValue.equals(policyWriter.getManagementIpAddress())) {
-                // Remove service chain and remote forwarder
-                final ServiceChain serviceChain = findServiceChainToRsp(renderedServicePath);
-                final ServiceFfName remoteForwarder = findRemoteForwarder(firstHopSff);
-                policyWriter.cache(serviceChain);
-                policyWriter.cache(remoteForwarder);
+                final RspName rspName = generateRspName(servicePath, tenantId);
+                final RenderedServicePath renderedServicePath = SfcProviderRenderedPathAPI.readRenderedServicePath(rspName);
+                final ServiceFunctionForwarder firstHopSff = getFirstHopSff(renderedServicePath);
+                if (firstHopSff != null && firstHopSff.getIpMgmtAddress() != null &&
+                        firstHopSff.getIpMgmtAddress().getIpv4Address() != null) {
+                    final String sffMgmtIpValue = firstHopSff.getIpMgmtAddress().getIpv4Address().getValue();
+                    if (!sffMgmtIpValue.equals(policyWriter.getManagementIpAddress())) {
+                        // Remove service chain and remote forwarder
+                        final ServiceChain serviceChain = createServiceChain(renderedServicePath);
+                        final ServiceFfName remoteForwarder = findRemoteForwarder(firstHopSff);
+                        policyWriter.cache(serviceChain);
+                        policyWriter.cache(remoteForwarder);
+                    }
+                }
+            } else {
+                final String oppositeClassMapName = PolicyManagerUtil.generateClassMapName(sourceSgt.getValue(), destinationSgt.getValue());
+                final ClassMap oppositeClassMap = PolicyManagerUtil.createClassMap(oppositeClassMapName, null);
+                final Class policyMapEntry = PolicyManagerUtil.createPolicyEntry(oppositeClassMapName, null, PolicyManagerImpl.ActionCase.CHAIN);
+                policyWriter.cache(oppositeClassMap);
+                policyWriter.cache(policyMapEntry);
+
+                final RspName reversedRspName = generateReversedRspName(servicePath, tenantId);
+                final RenderedServicePath reversedRenderedServicePath = SfcProviderRenderedPathAPI.readRenderedServicePath(reversedRspName);
+                final ServiceFunctionForwarder reversedFirstHopSff = getFirstHopSff(reversedRenderedServicePath);
+                if (reversedFirstHopSff != null && reversedFirstHopSff.getIpMgmtAddress() != null &&
+                        reversedFirstHopSff.getIpMgmtAddress().getIpv4Address() != null) {
+                    final String reversedSffMgmtIpValue = reversedFirstHopSff.getIpMgmtAddress().getIpv4Address().getValue();
+                    if (!reversedSffMgmtIpValue.equals(policyWriter.getManagementIpAddress())) {
+                        // Remove service chain and remote forwarder
+                        final ServiceChain serviceChain = createServiceChain(reversedRenderedServicePath);
+                        final ServiceFfName remoteForwarder = findRemoteForwarder(reversedFirstHopSff);
+                        policyWriter.cache(serviceChain);
+                        policyWriter.cache(remoteForwarder);
+                    }
+                }
             }
-        }
-        if (servicePath.isSymmetric()) {
-            final String oppositeClassMapName = PolicyManagerUtil.generateClassMapName(destinationSgt.getValue(), sourceSgt.getValue());
-            final ClassMap oppositeClassMap = PolicyManagerUtil.createClassMap(oppositeClassMapName, null);
-            policyWriter.cache(oppositeClassMap);
-            policyMapEntries.add(PolicyManagerUtil.createPolicyEntry(oppositeClassMapName, null, PolicyManagerImpl.ActionCase.CHAIN));
+        } else if ((participation.equals(PROVIDER) && direction.equals(Out)) ||
+                (participation.equals(CONSUMER) && direction.equals(In))) {
+            // Asymmetric chain
+            final String classMapName = PolicyManagerUtil.generateClassMapName(sourceSgt.getValue(), destinationSgt.getValue());
+            final ClassMap classMap = PolicyManagerUtil.createClassMap(classMapName, null);
+            final Class policyMapEntry = PolicyManagerUtil.createPolicyEntry(classMapName, null, PolicyManagerImpl.ActionCase.CHAIN);
+            policyWriter.cache(classMap);
+            policyWriter.cache(policyMapEntry);
 
-            final RspName reversedRspName = generateReversedRspName(servicePath, tenantId);
-            final RenderedServicePath reversedRenderedServicePath = SfcProviderRenderedPathAPI.readRenderedServicePath(reversedRspName);
-            final ServiceFunctionForwarder reversedFirstHopSff = getFirstHopSff(reversedRenderedServicePath);
-            if (reversedFirstHopSff != null && reversedFirstHopSff.getIpMgmtAddress() != null &&
-                    reversedFirstHopSff.getIpMgmtAddress().getIpv4Address() != null) {
-                final String reversedSffMgmtIpValue = reversedFirstHopSff.getIpMgmtAddress().getIpv4Address().getValue();
-                if (reversedSffMgmtIpValue.equals(policyWriter.getManagementIpAddress())) {
+            final RspName rspName = generateRspName(servicePath, tenantId);
+            final RenderedServicePath renderedServicePath = SfcProviderRenderedPathAPI.readRenderedServicePath(rspName);
+            final ServiceFunctionForwarder firstHopSff = getFirstHopSff(renderedServicePath);
+            if (firstHopSff != null && firstHopSff.getIpMgmtAddress() != null &&
+                    firstHopSff.getIpMgmtAddress().getIpv4Address() != null) {
+                final String sffMgmtIpValue = firstHopSff.getIpMgmtAddress().getIpv4Address().getValue();
+                if (!sffMgmtIpValue.equals(policyWriter.getManagementIpAddress())) {
                     // Remove service chain and remote forwarder
-                    final ServiceChain serviceChain = findServiceChainToRsp(renderedServicePath);
-                    final ServiceFfName remoteForwarder = findRemoteForwarder(reversedFirstHopSff);
+                    final ServiceChain serviceChain = createServiceChain(renderedServicePath);
+                    final ServiceFfName remoteForwarder = findRemoteForwarder(firstHopSff);
                     policyWriter.cache(serviceChain);
                     policyWriter.cache(remoteForwarder);
                 }
             }
         }
-        policyWriter.cache(policyMapEntries);
     }
 
-    private static ServiceFfName findRemoteForwarder(ServiceFunctionForwarder firstHopSff) {
-        ServiceFfNameBuilder serviceFfNameBuilder = new ServiceFfNameBuilder();
-        serviceFfNameBuilder.setName(firstHopSff.getName().getValue())
-                .setKey(new ServiceFfNameKey(firstHopSff.getName().getValue()));
-        return serviceFfNameBuilder.build();
+    /**
+     * Service-path (netconf) is created on every netconf device, which contains service function belonging to specific
+     * chain. Classifier has to be able to reach first service function forwarder in order to send packet to chain. If
+     * first service function forwarder is present on the same node as classifier, service-path entry should be already
+     * present (created by IOS-XE renderer in SFC) also with appropriate remote SFF if necessary. If first SFF is on
+     * different node, classifier has to create it's own service-path entry with remote SFF.
+     *
+     * @param renderedServicePath classifier has to reach
+     * @param policyWriter        policy entries writer
+     * @return true if everything went good, false otherwise
+     */
+    private static boolean resolveRemoteSfcComponents(final RenderedServicePath renderedServicePath, PolicyWriter policyWriter) {
+        final ServiceFunctionForwarder forwarder = getFirstHopSff(renderedServicePath);
+        if (forwarder == null) {
+            return false;
+        }
+        final SffName sffName = forwarder.getName();
+        if (forwarder.getSffDataPlaneLocator() == null || forwarder.getSffDataPlaneLocator().isEmpty()) {
+            LOG.warn("Service function forwarder {} does not contain data plane locator", sffName.getValue());
+            return false;
+        }
+        // TODO only first dpl resolved
+        final SffDataPlaneLocator sffDataPlaneLocator = forwarder.getSffDataPlaneLocator().get(0);
+        final DataPlaneLocator dataPlaneLocator = sffDataPlaneLocator.getDataPlaneLocator();
+        final LocatorType locatorType = dataPlaneLocator.getLocatorType();
+        if (locatorType != null && locatorType instanceof Ip) {
+            final IpAddress remoteForwarderIpAddress = (((Ip) locatorType).getIp());
+            if (remoteForwarderIpAddress == null || remoteForwarderIpAddress.getIpv4Address() == null) {
+                LOG.warn("Service function forwarder {} data plane locator does not contain ip address", sffName.getValue());
+                return false;
+            }
+            final String remoteForwarderStringIp = remoteForwarderIpAddress.getIpv4Address().getValue();
+            final java.util.Optional<IpAddress> optionalIpMgmtAddress = java.util.Optional.ofNullable(forwarder.getIpMgmtAddress());
+
+            return optionalIpMgmtAddress.map(IpAddress::getIpv4Address)
+                    .map(Ipv4Address::getValue)
+                    .map(addressValue -> {
+                        final ServiceTypeChoice serviceTypeChoice;
+                        if (!addressValue.equals(policyWriter.getManagementIpAddress())) {
+                            // Remote forwarder
+                            final ServiceFfNameBuilder remoteSffBuilder = new ServiceFfNameBuilder();
+                            remoteSffBuilder.setName(sffName.getValue())
+                                    .setKey(new ServiceFfNameKey(sffName.getValue()))
+                                    .setIp(new IpBuilder().setAddress(new Ipv4Address(remoteForwarderStringIp)).build());
+                            policyWriter.cache(remoteSffBuilder.build());
+                            serviceTypeChoice = createForwarderTypeChoice(sffName.getValue());
+                            // Service chain
+                            final List<Services> services = new ArrayList<>();
+                            final ServicesBuilder servicesBuilder = new ServicesBuilder();
+                            servicesBuilder.setServiceIndexId(renderedServicePath.getStartingIndex())
+                                    .setServiceTypeChoice(serviceTypeChoice);
+                            services.add(servicesBuilder.build());
+                            final List<ServicePath> servicePaths = new ArrayList<>();
+                            final ServicePathBuilder servicePathBuilder = new ServicePathBuilder();
+                            servicePathBuilder.setKey(new ServicePathKey(renderedServicePath.getPathId()))
+                                    .setServicePathId(renderedServicePath.getPathId())
+                                    .setConfigServiceChainPathMode(new ConfigServiceChainPathModeBuilder()
+                                            .setServiceIndex(new ServiceIndexBuilder()
+                                                    .setServices(services).build()).build());
+                            servicePaths.add(servicePathBuilder.build());
+                            final ServiceChainBuilder chainBuilder = new ServiceChainBuilder();
+                            chainBuilder.setServicePath(servicePaths);
+                            final ServiceChain serviceChain = chainBuilder.build();
+                            policyWriter.cache(serviceChain);
+                        }
+                        return true;
+                    }).orElseGet(createNegativePathWithLogSupplier(sffName.getValue(),
+                            (value) -> LOG.error("Cannot create remote forwarder, SFF {} does not contain management ip address",
+                                    value))
+                    );
+        }
+        return false;
     }
 
-    private static ServiceFunctionForwarder getFirstHopSff(RenderedServicePath renderedServicePath) {
-        if (renderedServicePath == null || renderedServicePath.getRenderedServicePathHop() == null ||
-                renderedServicePath.getRenderedServicePathHop().isEmpty()) {
+    static ServiceFunctionPath findServicePathFromParameterValues(final List<ParameterValue> params) {
+        if (params == null || params.isEmpty()) {
+            LOG.error("Cannot found service path, parameter value is null");
             return null;
         }
-        final RenderedServicePathHop firstHop = renderedServicePath.getRenderedServicePathHop().get(0);
-        final SffName firstHopSff = firstHop.getServiceFunctionForwarder();
-        if (firstHopSff == null) {
+        final Map<String, Object> paramsMap = new HashMap<>();
+        for (ParameterValue value : params) {
+            if (value.getName() == null)
+                continue;
+            if (value.getIntValue() != null) {
+                paramsMap.put(value.getName().getValue(), value.getIntValue());
+            } else if (value.getStringValue() != null) {
+                paramsMap.put(value.getName().getValue(), value.getStringValue());
+            }
+        }
+        String chainName = null;
+        for (String name : paramsMap.keySet()) {
+            if (name.equals(ChainActionDefinition.SFC_CHAIN_NAME)) {
+                chainName = (String) paramsMap.get(name);
+            }
+        }
+        if (chainName == null) {
+            LOG.error("Cannot found service path, chain name is null");
             return null;
         }
-        return SfcProviderServiceForwarderAPI.readServiceFunctionForwarder(firstHopSff);
+        final ServiceFunctionPath serviceFunctionPath = findServiceFunctionPathFromServiceChainName(new SfcName(chainName));
+        if (serviceFunctionPath == null) {
+            LOG.error("Service function path not found for name {}", chainName);
+            return null;
+        }
+        return serviceFunctionPath;
     }
 
-    private static ServiceChain findServiceChainToRsp(final RenderedServicePath renderedServicePath) {
-        // Construct service chain with key
-        final Long pathId = renderedServicePath.getPathId();
-        final ServicePathBuilder servicePathBuilder = new ServicePathBuilder();
-        final ServiceChainBuilder serviceChainBuilder = new ServiceChainBuilder();
-        servicePathBuilder.setServicePathId(pathId)
-                .setKey(new ServicePathKey(pathId));
-        serviceChainBuilder.setServicePath(Collections.singletonList(servicePathBuilder.build()));
-        return serviceChainBuilder.build();
+    static ServiceFunctionPath findServiceFunctionPathFromServiceChainName(final SfcName chainName) {
+        final ServiceFunctionPaths allPaths = SfcProviderServicePathAPI.readAllServiceFunctionPaths();
+        for (ServiceFunctionPath serviceFunctionPath : allPaths.getServiceFunctionPath()) {
+            if (serviceFunctionPath.getServiceChainName().equals(chainName)) {
+                return serviceFunctionPath;
+            }
+        }
+        return null;
     }
 
+    private static ServiceFfName findRemoteForwarder(ServiceFunctionForwarder firstHopSff) {
+        ServiceFfNameBuilder serviceFfNameBuilder = new ServiceFfNameBuilder();
+        serviceFfNameBuilder.setName(firstHopSff.getName().getValue())
+                .setKey(new ServiceFfNameKey(firstHopSff.getName().getValue()));
+        return serviceFfNameBuilder.build();
+    }
+
+    /**
+     * Creates {@link RenderedServicePath} if not exist. If created, ios-xe renderer in SFC is invoked, so this method
+     * has to wait till SFC part is done to prevent transaction collisions in {@link this#checkRspManagerStatus(RspName,
+     * DataBroker)}
+     *
+     * @param sfp        - path used to create RSP
+     * @param tenantId   - used to generate RSP name according to GBP standards
+     * @param dataBroker - data provider to access odl controller
+     * @return read/created RSP
+     */
     static RenderedServicePath createRenderedPath(final ServiceFunctionPath sfp, final TenantId tenantId,
                                                   final DataBroker dataBroker) {
         RenderedServicePath renderedServicePath;
@@ -276,12 +435,23 @@ public class ServiceChainingUtil {
                 .build();
         renderedServicePath = SfcProviderRenderedPathAPI.createRenderedServicePathAndState(sfp, input);
         LOG.info("Rendered service path {} created", rspName.getValue());
-        checkSfcRspStatus(rspName, dataBroker);
+        checkRspManagerStatus(rspName, dataBroker);
         return renderedServicePath;
     }
 
-    static RenderedServicePath createSymmetricRenderedPath(final ServiceFunctionPath sfp, final RenderedServicePath rsp,
-                                                           final TenantId tenantId, final DataBroker dataBroker) {
+    /**
+     * Creates reversed {@link RenderedServicePath} if not exist. To be successful, direct path has to exist.
+     * If created, ios-xe renderer in SFC is invoked, so this method has to wait till SFC part is done to prevent
+     * transaction collisions in {@link this#checkRspManagerStatus(RspName, DataBroker)}
+     *
+     * @param sfp        - path used to create RSP
+     * @param rsp        - appropriate direct RSP, used when the reversed path is created
+     * @param tenantId   - used to generate RSP name according to GBP standards
+     * @param dataBroker - data provider to access odl controller
+     * @return read/created RSP
+     */
+    static RenderedServicePath createReversedRenderedPath(final ServiceFunctionPath sfp, final RenderedServicePath rsp,
+                                                          final TenantId tenantId, final DataBroker dataBroker) {
         RenderedServicePath reversedRenderedPath;
         // Try to read existing RSP
         final RspName rspName = generateReversedRspName(sfp, tenantId);
@@ -292,26 +462,25 @@ public class ServiceChainingUtil {
         LOG.info("Reversed rendered service path with name {} not found, creating a new one ..", rspName.getValue());
         reversedRenderedPath = SfcProviderRenderedPathAPI.createReverseRenderedServicePathEntry(rsp);
         LOG.info("Rendered service path {} created", rspName.getValue());
-        checkSfcRspStatus(rspName, dataBroker);
+        checkRspManagerStatus(rspName, dataBroker);
         return reversedRenderedPath;
     }
 
-    static ServiceFunctionPath findServiceFunctionPath(final SfcName chainName) {
-        final ServiceFunctionPaths allPaths = SfcProviderServicePathAPI.readAllServiceFunctionPaths();
-        for (ServiceFunctionPath serviceFunctionPath : allPaths.getServiceFunctionPath()) {
-            if (serviceFunctionPath.getServiceChainName().equals(chainName)) {
-                return serviceFunctionPath;
-            }
-        }
-        return null;
-    }
-
-    private static RspName generateRspName(final ServiceFunctionPath serviceFunctionPath, final TenantId tenantId) {
-        return new RspName(serviceFunctionPath.getName().getValue() + tenantId.getValue() + RSP_SUFFIX);
+    static ServiceTypeChoice createForwarderTypeChoice(final String forwarderName) {
+        final ServiceFunctionForwarderBuilder sffBuilder = new ServiceFunctionForwarderBuilder();
+        sffBuilder.setServiceFunctionForwarder(forwarderName);
+        return sffBuilder.build();
     }
 
-    private static RspName generateReversedRspName(final ServiceFunctionPath serviceFunctionPath, final TenantId tenantId) {
-        return new RspName(serviceFunctionPath.getName().getValue() + tenantId.getValue() + RSP_REVERSED_SUFFIX);
+    private static ServiceChain createServiceChain(final RenderedServicePath renderedServicePath) {
+        // Construct service chain with key
+        final Long pathId = renderedServicePath.getPathId();
+        final ServicePathBuilder servicePathBuilder = new ServicePathBuilder();
+        final ServiceChainBuilder serviceChainBuilder = new ServiceChainBuilder();
+        servicePathBuilder.setServicePathId(pathId)
+                .setKey(new ServicePathKey(pathId));
+        serviceChainBuilder.setServicePath(Collections.singletonList(servicePathBuilder.build()));
+        return serviceChainBuilder.build();
     }
 
     private static <T> Supplier<Boolean> createNegativePathWithLogSupplier(final T value, final Consumer<T> logCommand) {
@@ -322,139 +491,33 @@ public class ServiceChainingUtil {
         };
     }
 
-    static boolean setSfcPart(final ServiceFunctionPath serviceFunctionPath, final RenderedServicePath renderedServicePath,
-                              final RenderedServicePath reversedRenderedServicePath, PolicyWriter policyWriter) {
-        boolean outcome = true;
-        // Direct path
-        final java.util.Optional<RenderedServicePath> renderedServicePathSafe = java.util.Optional.ofNullable(renderedServicePath);
-        if (renderedServicePathSafe.isPresent()) {
-            if (renderedServicePath.getRenderedServicePathHop() != null
-                    && !renderedServicePath.getRenderedServicePathHop().isEmpty()) {
-                if (!resolveRenderedServicePath(renderedServicePath, policyWriter)) {
-                    outcome = false;
-                }
-            } else {
-                LOG.warn("Rendered service path {} does not contain any hop",
-                        renderedServicePathSafe.map(RenderedServicePath::getName).map(RspName::getValue).orElse("n/a"));
-                outcome = false;
-            }
-        } else {
-            LOG.warn("Rendered service path is null");
-            outcome = false;
-        }
-        if (serviceFunctionPath.isSymmetric()) {
-            // Reversed path
-            final java.util.Optional<RenderedServicePath> reversedRenderedServicePathSafe = java.util.Optional.ofNullable(reversedRenderedServicePath);
-            if (reversedRenderedServicePathSafe.isPresent()) {
-                if (reversedRenderedServicePath.getRenderedServicePathHop() != null
-                        && !reversedRenderedServicePath.getRenderedServicePathHop().isEmpty()) {
-                    if (!resolveRenderedServicePath(reversedRenderedServicePath, policyWriter)) {
-                        outcome = false;
-                    }
-                } else {
-                    LOG.warn("Rendered service path {} does not contain any hop",
-                            reversedRenderedServicePathSafe.map(RenderedServicePath::getName).map(RspName::getValue).orElse("n/a"));
-                    outcome = false;
-                }
-            } else {
-                LOG.warn("Reversed rendered service path is null");
-                outcome = false;
-            }
+    private static ServiceFunctionForwarder getFirstHopSff(RenderedServicePath renderedServicePath) {
+        if (renderedServicePath == null || renderedServicePath.getRenderedServicePathHop() == null ||
+                renderedServicePath.getRenderedServicePathHop().isEmpty()) {
+            return null;
         }
-        return outcome;
-    }
-
-    private static boolean resolveRenderedServicePath(final RenderedServicePath renderedServicePath, PolicyWriter policyWriter) {
         final RenderedServicePathHop firstHop = renderedServicePath.getRenderedServicePathHop().get(0);
-        if (firstHop == null) {
-            return false;
-        }
-        final SffName sffName = firstHop.getServiceFunctionForwarder();
-
-        // Create remote forwarder if necessary
-        final java.util.Optional<ServiceFunctionForwarder> serviceFunctionForwarder = java.util.Optional.ofNullable(
-                SfcProviderServiceForwarderAPI.readServiceFunctionForwarder(sffName));
-        if (!serviceFunctionForwarder.isPresent()) {
-            LOG.warn("Service function forwarder {} does not exist", sffName.getValue());
-            return false;
-        }
-        final ServiceFunctionForwarder forwarder = serviceFunctionForwarder.get();
-        if (forwarder.getSffDataPlaneLocator() == null || forwarder.getSffDataPlaneLocator().isEmpty()) {
-            LOG.warn("Service function forwarder {} does not contain data plane locator", sffName.getValue());
-            return false;
-        }
-        // TODO only first dpl resolved
-        final SffDataPlaneLocator sffDataPlaneLocator = forwarder.getSffDataPlaneLocator().get(0);
-        final DataPlaneLocator dataPlaneLocator = sffDataPlaneLocator.getDataPlaneLocator();
-        final LocatorType locatorType = dataPlaneLocator.getLocatorType();
-        if (locatorType != null && locatorType instanceof Ip) {
-            final IpAddress remoteForwarderIpAddress = IetfModelCodec.ipAddress2010(((Ip) locatorType).getIp());
-            if (remoteForwarderIpAddress == null || remoteForwarderIpAddress.getIpv4Address() == null) {
-                LOG.warn("Service function forwarder {} data plane locator does not contain ip address", sffName.getValue());
-                return false;
-            }
-            final String remoteForwarderStringIp = remoteForwarderIpAddress.getIpv4Address().getValue();
-            return serviceFunctionForwarder.map(sff -> java.util.Optional.ofNullable(sff.getIpMgmtAddress())
-                    .map(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress::getIpv4Address)
-                    .map(Ipv4Address::getValue)
-                    .map(addressValue -> {
-                        final ServiceTypeChoice serviceTypeChoice;
-                        if (!addressValue.equals(policyWriter.getManagementIpAddress())) {
-                            final ServiceFfNameBuilder remoteSffBuilder = new ServiceFfNameBuilder();
-                            remoteSffBuilder.setName(sffName.getValue())
-                                    .setKey(new ServiceFfNameKey(sffName.getValue()))
-                                    .setIp(new IpBuilder().setAddress(new Ipv4Address(remoteForwarderStringIp)).build());
-                            policyWriter.cache(remoteSffBuilder.build());
-                            serviceTypeChoice = forwarderTypeChoice(sffName.getValue());
-                            // Service chain
-                            final List<Services> services = new ArrayList<>();
-                            final ServicesBuilder servicesBuilder = new ServicesBuilder();
-                            servicesBuilder.setServiceIndexId(renderedServicePath.getStartingIndex())
-                                    .setServiceTypeChoice(serviceTypeChoice);
-                            services.add(servicesBuilder.build());
-                            final List<ServicePath> servicePaths = new ArrayList<>();
-                            final ServicePathBuilder servicePathBuilder = new ServicePathBuilder();
-                            servicePathBuilder.setKey(new ServicePathKey(renderedServicePath.getPathId()))
-                                    .setServicePathId(renderedServicePath.getPathId())
-                                    .setConfigServiceChainPathMode(new ConfigServiceChainPathModeBuilder()
-                                            .setServiceIndex(new ServiceIndexBuilder()
-                                                    .setServices(services).build()).build());
-                            servicePaths.add(servicePathBuilder.build());
-                            final ServiceChainBuilder chainBuilder = new ServiceChainBuilder();
-                            chainBuilder.setServicePath(servicePaths);
-                            final ServiceChain serviceChain = chainBuilder.build();
-                            policyWriter.cache(serviceChain);
-                        }
-                        return true;
-                    }).orElseGet(createNegativePathWithLogSupplier(sffName.getValue(),
-                            (value) -> LOG.error("Cannot create remote forwarder, SFF {} does not contain management ip address",
-                                    value))
-                    )
-            ).orElseGet(createNegativePathWithLogSupplier(sffName.getValue(),
-                    (value) -> LOG.error("Sff with name {} does not exist", value))
-            );
+        final SffName firstHopSff = firstHop.getServiceFunctionForwarder();
+        if (firstHopSff == null) {
+            return null;
         }
-        return false;
+        return SfcProviderServiceForwarderAPI.readServiceFunctionForwarder(firstHopSff);
     }
 
-    static ServiceTypeChoice forwarderTypeChoice(final String forwarderName) {
-        final ServiceFunctionForwarderBuilder sffBuilder = new ServiceFunctionForwarderBuilder();
-        sffBuilder.setServiceFunctionForwarder(forwarderName);
-        return sffBuilder.build();
+    private static RspName generateRspName(final ServiceFunctionPath serviceFunctionPath, final TenantId tenantId) {
+        return new RspName(serviceFunctionPath.getName().getValue() + "-" + tenantId.getValue() + RSP_SUFFIX);
     }
 
-    static ServiceTypeChoice functionTypeChoice(final String functionName) {
-        final ServiceFunctionBuilder sfBuilder = new ServiceFunctionBuilder();
-        sfBuilder.setServiceFunction(functionName);
-        return sfBuilder.build();
+    private static RspName generateReversedRspName(final ServiceFunctionPath serviceFunctionPath, final TenantId tenantId) {
+        return new RspName(serviceFunctionPath.getName().getValue() + "-" + tenantId.getValue() + RSP_REVERSED_SUFFIX);
     }
 
-    private static void checkSfcRspStatus(final RspName rspName, final DataBroker dataBroker) {
+    private static void checkRspManagerStatus(final RspName rspName, final DataBroker dataBroker) {
         /** TODO A better way to do this is to register listener and wait for notification than using hardcoded timeout
          *  with Thread.sleep(). Example in class BridgeDomainManagerImpl
          */
         ConfiguredRenderedPath renderedPath = null;
-        LOG.info("Waiting for SFC to configure path {} ...", rspName.getValue());
+        LOG.debug("Waiting for SFC to configure path {} ...", rspName.getValue());
 
         byte attempt = 0;
         do {
@@ -493,7 +556,7 @@ public class ServiceChainingUtil {
             } else if (renderedPath.getPathStatus().equals(ConfiguredRenderedPath.PathStatus.Failure)) {
                 LOG.warn("SFC failed to configure rsp");
             } else if (renderedPath.getPathStatus().equals(ConfiguredRenderedPath.PathStatus.Success)) {
-                LOG.info("RSP {} configured by SFC", rspName.getValue());
+                LOG.debug("RSP {} configured by SFC", rspName.getValue());
                 try {
                     Thread.sleep(5000); // Just for sure, maybe will be safe to remove this
                 } catch (InterruptedException e) {
index 034da8ac64de41ef0f4794217752d9a124d2fbcd..6532cdb817ebca9208fa8bd0a9ce0795a896b794 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer;
 
+import java.util.HashSet;
+import java.util.Set;
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.Futures;
@@ -21,10 +23,6 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
 public class PolicyWriter {
 
     private static final Logger LOG = LoggerFactory.getLogger(PolicyWriter.class);
@@ -54,26 +52,10 @@ public class PolicyWriter {
         this.policyMapName = Preconditions.checkNotNull(policyMapName);
     }
 
-    public void cache(ClassMap classMap) {
-        classMapEntries.add(classMap);
-    }
-
-    public void cache(List<Class> policyMapEntries) {
-        this.policyMapEntries.addAll(policyMapEntries);
-    }
-
-    public void cache(ServiceFfName remoteForwarder) {
-        remoteForwarders.add(remoteForwarder);
-    }
-
-    public void cache(ServiceChain serviceChain) {
-        serviceChains.add(serviceChain);
-    }
-
     public CheckedFuture<Boolean, TransactionCommitFailedException> commitToDatastore() {
-        LOG.info("Configuring policy on node {} ... ", nodeId.getValue());
+        LOG.debug("Configuring policy on node {}, interface {} ... ", nodeId.getValue(), interfaceName);
         if (policyMapEntries.isEmpty()) {
-            LOG.info("Policy map {} is empty, skipping", policyMapName);
+            LOG.debug("Policy map {} is empty, skipping", policyMapName);
             return Futures.immediateCheckedFuture(true);
         }
         // SFC
@@ -84,40 +66,55 @@ public class PolicyWriter {
         boolean policyMapResult = PolicyWriterUtil.writePolicyMap(policyMapName, policyMapEntries, nodeId, mountpoint);
         boolean interfaceResult = PolicyWriterUtil.writeInterface(policyMapName, interfaceName, nodeId, mountpoint);
         // Result
-        LOG.info("Policy configuration on node {} completed", nodeId.getValue());
+        LOG.info("Policy-map created on node {}, interface {}", nodeId.getValue(), interfaceName);
         return Futures.immediateCheckedFuture(classMapResult && policyMapResult && interfaceResult && remoteResult
                 && servicePathsResult);
     }
 
     public CheckedFuture<Boolean, TransactionCommitFailedException> removeFromDatastore() {
-        LOG.info("Removing policy from node {} ... ", nodeId.getValue());
+        LOG.debug("Removing policy from node {}, interface {} ... ", nodeId.getValue(), interfaceName);
         if (policyMapEntries.isEmpty()) {
-            LOG.info("Policy map {} is empty, nothing to remove", policyMapName);
+            LOG.debug("Policy map {} is empty, nothing to remove", policyMapName);
             return Futures.immediateCheckedFuture(true);
         }
         // GBP - maintain order!
         boolean policyMapEntriesResult = PolicyWriterUtil.removePolicyMapEntries(policyMapName, policyMapEntries,
                 nodeId, mountpoint);
         boolean classMapResult = PolicyWriterUtil.removeClassMaps(classMapEntries, nodeId, mountpoint);
-        // TODO remove class map?
         // SFC
-        boolean servicePathsResult = PolicyWriterUtil.removeServicePaths(serviceChains, nodeId, mountpoint);
         boolean remoteSffResult = PolicyWriterUtil.removeRemote(remoteForwarders, nodeId, mountpoint);
+        boolean servicePathsResult = PolicyWriterUtil.removeServicePaths(serviceChains, nodeId, mountpoint);
         // Result
-        LOG.info("Policy removed from node {}", nodeId.getValue());
+        LOG.info("Policy-map removed from node {}, interface {}", nodeId.getValue(), interfaceName);
         return Futures.immediateCheckedFuture(classMapResult && policyMapEntriesResult && servicePathsResult
-            && remoteSffResult);
+                && remoteSffResult);
+    }
+
+    public void cache(ClassMap classMap) {
+        classMapEntries.add(classMap);
+    }
+
+    public void cache(Class policyMapEntry) {
+        this.policyMapEntries.add(policyMapEntry);
+    }
+
+    public void cache(ServiceFfName remoteForwarder) {
+        remoteForwarders.add(remoteForwarder);
+    }
+
+    public void cache(ServiceChain serviceChain) {
+        serviceChains.add(serviceChain);
     }
 
     public String getManagementIpAddress() {
         return managementIpAddress;
     }
 
-    public DataBroker getCurrentMountpoint() {
+    public DataBroker getMountpoint() {
         return mountpoint;
     }
 
-    public NodeId getCurrentNodeId() {
+    public NodeId getNodeId() {
         return nodeId;
     }
 }
index ec71181d33a010e5ed6d5e62c4187366fa229b4e..a3c7056844564add63dc4164cf3800a5ca75a5c0 100644 (file)
@@ -33,10 +33,8 @@ import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._interface.Gigabit
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._interface.GigabitEthernetKey;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.ClassKey;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServiceFunctionForwarder;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePath;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePathKey;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.Local;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfName;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfNameKey;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
@@ -77,7 +75,7 @@ class PolicyWriterUtil {
             if (checkWritten(readTransaction, classMapIid) == null) {
                 return false;
             }
-            LOG.info("Created class-map {} on node {}", entry.getName(), nodeId.getValue());
+            LOG.trace("Created class-map {} on node {}", entry.getName(), nodeId.getValue());
         }
         return true;
     }
@@ -106,7 +104,7 @@ class PolicyWriterUtil {
             }
             final ReadOnlyTransaction readTransaction = optionalReadTransaction.get();
             result = checkRemoved(readTransaction, classMapIid);
-            LOG.info("Class-map {} removed from node {}", entry.getName(), nodeId.getValue());
+            LOG.trace("Class-map {} removed from node {}", entry.getName(), nodeId.getValue());
         }
         return result;
     }
@@ -134,7 +132,7 @@ class PolicyWriterUtil {
         if (checkWritten(readTransaction, policyMapIid) == null) {
             return false;
         }
-        LOG.info("Created policy-map {} on node {}", policyMap.getName(), nodeId.getValue());
+        LOG.trace("Created policy-map {} on node {}", policyMap.getName(), nodeId.getValue());
         return true;
     }
 
@@ -153,7 +151,7 @@ class PolicyWriterUtil {
             final WriteTransaction writeTransaction = optionalWriteTransaction.get();
             final InstanceIdentifier policyMapEntryIid = policyMapEntryInstanceIdentifier(policyMapName, entry.getName());
             if (deleteTransaction(writeTransaction, policyMapEntryIid)) {
-                LOG.info("Policy map entry {} removed from node {}", entry.getName(), nodeId.getValue());
+                LOG.trace("Policy map entry {} removed from node {}", entry.getName(), nodeId.getValue());
             }
         }
         return true;
@@ -171,7 +169,7 @@ class PolicyWriterUtil {
         final ServicePolicy servicePolicy = PolicyManagerUtil.createServicePolicy(policyMapName, Direction.Input);
         final InstanceIdentifier<ServicePolicy> servicePolicyIid = interfaceInstanceIdentifier(interfaceName);
         writeMergeTransaction(writeTransaction, servicePolicyIid, servicePolicy);
-        LOG.info("Service-policy interface {}, bound to policy-map {} created on  node {}",
+        LOG.trace("Service-policy interface {}, bound to policy-map {} created on  node {}",
                 interfaceName, policyMapName, nodeId.getValue());
         return true;
     }
@@ -191,7 +189,7 @@ class PolicyWriterUtil {
             final WriteTransaction writeTransaction = optionalWriteTransaction.get();
             final InstanceIdentifier<ServiceFfName> forwarderIid = remoteSffInstanceIdentifier(forwarder);
             writeMergeTransaction(writeTransaction, forwarderIid, forwarder);
-            LOG.info("Remote forwarder {} created on node {}", forwarder.getName(), nodeId.getValue());
+            LOG.trace("Remote forwarder {} created on node {}", forwarder.getName(), nodeId.getValue());
         }
         return true;
     }
@@ -211,7 +209,7 @@ class PolicyWriterUtil {
             final WriteTransaction writeTransaction = optionalWriteTransaction.get();
             final InstanceIdentifier<ServiceFfName> forwarderIid = remoteSffInstanceIdentifier(forwarder);
             deleteTransaction(writeTransaction, forwarderIid);
-            LOG.info("Remote forwarder {} removed from node {}", forwarder.getName(), nodeId.getValue());
+            LOG.trace("Remote forwarder {} removed from node {}", forwarder.getName(), nodeId.getValue());
         }
         return true;
     }
@@ -229,7 +227,7 @@ class PolicyWriterUtil {
                 final WriteTransaction writeTransaction = optionalWriteTransaction.get();
                 final InstanceIdentifier<ServicePath> servicePathIid = servicePathInstanceIdentifier(entry.getKey());
                 writeMergeTransaction(writeTransaction, servicePathIid, entry);
-                LOG.info("Service path with ID: {} created on node {}", entry.getServicePathId(), nodeId.getValue());
+                LOG.trace("Service path with ID: {} created on node {}", entry.getServicePathId(), nodeId.getValue());
             }
         }
         return true;
@@ -255,7 +253,7 @@ class PolicyWriterUtil {
                 final WriteTransaction writeTransaction = optionalWriteTransaction.get();
                 final InstanceIdentifier<ServicePath> servicePathIid = servicePathInstanceIdentifier(servicePath.getKey());
                 if (deleteTransaction(writeTransaction, servicePathIid)) {
-                    LOG.info("Service-path with ID: {} removed from node {}", servicePath.getServicePathId(),
+                    LOG.trace("Service-path with ID: {} removed from node {}", servicePath.getServicePathId(),
                             nodeId.getValue());
                 }
             }
@@ -288,13 +286,6 @@ class PolicyWriterUtil {
                 .build();
     }
 
-    private static InstanceIdentifier<Local> localSffInstanceIdentifier() {
-        return InstanceIdentifier.builder(Native.class)
-                .child(org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain.class)
-                .child(ServiceFunctionForwarder.class)
-                .child(Local.class).build();
-    }
-
     private static InstanceIdentifier<ServiceFfName> remoteSffInstanceIdentifier(final ServiceFfName sffName) {
         return InstanceIdentifier.builder(Native.class)
                 .child(org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain.class)
index 20bdaf0c6699a18042d699e4c77bf299e6554ffa..c58e86382f299e43372a930e646f6cef69100bae 100644 (file)
@@ -263,7 +263,7 @@ public class PolicyManagerImplTest {
         when(nodeManager.getNodeIdByMountpointIid(eq(createMountpointIid()))).thenReturn(nodeId);
         when(nodeManager.getNodeManagementIpByMountPointIid(eq(createMountpointIid()))).thenReturn(ipAddress);
         ServiceFunctionPath sfp = createServiceFunctionPath();
-        stub(method(ServiceChainingUtil.class, "getServicePath")).toReturn(sfp);
+        stub(method(ServiceChainingUtil.class, "findServicePathFromParameterValues")).toReturn(sfp);
         RenderedServicePath rsp = createRenderedServicePath();
         stub(method(ServiceChainingUtil.class, "createRenderedPath")).toReturn(rsp);
         ServiceFunctionForwarder serviceFunctionForwarder = createServiceForwarder();
index 2e5b5a78329c5e57a48fb0cbe45b9aa4cd3428e6..ac248b9bf19c84a35137d2f9a6c397c31890dbb9 100644 (file)
@@ -90,7 +90,7 @@ public class PolicyManagerUtilTest {
         Mockito.when(roTx.read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(ServiceFunctionPaths.class)))
                 .thenReturn(Futures.immediateCheckedFuture(Optional.of(sfPaths)));
 
-        final ServiceFunctionPath servicePath = ServiceChainingUtil.getServicePath(Collections.singletonList(paramValueSfc));
+        final ServiceFunctionPath servicePath = ServiceChainingUtil.findServicePathFromParameterValues(Collections.singletonList(paramValueSfc));
         Assert.assertEquals(serviceFunctionPath, servicePath);
     }
 
@@ -107,7 +107,7 @@ public class PolicyManagerUtilTest {
                 dataBroker);
         Assert.assertEquals(renderedSP, renderedPath);
         final InstanceIdentifier<RenderedServicePath> ii = rendererServicePathIICaptor.getValue();
-        Assert.assertEquals("sfp-name-01tenant-id-01-gbp-rsp", ii.firstKeyOf(RenderedServicePath.class).getName().getValue());
+        Assert.assertEquals("sfp-name-01-tenant-id-01-gbp-rsp", ii.firstKeyOf(RenderedServicePath.class).getName().getValue());
     }
 
     @Test
@@ -120,11 +120,11 @@ public class PolicyManagerUtilTest {
                 .thenReturn(Futures.immediateCheckedFuture(Optional.of(renderedServicePath)));
 
 
-        final RenderedServicePath symmetricRenderedPath = ServiceChainingUtil.createSymmetricRenderedPath(
+        final RenderedServicePath symmetricRenderedPath = ServiceChainingUtil.createReversedRenderedPath(
                 serviceFunctionPath, renderedServicePath, tenantId, dataBroker);
         Assert.assertEquals(renderedServicePath, symmetricRenderedPath);
         final InstanceIdentifier<RenderedServicePath> ii = rendererServicePathIICaptor.getValue();
-        Assert.assertEquals("sfp-name-01tenant-id-02-gbp-rsp-Reverse", ii.firstKeyOf(RenderedServicePath.class).getName().getValue());
+        Assert.assertEquals("sfp-name-01-tenant-id-02-gbp-rsp-Reverse", ii.firstKeyOf(RenderedServicePath.class).getName().getValue());
     }
 
     @Test
index 8eb8b0177cfa396da7017325ec8f9cbea6e41492..c932bd79ab06b94481eaa679e5767b35521f902f 100644 (file)
@@ -19,6 +19,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil.ActionInDirection;
 import org.mockito.Captor;
 import org.mockito.Matchers;
 import org.mockito.Mock;
@@ -48,13 +49,14 @@ import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev1407
 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarder.base.SffDataPlaneLocatorBuilder;
 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarder.base.sff.data.plane.locator.DataPlaneLocatorBuilder;
 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarderBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarderKey;
 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.cisco.params.xml.ns.yang.sfc.sl.rev140701.data.plane.locator.locator.type.IpBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+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.ios.rev160308._native.ClassMap;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain;
 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class;
@@ -68,14 +70,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.IpPrefixType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection;
 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.renderer.rev151103.EndpointPolicyParticipation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipationBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.actions.Action;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.actions.ActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
@@ -113,7 +116,7 @@ public class ServiceChainingUtilTest {
     @Captor
     private ArgumentCaptor<RenderedServicePath> rspCaptor;
     @Captor
-    private ArgumentCaptor<List<Class>> listClassCaptor;
+    private ArgumentCaptor<Class> listClassCaptor;
     @Captor
     private ArgumentCaptor<ClassMap> classMapCaptor;
     @Mock
@@ -128,12 +131,12 @@ public class ServiceChainingUtilTest {
     @Before
     public void setUp() throws Exception {
         final NodeId currentNodeId = new NodeId("unit-node-01");
-        Mockito.when(policyWriter.getCurrentNodeId()).thenReturn(currentNodeId);
+        Mockito.when(policyWriter.getNodeId()).thenReturn(currentNodeId);
 
         final String managementIpAddress = "1.2.3.5";
         Mockito.when(policyWriter.getManagementIpAddress()).thenReturn(managementIpAddress);
 
-        Mockito.when(policyWriter.getCurrentMountpoint()).thenReturn(dataBroker);
+        Mockito.when(policyWriter.getMountpoint()).thenReturn(dataBroker);
         Mockito.when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx);
 
         policyConfigurationContext = new PolicyConfigurationContext();
@@ -150,7 +153,7 @@ public class ServiceChainingUtilTest {
 
         stub(method(SfcProviderServicePathAPI.class, "readAllServiceFunctionPaths")).toReturn(sfcPaths);
 
-        final ServiceFunctionPath servicePath = ServiceChainingUtil.getServicePath(Lists.newArrayList(
+        final ServiceFunctionPath servicePath = ServiceChainingUtil.findServicePathFromParameterValues(Lists.newArrayList(
                 createParameterValue("sfc-chain-name", sfcNameValue)
         ));
         Assert.assertEquals(sfcPath, servicePath);
@@ -165,7 +168,7 @@ public class ServiceChainingUtilTest {
         final PeerEndpoint peerEndpoint = createPeerEndpoint();
         final Sgt sourceSgt = new Sgt(1);
         final Sgt destinationSgt = new Sgt(2);
-        final Map<PolicyManagerImpl.ActionCase, Action> actionMap = createActionMap();
+        final Map<PolicyManagerImpl.ActionCase, PolicyManagerUtil.ActionInDirection> actionMap = createActionMap();
         final String classMapName = "unit-class-map-name-01";
 
         final String sfcNameValue = "123";
@@ -178,14 +181,10 @@ public class ServiceChainingUtilTest {
 
         final RenderedServicePath rsp = createRsp("unit-rsp-02");
         stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(rsp);
-        stub(method(ServiceChainingUtil.class, "setSfcPart")).toReturn(true);
 
         ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, policyConfigurationContext, dataBroker);
 
-        Mockito.verify(policyWriter).cache(classMapCaptor.capture());
-        Mockito.verify(policyWriter).cache(listClassCaptor.capture());
         Mockito.verifyNoMoreInteractions(policyWriter);
-        Assert.assertEquals(1, listClassCaptor.getValue().size());
     }
 
     @Test
@@ -193,7 +192,7 @@ public class ServiceChainingUtilTest {
         final PeerEndpoint peerEndpoint = createPeerEndpoint();
         final Sgt sourceSgt = new Sgt(1);
         final Sgt destinationSgt = new Sgt(2);
-        final Map<PolicyManagerImpl.ActionCase, Action> actionMap = createActionMap();
+        final Map<PolicyManagerImpl.ActionCase, ActionInDirection> actionMap = createActionMap();
         final String classMapName = "unit-class-map-name-01";
 
         final String sfcNameValue = "123";
@@ -201,19 +200,23 @@ public class ServiceChainingUtilTest {
         final ServiceFunctionPaths sfcPaths = new ServiceFunctionPathsBuilder()
                 .setServiceFunctionPath(Collections.singletonList(sfcPath))
                 .build();
+        final org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder serviceFunctionForwarder
+                = new ServiceFunctionForwarderBuilder()
+                .setName(new SffName("sff"))
+                .setKey(new ServiceFunctionForwarderKey(new SffName("sff"))).build();
 
         stub(method(SfcProviderServicePathAPI.class, "readAllServiceFunctionPaths")).toReturn(sfcPaths);
 
         final RenderedServicePath rsp = createRsp("unit-rsp-02");
         stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(rsp);
-        stub(method(ServiceChainingUtil.class, "setSfcPart")).toReturn(true);
+        stub(method(SfcProviderServiceForwarderAPI.class, "readServiceFunctionForwarder")).toReturn(serviceFunctionForwarder);
 
         ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, policyConfigurationContext, dataBroker);
 
-        Mockito.verify(policyWriter, Mockito.times(2)).cache(classMapCaptor.capture());
+        Mockito.verify(policyWriter).cache(classMapCaptor.capture());
         Mockito.verify(policyWriter).cache(listClassCaptor.capture());
         Mockito.verifyNoMoreInteractions(policyWriter);
-        Assert.assertEquals(2, listClassCaptor.getValue().size());
+        Assert.assertNotNull(listClassCaptor.getValue());
     }
 
     @Test
@@ -221,7 +224,7 @@ public class ServiceChainingUtilTest {
         final PeerEndpoint peerEndpoint = createPeerEndpoint();
         final Sgt sourceSgt = new Sgt(1);
         final Sgt destinationSgt = new Sgt(2);
-        final Map<PolicyManagerImpl.ActionCase, Action> actionMap = createActionMap();
+        final Map<PolicyManagerImpl.ActionCase, ActionInDirection> actionMap = createActionMap();
         final String classMapName = "unit-class-map-name-01";
 
         final String sfcNameValue = "123";
@@ -229,13 +232,17 @@ public class ServiceChainingUtilTest {
         final ServiceFunctionPaths sfcPaths = new ServiceFunctionPathsBuilder()
                 .setServiceFunctionPath(Collections.singletonList(sfcPath))
                 .build();
+        final org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder serviceFunctionForwarder
+                = new ServiceFunctionForwarderBuilder()
+                .setName(new SffName("sff"))
+                .setKey(new ServiceFunctionForwarderKey(new SffName("sff"))).build();
 
         stub(method(SfcProviderServicePathAPI.class, "readAllServiceFunctionPaths")).toReturn(sfcPaths);
 
         final RenderedServicePath rsp = createRsp("unit-rsp-02");
         stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(rsp);
-        stub(method(ServiceChainingUtil.class, "setSfcPart")).toReturn(true);
-        stub(method(ServiceChainingUtil.class, "createSymmetricRenderedPath")).toReturn(null);
+        stub(method(ServiceChainingUtil.class, "createReversedRenderedPath")).toReturn(null);
+        stub(method(SfcProviderServiceForwarderAPI.class, "readServiceFunctionForwarder")).toReturn(serviceFunctionForwarder);
 
         policyConfigurationContext.setCurrentRendererEP(createRendererEP(
                 "unit-address", new ContextId("unit-conext-1"), Collections.emptyList())
@@ -243,7 +250,7 @@ public class ServiceChainingUtilTest {
 
         ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap,
                 policyConfigurationContext, dataBroker);
-        Mockito.verify(policyWriter, Mockito.times(2)).cache(classMapCaptor.capture());
+        Mockito.verify(policyWriter).cache(classMapCaptor.capture());
         Mockito.verify(policyWriter).cache(listClassCaptor.capture());
         Mockito.verifyNoMoreInteractions(policyWriter);
     }
@@ -253,7 +260,7 @@ public class ServiceChainingUtilTest {
         final PeerEndpoint peerEndpoint = createPeerEndpoint();
         final Sgt sourceSgt = new Sgt(1);
         final Sgt destinationSgt = new Sgt(2);
-        final Map<PolicyManagerImpl.ActionCase, Action> actionMap = createActionMap();
+        final Map<PolicyManagerImpl.ActionCase, ActionInDirection> actionMap = createActionMap();
         final String classMapName = "unit-class-map-name-01";
 
         final String sfcNameValue = "123";
@@ -266,7 +273,6 @@ public class ServiceChainingUtilTest {
 
         final RenderedServicePath rsp = createRsp("unit-rsp-02");
         stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(rsp);
-        stub(method(ServiceChainingUtil.class, "setSfcPart")).toReturn(false);
 
         ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, policyConfigurationContext, dataBroker);
 
@@ -278,7 +284,7 @@ public class ServiceChainingUtilTest {
         final PeerEndpoint peerEndpoint = createPeerEndpoint(null);
         final Sgt sourceSgt = new Sgt(1);
         final Sgt destinationSgt = new Sgt(2);
-        final Map<PolicyManagerImpl.ActionCase, Action> actionMap = createActionMap();
+        final Map<PolicyManagerImpl.ActionCase, ActionInDirection> actionMap = createActionMap();
         final String classMapName = "unit-class-map-name-01";
 
         final String sfcNameValue = "123";
@@ -306,7 +312,7 @@ public class ServiceChainingUtilTest {
         final PeerEndpoint peerEndpoint = createPeerEndpoint(null);
         final Sgt sourceSgt = new Sgt(1);
         final Sgt destinationSgt = new Sgt(2);
-        final Map<PolicyManagerImpl.ActionCase, Action> actionMap = createActionMap(false);
+        final Map<PolicyManagerImpl.ActionCase, ActionInDirection> actionMap = createActionMap(false);
         final String classMapName = "unit-class-map-name-01";
 
         policyConfigurationContext.setCurrentRendererEP(createRendererEP(
@@ -318,12 +324,12 @@ public class ServiceChainingUtilTest {
         Mockito.verifyNoMoreInteractions(policyWriter);
     }
 
-    private Map<PolicyManagerImpl.ActionCase, Action> createActionMap() {
+    private Map<PolicyManagerImpl.ActionCase, ActionInDirection> createActionMap() {
         return createActionMap(true);
     }
 
-    private Map<PolicyManagerImpl.ActionCase, Action> createActionMap(final boolean fillParamValue) {
-        final Map<PolicyManagerImpl.ActionCase,Action> actionMap = new HashMap<>();
+    private Map<PolicyManagerImpl.ActionCase, ActionInDirection> createActionMap(final boolean fillParamValue) {
+        final Map<PolicyManagerImpl.ActionCase, ActionInDirection> actionMap = new HashMap<>();
         final ActionBuilder actionValue = new ActionBuilder();
         if (fillParamValue) {
             actionValue.setParameterValue(Collections.singletonList(new ParameterValueBuilder()
@@ -331,7 +337,9 @@ public class ServiceChainingUtilTest {
                     .setStringValue("123")
                     .build()));
         }
-        actionMap.put(PolicyManagerImpl.ActionCase.CHAIN, actionValue.build());
+        ActionInDirection actionInDirection = new ActionInDirection(actionValue.build(),
+                EndpointPolicyParticipation.CONSUMER, HasDirection.Direction.Out);
+        actionMap.put(PolicyManagerImpl.ActionCase.CHAIN, actionInDirection);
         return actionMap;
     }
 
@@ -373,7 +381,7 @@ public class ServiceChainingUtilTest {
 
         final RenderedServicePath renderedPath = ServiceChainingUtil.createRenderedPath(sfp, tenantId, dataBroker);
 
-        Assert.assertEquals("123_plainunit-tennant-01-gbp-rsp", rspNameCaptor.getValue().getValue());
+        Assert.assertEquals("123_plain-unit-tennant-01-gbp-rsp", rspNameCaptor.getValue().getValue());
         Assert.assertEquals(rsp, renderedPath);
     }
 
@@ -397,7 +405,7 @@ public class ServiceChainingUtilTest {
 
         final RenderedServicePath renderedPath = ServiceChainingUtil.createRenderedPath(sfp, tenantId, dataBroker);
 
-        Assert.assertEquals("123_plainunit-tennant-01-gbp-rsp", rspNameCaptor.getValue().getValue());
+        Assert.assertEquals("123_plain-unit-tennant-01-gbp-rsp", rspNameCaptor.getValue().getValue());
 
         final ServiceFunctionPath serviceFunctionPath = sfpCaptor.getValue();
         Assert.assertEquals("123_plain", serviceFunctionPath.getName().getValue());
@@ -406,7 +414,7 @@ public class ServiceChainingUtilTest {
         final CreateRenderedPathInput createRPInput = createRspCaptor.getValue();
         Assert.assertFalse(createRPInput.isSymmetric());
         Assert.assertEquals("123_plain", createRPInput.getParentServiceFunctionPath());
-        Assert.assertEquals("123_plainunit-tennant-01-gbp-rsp", createRPInput.getName());
+        Assert.assertEquals("123_plain-unit-tennant-01-gbp-rsp", createRPInput.getName());
 
         Assert.assertEquals(rsp, renderedPath);
     }
@@ -443,9 +451,9 @@ public class ServiceChainingUtilTest {
         final SfcProviderRenderedPathAPI api = PowerMockito.mock(SfcProviderRenderedPathAPI.class);
         PowerMockito.when(api.readRenderedServicePath(rspNameCaptor.capture())).thenReturn(rsp);
 
-        final RenderedServicePath symmetricRenderedPath = ServiceChainingUtil.createSymmetricRenderedPath(sfp, rsp, tennantId, dataBroker);
+        final RenderedServicePath symmetricRenderedPath = ServiceChainingUtil.createReversedRenderedPath(sfp, rsp, tennantId, dataBroker);
 
-        Assert.assertEquals("unit-sfp-02_plaintenant-02-gbp-rsp-Reverse", rspNameCaptor.getValue().getValue());
+        Assert.assertEquals("unit-sfp-02_plain-tenant-02-gbp-rsp-Reverse", rspNameCaptor.getValue().getValue());
         Assert.assertEquals(rsp, symmetricRenderedPath);
     }
 
@@ -463,9 +471,9 @@ public class ServiceChainingUtilTest {
         final NetconfTransactionCreator creator = PowerMockito.mock(NetconfTransactionCreator.class);
         PowerMockito.when(creator.netconfReadWriteTransaction(dataBroker)).thenReturn(java.util.Optional.empty());
 
-        final RenderedServicePath symmetricRenderedPath = ServiceChainingUtil.createSymmetricRenderedPath(sfp, rsp, tennantId, dataBroker);
+        final RenderedServicePath symmetricRenderedPath = ServiceChainingUtil.createReversedRenderedPath(sfp, rsp, tennantId, dataBroker);
 
-        Assert.assertEquals("unit-sfp-02_plaintenant-02-gbp-rsp-Reverse", rspNameCaptor.getValue().getValue());
+        Assert.assertEquals("unit-sfp-02_plain-tenant-02-gbp-rsp-Reverse", rspNameCaptor.getValue().getValue());
         Assert.assertEquals(rsp, rspCaptor.getValue());
         Assert.assertEquals(rsp, symmetricRenderedPath);
     }
@@ -480,179 +488,17 @@ public class ServiceChainingUtilTest {
 
         stub(method(SfcProviderServicePathAPI.class, "readAllServiceFunctionPaths")).toReturn(sfcPaths);
 
-        final ServiceFunctionPath servicePath = ServiceChainingUtil.findServiceFunctionPath(new SfcName(sfcNameValue));
+        final ServiceFunctionPath servicePath = ServiceChainingUtil.findServiceFunctionPathFromServiceChainName(new SfcName(sfcNameValue));
         Assert.assertEquals(sfcPath, servicePath);
     }
 
-    @Test
-    public void testSetSfcPart_success() throws Exception {
-        final RenderedServicePath rsp = createRsp("unit-rsp-03");
-        final DataPlaneLocatorBuilder dataPlaneLocatorBuilder = new DataPlaneLocatorBuilder();
-        final IpBuilder ipBuilderLocatorType = new IpBuilder();
-        ipBuilderLocatorType.setIp(IetfModelCodec.ipAddress2013(new IpAddress(new Ipv4Address("1.2.3.4"))));
-        dataPlaneLocatorBuilder.setLocatorType(ipBuilderLocatorType.build());
-        final SffDataPlaneLocatorBuilder sffDataPlaneLocatorBuilder = new SffDataPlaneLocatorBuilder();
-        sffDataPlaneLocatorBuilder.setDataPlaneLocator(dataPlaneLocatorBuilder.build());
-        final org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder
-                sff = new ServiceFunctionForwarderBuilder()
-                .setName(new SffName("unit-sff-03"))
-                .setIpMgmtAddress(IetfModelCodec.ipAddress2013(new IpAddress(new Ipv4Address("1.2.3.4"))))
-                .setSffDataPlaneLocator(Collections.singletonList(sffDataPlaneLocatorBuilder.build()))
-                .build();
-        final ServiceFunctionPathBuilder sfpBuilder = new ServiceFunctionPathBuilder();
-        sfpBuilder.setSymmetric(false);
-        final ServiceFunctionPath sfp = sfpBuilder.build();
-
-        PowerMockito.mockStatic(SfcProviderServiceForwarderAPI.class);
-        final SfcProviderServiceForwarderAPI api = PowerMockito.mock(SfcProviderServiceForwarderAPI.class);
-        PowerMockito.when(api.readServiceFunctionForwarder(sffNameCaptor.capture())).thenReturn(sff);
-
-        final boolean outcome = ServiceChainingUtil.setSfcPart(sfp, rsp, null, policyWriter);
-
-        Assert.assertEquals("rsp-hop-01-sf+sff", sffNameCaptor.getValue().getValue());
-        Assert.assertTrue(outcome);
-
-        Mockito.verify(policyWriter).cache(Matchers.<ServiceFfName>any());
-        Mockito.verify(policyWriter).cache(Matchers.<ServiceChain>any());
-        Mockito.verify(policyWriter).getManagementIpAddress();
-        Mockito.verifyNoMoreInteractions(policyWriter);
-    }
-
-    @Test
-    public void testSetSfcPart_success_newRsp() throws Exception {
-        final RenderedServicePath rsp = createRsp("unit-rsp-03");
-        final DataPlaneLocatorBuilder dataPlaneLocatorBuilder = new DataPlaneLocatorBuilder();
-        final IpBuilder ipBuilderLocatorType = new IpBuilder();
-        ipBuilderLocatorType.setIp(IetfModelCodec.ipAddress2013(new IpAddress(new Ipv4Address("1.2.3.4"))));
-        dataPlaneLocatorBuilder.setLocatorType(ipBuilderLocatorType.build());
-        final SffDataPlaneLocatorBuilder sffDataPlaneLocatorBuilder = new SffDataPlaneLocatorBuilder();
-        sffDataPlaneLocatorBuilder.setDataPlaneLocator(dataPlaneLocatorBuilder.build());
-        final org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder
-                sff = new ServiceFunctionForwarderBuilder()
-                .setName(new SffName("unit-sff-03"))
-                .setIpMgmtAddress(IetfModelCodec.ipAddress2013(new IpAddress(new Ipv4Address("1.2.3.4"))))
-                .setSffDataPlaneLocator(Collections.singletonList(sffDataPlaneLocatorBuilder.build()))
-                .build();
-        final ServiceFunctionPathBuilder sfpBuilder = new ServiceFunctionPathBuilder();
-        sfpBuilder.setSymmetric(false);
-        final ServiceFunctionPath sfp = sfpBuilder.build();
-
-        PowerMockito.mockStatic(SfcProviderServiceForwarderAPI.class);
-        final SfcProviderServiceForwarderAPI api = PowerMockito.mock(SfcProviderServiceForwarderAPI.class);
-        PowerMockito.when(api.readServiceFunctionForwarder(sffNameCaptor.capture())).thenReturn(sff);
-
-        final boolean outcome = ServiceChainingUtil.setSfcPart(sfp, rsp, null, policyWriter);
-
-        Assert.assertEquals("rsp-hop-01-sf+sff", sffNameCaptor.getValue().getValue());
-        Assert.assertTrue(outcome);
-
-        Mockito.verify(policyWriter).cache(Matchers.<ServiceFfName>any());
-        Mockito.verify(policyWriter).cache(Matchers.<ServiceChain>any());
-        Mockito.verify(policyWriter).getManagementIpAddress();
-        Mockito.verifyNoMoreInteractions(policyWriter);
-    }
-
-    @Test
-    public void testSetSfcPart_fail01() throws Exception {
-        final ServiceFunctionPathBuilder sfpBuilder = new ServiceFunctionPathBuilder();
-        sfpBuilder.setSymmetric(false);
-        final ServiceFunctionPath sfp = sfpBuilder.build();
-
-        Assert.assertFalse(ServiceChainingUtil.setSfcPart(sfp, null, null, policyWriter));
-
-        final RenderedServicePathBuilder rspBuilder = new RenderedServicePathBuilder().setName(new RspName("unit-rsp-05"));
-        Assert.assertFalse(ServiceChainingUtil.setSfcPart(sfp, rspBuilder.build(), null, policyWriter));
-
-        rspBuilder.setRenderedServicePathHop(Collections.emptyList());
-        Assert.assertFalse(ServiceChainingUtil.setSfcPart(sfp, rspBuilder.build(), null, policyWriter));
-
-        rspBuilder.setRenderedServicePathHop(Collections.singletonList(null));
-        Assert.assertFalse(ServiceChainingUtil.setSfcPart(sfp, rspBuilder.build(), null, policyWriter));
-    }
-
-    @Test
-    public void testSetSfcPart_fail02() throws Exception {
-        final RenderedServicePath rsp = createRsp("unit-rsp-03");
-        final ServiceFunctionPathBuilder sfpBuilder = new ServiceFunctionPathBuilder();
-        sfpBuilder.setSymmetric(false);
-        final ServiceFunctionPath sfp = sfpBuilder.build();
-
-        Mockito.doReturn(Futures.immediateCheckedFuture(Optional.absent()))
-                .when(rwTx).read(Mockito.eq(LogicalDatastoreType.CONFIGURATION), Mockito.<InstanceIdentifier<Local>>any());
-
-        PowerMockito.mockStatic(SfcProviderServiceForwarderAPI.class);
-        final SfcProviderServiceForwarderAPI api = PowerMockito.mock(SfcProviderServiceForwarderAPI.class);
-        PowerMockito.when(api.readServiceFunctionForwarder(sffNameCaptor.capture())).thenReturn(null);
-
-        final boolean outcome = ServiceChainingUtil.setSfcPart(sfp, rsp, null, policyWriter);
-
-        Assert.assertEquals("rsp-hop-01-sf+sff", sffNameCaptor.getValue().getValue());
-        Assert.assertFalse(outcome);
-
-        Mockito.verifyNoMoreInteractions(policyWriter);
-    }
-
-    @Test
-    public void testSetSfcPart_fail03() throws Exception {
-        final RenderedServicePath rsp = createRsp("unit-rsp-03");
-        final ServiceFunctionForwarderBuilder sffBuilder = new ServiceFunctionForwarderBuilder()
-                .setName(new SffName("unit-sff-03"))
-                .setIpMgmtAddress(null);
-        final ServiceFunctionPathBuilder sfpBuilder = new ServiceFunctionPathBuilder();
-        sfpBuilder.setSymmetric(false);
-        final ServiceFunctionPath sfp = sfpBuilder.build();
-
-        PowerMockito.mockStatic(SfcProviderServiceForwarderAPI.class);
-        final SfcProviderServiceForwarderAPI api = PowerMockito.mock(SfcProviderServiceForwarderAPI.class);
-        PowerMockito.when(api.readServiceFunctionForwarder(sffNameCaptor.capture())).thenReturn(
-                sffBuilder.build());
-
-        Assert.assertFalse(ServiceChainingUtil.setSfcPart(sfp, rsp, null, policyWriter));
-
-        Assert.assertEquals("rsp-hop-01-sf+sff", sffNameCaptor.getValue().getValue());
-
-        Mockito.verifyNoMoreInteractions(policyWriter);
-    }
-
-    @Test
-    public void testSetSfcPart_fail04() throws Exception {
-        final RenderedServicePath rsp = createRsp("unit-rsp-03");
-        final ServiceFunctionForwarderBuilder sffBuilder = new ServiceFunctionForwarderBuilder()
-                .setName(new SffName("unit-sff-03"))
-                .setIpMgmtAddress(null);
-        final ServiceFunctionPathBuilder sfpBuilder = new ServiceFunctionPathBuilder();
-        sfpBuilder.setSymmetric(false);
-        final ServiceFunctionPath sfp = sfpBuilder.build();
-
-        PowerMockito.mockStatic(SfcProviderServiceForwarderAPI.class);
-        final SfcProviderServiceForwarderAPI api = PowerMockito.mock(SfcProviderServiceForwarderAPI.class);
-        PowerMockito.when(api.readServiceFunctionForwarder(sffNameCaptor.capture())).thenReturn(
-                sffBuilder.build());
-
-        Assert.assertFalse(ServiceChainingUtil.setSfcPart(sfp, rsp, null, policyWriter));
-
-        Assert.assertEquals("rsp-hop-01-sf+sff", sffNameCaptor.getValue().getValue());
-
-        Mockito.verifyNoMoreInteractions(policyWriter);
-    }
-
     @Test
     public void testForwarderTypeChoice() throws Exception {
         final String sffValue = "unit-xx";
-        final ServiceTypeChoice fwChoice = ServiceChainingUtil.forwarderTypeChoice(sffValue);
+        final ServiceTypeChoice fwChoice = ServiceChainingUtil.createForwarderTypeChoice(sffValue);
 
         Assert.assertTrue(fwChoice instanceof ServiceFunctionForwarder);
         final ServiceFunctionForwarder sff = (ServiceFunctionForwarder) fwChoice;
         Assert.assertEquals(sffValue, sff.getServiceFunctionForwarder());
     }
-
-    @Test
-    public void testFunctionTypeChoice() throws Exception {
-        final String stcValue = "unit-xx";
-        final ServiceTypeChoice srvTypeChoice = ServiceChainingUtil.functionTypeChoice(stcValue);
-
-        Assert.assertTrue(srvTypeChoice instanceof ServiceFunction);
-        final ServiceFunction stc = (ServiceFunction) srvTypeChoice;
-        Assert.assertEquals(stcValue, stc.getServiceFunction());
-    }
-}
+}
\ No newline at end of file