From 1ebc9cd0e96570f4aed9d6489e1d02cc5f9a7239 Mon Sep 17 00:00:00 2001 From: Vladimir Lavor Date: Wed, 20 Jul 2016 14:00:20 +0200 Subject: [PATCH] ios-xe renderer now creates configuration per endpoint pair Change-Id: I097589bed0c2cd78249030e77be8a97a18f25605 Signed-off-by: Vladimir Lavor --- .../manager/PolicyConfigurationContext.java | 80 +++- .../impl/manager/PolicyManagerImpl.java | 142 ++++--- .../impl/util/PolicyManagerUtil.java | 176 +++++++-- .../impl/util/ServiceChainingUtil.java | 347 +++++++++--------- .../ios_xe_provider/impl/util/StatusUtil.java | 38 +- .../impl/writer/PolicyWriter.java | 120 ------ .../impl/writer/PolicyWriterUtil.java | 272 ++++++++------ .../impl/manager/PolicyManagerImplTest.java | 11 +- .../impl/util/PolicyManagerUtilTest.java | 35 +- .../impl/util/ServiceChainingUtilTest.java | 275 ++++++++------ .../impl/util/StatusUtilTest.java | 30 +- .../impl/writer/PolicyWriterUtilTest.java | 138 +++---- 12 files changed, 929 insertions(+), 735 deletions(-) delete mode 100644 renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/PolicyWriter.java diff --git a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyConfigurationContext.java b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyConfigurationContext.java index a6c7bc83d..27c99b4a2 100644 --- a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyConfigurationContext.java +++ b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyConfigurationContext.java @@ -10,7 +10,11 @@ package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager; import java.util.ArrayList; import java.util.List; -import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriter; +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.common.api.data.TransactionCommitFailedException; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.unconfigured.rule.groups.unconfigured.rule.group.UnconfiguredResolvedRule; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Status; 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.status.unconfigured.endpoints.UnconfiguredRendererEndpoint; @@ -18,47 +22,60 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.r /** * Purpose: placeholder for * */ public class PolicyConfigurationContext { private final List unconfiguredRendererEPBag; - private PolicyWriter policyWriter; + private final List> cumulativeResult; + private PolicyManagerImpl.PolicyMapLocation policyMapLocation; private RendererEndpoint currentRendererEP; + private UnconfiguredResolvedRule currentUnconfiguredRule; public PolicyConfigurationContext() { unconfiguredRendererEPBag = new ArrayList<>(); + cumulativeResult = new ArrayList<>(); } /** - * @return policyWriter for mountpoint currently being configured + * Set transaction result to result pool + * + * @param result current result */ - public PolicyWriter getPolicyWriter() { - return policyWriter; + public void setFutureResult(final CheckedFuture result) { + cumulativeResult.add(result); } /** - * @param policyWriter for mountpoint currently being configured + * append given endpoint to collection of not configurable policies + * + * @param endpoint not configurable endpoint */ - public void setPolicyWriter(final PolicyWriter policyWriter) { - this.policyWriter = policyWriter; + public void appendUnconfiguredRendererEP(UnconfiguredRendererEndpoint endpoint) { + unconfiguredRendererEPBag.add(endpoint); } /** - * @return list of not configurable policies + * @return policy-map location */ - public List getUnconfiguredRendererEPBag() { - return unconfiguredRendererEPBag; + public PolicyManagerImpl.PolicyMapLocation getPolicyMapLocation() { + return policyMapLocation; } /** - * append given endpoint to collection of not configurable policies - * @param endpoint not configurable endpoint + * @param policyMapLocation for actual policy-map/interface location */ - public void appendUnconfiguredRendererEP(UnconfiguredRendererEndpoint endpoint) { - unconfiguredRendererEPBag.add(endpoint); + public void setPolicyMapLocation(final PolicyManagerImpl.PolicyMapLocation policyMapLocation) { + this.policyMapLocation = policyMapLocation; + } + + /** + * @return endpoint currently being configured + */ + public RendererEndpoint getCurrentRendererEP() { + return currentRendererEP; } /** @@ -69,9 +86,32 @@ public class PolicyConfigurationContext { } /** - * @return endpoint currently being configured + * @return list of not configurable policies */ - public RendererEndpoint getCurrentRendererEP() { - return currentRendererEP; + List getUnconfiguredRendererEPBag() { + return unconfiguredRendererEPBag; + } + + /** + * @return all unconfigured rules + */ + public UnconfiguredResolvedRule getCurrentUnconfiguredRule() { + return currentUnconfiguredRule; + } + + /** + * Add unconfigured rule to list + * + * @param unconfiguredResolvedRule unconfigured rule + */ + public void setCurrentUnconfiguredRule(final UnconfiguredResolvedRule unconfiguredResolvedRule) { + this.currentUnconfiguredRule = unconfiguredResolvedRule; + } + + /** + * @return get all transaction results as a list + */ + ListenableFuture> getCumulativeResult() { + return Futures.allAsList(cumulativeResult); } } diff --git a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyManagerImpl.java b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyManagerImpl.java index bfb4ee16a..7c6694136 100644 --- a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyManagerImpl.java +++ b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyManagerImpl.java @@ -13,10 +13,7 @@ import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.ma 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 com.google.common.base.Function; import com.google.common.base.Preconditions; @@ -31,8 +28,6 @@ import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFaile import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.manager.PolicyManager; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.StatusUtil; -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.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.RendererKey; @@ -93,21 +88,26 @@ public class PolicyManagerImpl implements PolicyManager { }); } - private ListenableFuture> syncEndpoints(final Configuration dataAfter, DsAction action) { + /** + * Resolve policy for all endpoint pairs + * + * @param dataAfter - data used while processing + * @param action - specifies whether data are intended for creating or removing of configuration + * @return status of policy resolution + */ + private ListenableFuture> syncEndpoints(final Configuration dataAfter, final DsAction action) { if (dataAfter.getRendererEndpoints() == null || dataAfter.getRendererEndpoints().getRendererEndpoint() == null) { - LOG.debug("no configuration obtained - skipping"); + LOG.debug("No configuration obtained - skipping"); return Futures.immediateFuture(Optional.empty()); } - final PolicyConfigurationContext context = new PolicyConfigurationContext(); - final Map policyWriterPerDeviceCache = new HashMap<>(); + // Renderer endpoint for (RendererEndpoint rendererEndpoint : dataAfter.getRendererEndpoints().getRendererEndpoint()) { - // Store the endpoint currently being configured context.setCurrentRendererEP(rendererEndpoint); if (dataAfter.getEndpoints() == null || dataAfter.getEndpoints().getAddressEndpointWithLocation() == null) { - final String info = "renderer-endpoint: missing address-endpoint-with-location"; + final String info = "Renderer-endpoint: missing address-endpoint-with-location"; context.appendUnconfiguredRendererEP(StatusUtil.assembleFullyNotConfigurableRendererEP(context, info)); continue; } @@ -116,36 +116,29 @@ public class PolicyManagerImpl implements PolicyManager { 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); + final String info = String.format("No data-broker for mount-point [%s] available", mountpointIid); + context.appendUnconfiguredRendererEP(StatusUtil.assembleFullyNotConfigurableRendererEP(context, info)); + continue; + } + final String managementIpAddress = nodeManager.getNodeManagementIpByMountPointIid(mountpointIid); + if (managementIpAddress == null) { + final String info = String.format("Can not create policyWriter, managementIpAddress for mountpoint %s is null", + mountpointIid); context.appendUnconfiguredRendererEP(StatusUtil.assembleFullyNotConfigurableRendererEP(context, info)); continue; } - // Generate policy writer key - policy map name, composed from base value, interface name and node id 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); + final String info = String.format("Cannot compose policy-map, missing value. Interface: %s, NodeId: %s", interfaceName, nodeId); + context.appendUnconfiguredRendererEP(StatusUtil.assembleFullyNotConfigurableRendererEP(context, info)); + LOG.warn(info); continue; } final String policyMapName = BASE_POLICY_MAP_NAME.concat(interfaceName); - final String policyWriterKey = policyMapName.concat("-" + nodeId.getValue()); - // Find appropriate writer - PolicyWriter policyWriter = policyWriterPerDeviceCache.get(policyWriterKey); - if (policyWriter == null) { - // Initialize new policy writer - final String managementIpAddress = nodeManager.getNodeManagementIpByMountPointIid(mountpointIid); - if (managementIpAddress == null) { - final String info = String.format("can not create policyWriter, managementIpAddress for mountpoint %s is null", - mountpointIid); - context.appendUnconfiguredRendererEP(StatusUtil.assembleFullyNotConfigurableRendererEP(context, info)); - continue; - } - policyWriter = new PolicyWriter(mountpoint, interfaceName, managementIpAddress, policyMapName, nodeId); - policyWriterPerDeviceCache.put(policyWriterKey, policyWriter); - } - - // Assign policyWriter for current policy-map - context.setPolicyWriter(policyWriter); + final PolicyMapLocation policyMapLocation = new PolicyMapLocation(policyMapName, interfaceName, nodeId, + managementIpAddress, mountpoint); + context.setPolicyMapLocation(policyMapLocation); final Sgt sourceSgt = PolicyManagerUtil.findSgtTag(rendererEndpoint, dataAfter.getEndpoints() .getAddressEndpointWithLocation()); @@ -154,28 +147,27 @@ public class PolicyManagerImpl implements PolicyManager { final Sgt destinationSgt = PolicyManagerUtil.findSgtTag(peerEndpoint, dataAfter.getEndpoints() .getAddressEndpointWithLocation()); if (sourceSgt == null || destinationSgt == null) { - final String info = String.format("endpoint-policy: missing sgt value(sourceSgt=%s, destinationSgt=%s)", + final String info = String.format("Endpoint-policy: missing sgt value(sourceSgt=%s, destinationSgt=%s)", sourceSgt, destinationSgt); context.appendUnconfiguredRendererEP( StatusUtil.assembleNotConfigurableRendererEPForPeer(context, peerEndpoint, info)); continue; } - PolicyManagerUtil.syncResolvedPolicy(sourceSgt, destinationSgt, context, dataAfter, peerEndpoint, - dataBroker, action); + // Resolve policy between endpoints + if (action.equals(Create)) { + LOG.debug("Setting up policy between endpoint {}, sgt: {} and peer {}, sgt: {}", rendererEndpoint, + sourceSgt, peerEndpoint, destinationSgt); + PolicyManagerUtil.syncEndpointPairCreatePolicy(sourceSgt, destinationSgt, context, dataAfter, + peerEndpoint, dataBroker); + } else { + LOG.debug("Removing policy between endpoint {}, sgt: {} and peer {}, sgt: {}", rendererEndpoint, + sourceSgt, peerEndpoint, destinationSgt); + PolicyManagerUtil.syncEndpointPairRemovePolicy(sourceSgt, destinationSgt, context, dataAfter, + peerEndpoint); + } } } - - final List> allFutureResults = new ArrayList<>(); - if (action.equals(Create)) { - // TODO ensure that last transaction is done before the next one starts - policyWriterPerDeviceCache.values().forEach((pw) -> allFutureResults.add(pw.commitToDatastore())); - } else if (action.equals(Delete)) { - policyWriterPerDeviceCache.values().forEach((pw) -> allFutureResults.add(pw.removeFromDatastore())); - } else { - LOG.info("unsupported policy manage action: {}", action); - } - final ListenableFuture> cumulativeResult = Futures.allAsList(allFutureResults); - + final ListenableFuture> cumulativeResult = context.getCumulativeResult(); return Futures.transform(cumulativeResult, new Function, Optional>() { @Nullable @Override @@ -194,14 +186,9 @@ public class PolicyManagerImpl implements PolicyManager { }); } - private CheckedFuture reportPolicy(long version, @Nonnull final Optional statusValue) { - final Optional optionalReadWriteTransaction = - NetconfTransactionCreator.netconfReadWriteTransaction(dataBroker); - if (!optionalReadWriteTransaction.isPresent()) { - LOG.warn("Failed to create transaction, mountpoint: {}", dataBroker); - return Futures.immediateCheckedFuture(null); - } - final ReadWriteTransaction readWriteTransaction = optionalReadWriteTransaction.get(); + private CheckedFuture reportPolicy(final long version, + @Nonnull final Optional statusValue) { + final ReadWriteTransaction readWriteTransaction = dataBroker.newReadWriteTransaction(); final InstanceIdentifier iid = InstanceIdentifier.create(Renderers.class) .child(Renderer.class, new RendererKey(NodeManager.iosXeRenderer)) .child(RendererPolicy.class); @@ -218,7 +205,48 @@ public class PolicyManagerImpl implements PolicyManager { //NOOP } - public enum DsAction {Create, Delete} + enum DsAction {Create, Delete} public enum ActionCase {ALLOW, CHAIN} -} + + /** + * Wrapper class - contains all necessary information to clearly localize policy-map/interface/node in network + */ + public static class PolicyMapLocation { + + private final String policyMapName; + private final String interfaceName; + private final NodeId nodeId; + private final String managementIpAddress; + private final DataBroker mountpoint; + + public PolicyMapLocation(final String policyMapName, final String interfaceName, final NodeId nodeId, + final String managementIpAddress, final DataBroker mountpoint) { + this.policyMapName = Preconditions.checkNotNull(policyMapName); + this.interfaceName = Preconditions.checkNotNull(interfaceName); + this.nodeId = Preconditions.checkNotNull(nodeId); + this.managementIpAddress = Preconditions.checkNotNull(managementIpAddress); + this.mountpoint = Preconditions.checkNotNull(mountpoint); + } + + public String getPolicyMapName() { + return policyMapName; + } + + public String getInterfaceName() { + return interfaceName; + } + + public NodeId getNodeId() { + return nodeId; + } + + public String getManagementIpAddress() { + return managementIpAddress; + } + + public DataBroker getMountpoint() { + return mountpoint; + } + } +} \ No newline at end of file diff --git a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/PolicyManagerUtil.java b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/PolicyManagerUtil.java index 2d0ff18f7..56f829a99 100644 --- a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/PolicyManagerUtil.java +++ b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/PolicyManagerUtil.java @@ -9,8 +9,6 @@ package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util; import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.ActionCase.CHAIN; -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; @@ -20,13 +18,16 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.Futures; 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.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriterUtil; 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; @@ -66,6 +67,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpo import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionDefinitionId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.RuleName; 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; @@ -81,6 +83,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.p 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; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -90,36 +93,76 @@ public class PolicyManagerUtil { private static final Logger LOG = LoggerFactory.getLogger(PolicyManagerUtil.class); /** - * 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. + * Main method for policy creation 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 context - stores info about location of classifier/policy-map and status + * @param data - 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) { + public static void syncEndpointPairCreatePolicy(final Sgt sourceSgt, final Sgt destinationSgt, + final PolicyConfigurationContext context, final Configuration data, + final PeerEndpoint peerEndpoint, final DataBroker dataBroker) { + // Create appropriate policy map + if (!PolicyManagerUtil.constructEmptyPolicyMapWithInterface(context)) { + final String policyMapName = context.getPolicyMapLocation().getPolicyMapName(); + final String interfaceName = context.getPolicyMapLocation().getInterfaceName(); + final String info = String.format("Unable to create policy-map %s on interface %s", policyMapName, interfaceName); + context.appendUnconfiguredRendererEP(StatusUtil.assembleFullyNotConfigurableRendererEP(context, info)); + LOG.warn(info); + return; + } + // Find actions from acquired data - final Map actionMap = PolicyManagerUtil.getActionInDirection(dataAfter, peerEndpoint); + final Map actionMap = PolicyManagerUtil.getActionInDirection(data, peerEndpoint); if (actionMap.isEmpty()) { - LOG.debug("no usable action found for EP-sgt[{}] | peerEP-sgt[{}]", - sourceSgt, destinationSgt); + LOG.debug("No usable action found for EP-sgt[{}] | peerEP-sgt[{}]", sourceSgt, destinationSgt); return; } // Chain action - if (actionMap.containsKey(ActionCase.CHAIN) && action.equals(Create)) { - ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, context, + if (actionMap.containsKey(ActionCase.CHAIN)) { + ServiceChainingUtil.newChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, context, dataBroker); } - if (actionMap.containsKey(ActionCase.CHAIN) && action.equals(Delete)) { + } + + /** + * Method for policy removal which looks for all actions specified in rules between two endpoints. Whichever + * action has been found, it is resolved (only chain action is supported). + * + * @param sourceSgt - security group tag of source endpoint + * @param destinationSgt - security group tag of destination endpoint + * @param context - stores info about location of classifier/policy-map and status + * @param data - data used to identify all elements marked to remove + * @param peerEndpoint - contains info about rule groups between endpoint pairs + */ + public static void syncEndpointPairRemovePolicy(final Sgt sourceSgt, final Sgt destinationSgt, + final PolicyConfigurationContext context, final Configuration data, + final PeerEndpoint peerEndpoint) { + // Find actions from acquired data + final Map actionMap = PolicyManagerUtil.getActionInDirection(data, peerEndpoint); + if (actionMap.isEmpty()) { + LOG.debug("no usable action found for EP-sgt[{}] | peerEP-sgt[{}]", + sourceSgt, destinationSgt); + return; + } + + // Chain action + if (actionMap.containsKey(ActionCase.CHAIN)) { ServiceChainingUtil.resolveRemovedChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, - context.getPolicyWriter()); + context); + } + + // Remove policy-map if empty + if (!deleteEmptyPolicyMapWithInterface(context.getPolicyMapLocation())) { + final PolicyManagerImpl.PolicyMapLocation location = context.getPolicyMapLocation(); + final String info = String.format("Unable to remove policy-map %s and interface %s", location.getPolicyMapName(), + location.getInterfaceName()); + LOG.warn(info); } } @@ -166,6 +209,82 @@ public class PolicyManagerUtil { return augmentation.getSgt(); } + /** + * Creates empty policy-map if does not exist and bounds it to interface if it is not. If policy-map exists, method + * checks whether it is connected to correct interface and creates it if necessary. If policy-map does not exist, + * it is created with particular interface + * + * @param context - all data required to create/localize policy-map + * @return true if policy-map and interface is present/written on the device, false otherwise + */ + private static boolean constructEmptyPolicyMapWithInterface(final PolicyConfigurationContext context) { + final PolicyManagerImpl.PolicyMapLocation policyMapLocation = context.getPolicyMapLocation(); + final String policyMapName = policyMapLocation.getPolicyMapName(); + final DataBroker mountpoint = policyMapLocation.getMountpoint(); + final String interfaceName = policyMapLocation.getInterfaceName(); + final NodeId nodeId = policyMapLocation.getNodeId(); + final InstanceIdentifier policyMapIid = PolicyWriterUtil.policyMapInstanceIdentifier(policyMapName); + final Optional optionalPolicyMap = + Optional.ofNullable(PolicyWriterUtil.netconfRead(mountpoint, policyMapIid)); + if (optionalPolicyMap.isPresent()) { + LOG.trace("Policy map with name {} on interface {} already exists", policyMapName, interfaceName); + final InstanceIdentifier servicePolicyIid = PolicyWriterUtil.interfaceInstanceIdentifier(interfaceName); + final Optional optionalServicePolicy = + Optional.ofNullable(PolicyWriterUtil.netconfRead(mountpoint, servicePolicyIid)); + if (optionalServicePolicy.isPresent()) { + LOG.trace("Policy map {} is bound to correct interface {} ", policyMapName, interfaceName); + return true; + } else { + boolean iResult = PolicyWriterUtil.writeInterface(context.getPolicyMapLocation()); + context.setFutureResult(Futures.immediateCheckedFuture(iResult)); + return iResult; + } + } else { + final PolicyMap emptyMap = createEmptyPolicyMap(policyMapName); + boolean pmResult = PolicyWriterUtil.writePolicyMap(emptyMap, context.getPolicyMapLocation()); + context.setFutureResult(Futures.immediateCheckedFuture(pmResult)); + if (pmResult) { + LOG.info("Created policy-map {} on node {}", policyMapName, nodeId.getValue()); + LOG.trace("Adding policy-map {} to interface {}", policyMapName, interfaceName); + boolean iResult = PolicyWriterUtil.writeInterface(context.getPolicyMapLocation()); + context.setFutureResult(Futures.immediateCheckedFuture(iResult)); + return iResult; + } + return false; + } + } + + /** + * Removes empty policy-map and its interface + * + * @param policyMapLocation - location of policy-map + * @return true if policy-map is present and not empty or if it is successfully removed also with interface, false + * otherwise + */ + private static boolean deleteEmptyPolicyMapWithInterface(PolicyManagerImpl.PolicyMapLocation policyMapLocation) { + final String policyMapName = policyMapLocation.getPolicyMapName(); + final DataBroker mountpoint = policyMapLocation.getMountpoint(); + final InstanceIdentifier policyMapIid = PolicyWriterUtil.policyMapInstanceIdentifier(policyMapName); + // Read policy map + final Optional optionalPolicyMap = Optional.ofNullable(PolicyWriterUtil.netconfRead(mountpoint, policyMapIid)); + if (optionalPolicyMap.isPresent()) { + final PolicyMap policyMap = optionalPolicyMap.get(); + if (policyMap.getXmlClass() == null || policyMap.getXmlClass().isEmpty()) { + // No entries, remove + if (PolicyWriterUtil.removePolicyMap(policyMapLocation)) { + // Remove interface binding if exists + LOG.info("Policy-map {} removed", policyMapName); + return PolicyWriterUtil.removeInterface(policyMapLocation); + } + return false; + } + LOG.debug("Policy-map {} still contains entries, cannot be removed", policyMapLocation.getPolicyMapName()); + return true; + } + return true; + + } + public static ServicePolicy createServicePolicy(final String chainName, final Direction direction) { // Service Chain final ServiceChainBuilder serviceChainBuilder = new ServiceChainBuilder(); @@ -181,20 +300,18 @@ public class PolicyManagerUtil { return servicePolicyBuilder.build(); } - public static PolicyMap createPolicyMap(final String policyMapName, final Set policyMapEntries) { + private static PolicyMap createEmptyPolicyMap(String policyMapName) { // 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 policyMapEntriesList = new ArrayList<>(policyMapEntries); final PolicyMapBuilder policyMapBuilder = new PolicyMapBuilder(); policyMapBuilder.setName(policyMapName) .setKey(new PolicyMapKey(policyMapName)) - .setType(PolicyMap.Type.ServiceChain) - .setXmlClass(policyMapEntriesList); + .setType(PolicyMap.Type.ServiceChain); return policyMapBuilder.build(); } - static Class createPolicyEntry(final String policyClassName, final RenderedServicePath renderedPath, - final ActionCase actionCase) { + static Class createPolicyMapEntry(final String policyClassName, final RenderedServicePath renderedPath, + final ActionCase actionCase) { // Forward Case final ForwardCaseBuilder forwardCaseBuilder = new ForwardCaseBuilder(); if (actionCase.equals(CHAIN) && renderedPath != null) { @@ -236,6 +353,7 @@ public class PolicyManagerUtil { return matchBuilder.build(); } + @Nonnull static ClassMap createClassMap(final String classMapName, final Match match) { final ClassMapBuilder cmBuilder = new ClassMapBuilder(); cmBuilder.setName(classMapName) @@ -289,11 +407,12 @@ public class PolicyManagerUtil { for (ResolvedRule resolvedRule : rulesInDirection) { // TODO only first action used for now final Action action = resolvedRule.getAction().get(0); + final RuleName name = resolvedRule.getName(); 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); + ActionInDirection actionInDirection = new ActionInDirection(name, action, participation, direction); result.put(ActionCase.CHAIN, actionInDirection); return result; } @@ -357,18 +476,25 @@ public class PolicyManagerUtil { */ static class ActionInDirection { + private final RuleName ruleName; private final Action action; private final EndpointPolicyParticipation participation; private final HasDirection.Direction direction; - ActionInDirection(final Action action, + ActionInDirection(final RuleName ruleName, + final Action action, final EndpointPolicyParticipation participation, final HasDirection.Direction direction) { + this.ruleName = Preconditions.checkNotNull(ruleName); this.action = Preconditions.checkNotNull(action); this.participation = Preconditions.checkNotNull(participation); this.direction = Preconditions.checkNotNull(direction); } + RuleName getRuleName() { + return ruleName; + } + Action getAction() { return action; } diff --git a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/ServiceChainingUtil.java b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/ServiceChainingUtil.java index dbbba5274..c099b3963 100644 --- a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/ServiceChainingUtil.java +++ b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/ServiceChainingUtil.java @@ -11,7 +11,7 @@ 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.createPolicyMapEntry; 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; @@ -21,6 +21,7 @@ import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ren import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation.PROVIDER; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -31,6 +32,7 @@ import java.util.function.Supplier; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; import com.google.common.util.concurrent.CheckedFuture; +import com.google.common.util.concurrent.Futures; 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; @@ -39,7 +41,7 @@ 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.writer.NetconfTransactionCreator; -import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriter; +import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriterUtil; import org.opendaylight.sfc.provider.api.SfcProviderRenderedPathAPI; import org.opendaylight.sfc.provider.api.SfcProviderServiceForwarderAPI; import org.opendaylight.sfc.provider.api.SfcProviderServicePathAPI; @@ -84,10 +86,12 @@ 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.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.ServiceFunctionForwarderBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.RuleName; 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.has.unconfigured.rule.groups.unconfigured.rule.group.UnconfiguredResolvedRuleBuilder; 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; @@ -103,24 +107,31 @@ public class ServiceChainingUtil { private static long timeout = 5000L; /** - * 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)}. + * According to provided action, this method gets service function path and collects all info about participation + * and orientation of path. According to path symmetricity, participation and direction, one of these cases happens: + * 1. Path is asymmetric, and it starts in this classifier (specified by context) - direct chain is created + * 2. Path is asymmetric, and it starts in classifier on opposite side of the chain - skipped + * 3. Path is symmetric, and it starts in this classifier - direct chain is created + * 2. Path is symmetric, and it starts in classifier on opposite side of the chain - reversed path is created + *

+ * Behaviour is correct also in case when "this" and "opposite" classifier is the same * * @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 context - contains policy-map location and status info * @param dataBroker - to access odl datastore */ - static void resolveNewChainAction(final PeerEndpoint peerEndpoint, final Sgt sourceSgt, - final Sgt destinationSgt, final Map actionMap, - final PolicyConfigurationContext context, final DataBroker dataBroker) { + static void newChainAction(final PeerEndpoint peerEndpoint, final Sgt sourceSgt, + final Sgt destinationSgt, final Map actionMap, + final PolicyConfigurationContext context, final DataBroker dataBroker) { final ActionInDirection actionInDirection = actionMap.get(ActionCase.CHAIN); if (actionInDirection == null) { return; } + context.setCurrentUnconfiguredRule(new UnconfiguredResolvedRuleBuilder() + .setRuleName(new RuleName(actionInDirection.getRuleName())).build()); // Rule action + orientation final Action action = actionInDirection.getAction(); final EndpointPolicyParticipation participation = actionInDirection.getParticipation(); @@ -140,71 +151,40 @@ public class ServiceChainingUtil { context.appendUnconfiguredRendererEP(StatusUtil.assembleNotConfigurableRendererEPForPeer(context, peerEndpoint, info)); return; } - RenderedServicePath renderedServicePath; boolean sfcPartSuccessful = true; - // Symmetric chain - create direct or reversed rendered service path in corresponding direction - if (servicePath.isSymmetric()) { - 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)) || + // Creates direct path in corresponding direction + 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()); + final RenderedServicePath renderedServicePath = ServiceChainingUtil.resolveRenderedServicePath(servicePath, + tenantId, dataBroker, sourceSgt, destinationSgt, context); + sfcPartSuccessful = resolveRemoteSfcComponents(renderedServicePath, context); + // Creates reversed path if symmetric + } else if (servicePath.isSymmetric()) { + final RenderedServicePath renderedServicePath = + ServiceChainingUtil.resolveReversedRenderedServicePath(servicePath, tenantId, dataBroker, sourceSgt, + destinationSgt, context); + sfcPartSuccessful = resolveRemoteSfcComponents(renderedServicePath, context); } - // Create appropriate service path && remote forwarder 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)); + context.appendUnconfiguredRendererEP(StatusUtil.assembleNotConfigurableRendererEPForPeer(context, + peerEndpoint, info)); } } /** - * Removes class-map and policy-map entry in policy between endpoint pair. If necessary, method deletes remote SFC - * components. + * According to service function path and direction, creates appropriate rendered service path name {@link RspName} + * and starts appropriate method which removes policy for resolved endpoint pair * - * @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 + * @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 context - contains policy-map location and status info */ static void resolveRemovedChainAction(final PeerEndpoint peerEndpoint, final Sgt sourceSgt, final Sgt destinationSgt, - final Map actionMap, PolicyWriter policyWriter) { + final Map actionMap, final PolicyConfigurationContext context) { final ActionInDirection actionInDirection = actionMap.get(ActionCase.CHAIN); final Action action = actionInDirection.getAction(); final EndpointPolicyParticipation participation = actionInDirection.getParticipation(); @@ -218,75 +198,14 @@ public class ServiceChainingUtil { return; } //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 = createServiceChain(renderedServicePath); - final ServiceFfName remoteForwarder = createRemoteForwarder(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 = createRemoteForwarder(reversedFirstHopSff); - policyWriter.cache(serviceChain); - policyWriter.cache(remoteForwarder); - } - } - } - } else if ((participation.equals(PROVIDER) && direction.equals(Out)) || + 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 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 = createRemoteForwarder(firstHopSff); - policyWriter.cache(serviceChain); - policyWriter.cache(remoteForwarder); - } - } + resolveRemovedRenderedServicePath(rspName, sourceSgt, destinationSgt, context); + + } else if (servicePath.isSymmetric()) { + final RspName rspName = generateReversedRspName(servicePath, tenantId); + resolveRemovedRenderedServicePath(rspName, sourceSgt, destinationSgt, context); } } @@ -295,13 +214,15 @@ public class ServiceChainingUtil { * 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. + * different node (remote classifier), classifier has to create it's own service-path entry with remote SFF. * - * @param renderedServicePath classifier has to reach - * @param policyWriter policy entries writer + * @param renderedServicePath - path classifier has to reach + * @param context - contains policy-map location and status info * @return true if everything went good, false otherwise */ - static boolean resolveRemoteSfcComponents(final RenderedServicePath renderedServicePath, PolicyWriter policyWriter) { + public static boolean resolveRemoteSfcComponents(final RenderedServicePath renderedServicePath, + final PolicyConfigurationContext context) { + final PolicyManagerImpl.PolicyMapLocation location = context.getPolicyMapLocation(); final ServiceFunctionForwarder forwarder = getFirstHopSff(renderedServicePath); if (forwarder == null) { return false; @@ -328,13 +249,14 @@ public class ServiceChainingUtil { .map(Ipv4Address::getValue) .map(addressValue -> { final ServiceTypeChoice serviceTypeChoice; - if (!addressValue.equals(policyWriter.getManagementIpAddress())) { + if (!addressValue.equals(location.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()); + boolean rsResult = PolicyWriterUtil.writeRemote(remoteSffBuilder.build(), location); + context.setFutureResult(Futures.immediateCheckedFuture(rsResult)); serviceTypeChoice = createForwarderTypeChoice(sffName.getValue()); // Service chain final List services = new ArrayList<>(); @@ -353,7 +275,8 @@ public class ServiceChainingUtil { final ServiceChainBuilder chainBuilder = new ServiceChainBuilder(); chainBuilder.setServicePath(servicePaths); final ServiceChain serviceChain = chainBuilder.build(); - policyWriter.cache(serviceChain); + boolean scResult = PolicyWriterUtil.writeServicePath(serviceChain, location); + context.setFutureResult(Futures.immediateCheckedFuture(scResult)); } return true; }).orElseGet(createNegativePathWithLogSupplier(sffName.getValue(), @@ -364,6 +287,15 @@ public class ServiceChainingUtil { return false; } + /** + * Investigates provided parameter values and derives service chain name. This name is used to find service function + * path + * + * @param params - list of parameters + * @return - service function path if found, null if provided parameters does not correspond with any chain or there + * is no service function path defined by that chain + */ + @Nullable static ServiceFunctionPath findServicePathFromParameterValues(final List params) { if (params == null || params.isEmpty()) { LOG.error("Cannot found service path, parameter value is null"); @@ -413,61 +345,129 @@ public class ServiceChainingUtil { /** * 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)} + * DataBroker)}. If this operation is successful, class-map {@link ClassMap} and entry in policy-map {@link Class} + * is written * - * @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 + * @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 + * @param sourceSgt - source security group tag + * @param destinationSgt - destination security group tag + * @param context - contains policy-map location and status info * @return read/created RSP */ - static RenderedServicePath createRenderedPath(final ServiceFunctionPath sfp, final TenantId tenantId, - final DataBroker dataBroker) { - RenderedServicePath renderedServicePath; - // Try to read existing RSP + static RenderedServicePath resolveRenderedServicePath(final ServiceFunctionPath sfp, final TenantId tenantId, + final DataBroker dataBroker, final Sgt sourceSgt, final Sgt destinationSgt, + final PolicyConfigurationContext context) { + // Get rendered service path final RspName rspName = generateRspName(sfp, tenantId); - renderedServicePath = SfcProviderRenderedPathAPI.readRenderedServicePath(rspName); - if (renderedServicePath != null) { - return renderedServicePath; + RenderedServicePath renderedServicePath = SfcProviderRenderedPathAPI.readRenderedServicePath(rspName); + if (renderedServicePath == null) { + LOG.info("Rendered service path with name {} not found, creating a new one ..", rspName.getValue()); + final CreateRenderedPathInput input = new CreateRenderedPathInputBuilder() + .setParentServiceFunctionPath(sfp.getName().getValue()) + .setName(rspName.getValue()) + .setSymmetric(sfp.isSymmetric()) + .build(); + renderedServicePath = SfcProviderRenderedPathAPI.createRenderedServicePathAndState(sfp, input); + LOG.info("Rendered service path {} created", rspName.getValue()); + checkRspManagerStatus(rspName, dataBroker); } - LOG.info("Rendered service path with name {} not found, creating a new one ..", rspName.getValue()); - final CreateRenderedPathInput input = new CreateRenderedPathInputBuilder() - .setParentServiceFunctionPath(sfp.getName().getValue()) - .setName(rspName.getValue()) - .setSymmetric(sfp.isSymmetric()) - .build(); - renderedServicePath = SfcProviderRenderedPathAPI.createRenderedServicePathAndState(sfp, input); - LOG.info("Rendered service path {} created", rspName.getValue()); - checkRspManagerStatus(rspName, dataBroker); + // 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 = createPolicyMapEntry(classMapName, renderedServicePath, ActionCase.CHAIN); + boolean cmResult = PolicyWriterUtil.writeClassMap(classMap, context.getPolicyMapLocation()); + context.setFutureResult(Futures.immediateCheckedFuture(cmResult)); + boolean pmeResult = PolicyWriterUtil.writePolicyMapEntry(policyMapEntry, context.getPolicyMapLocation()); + context.setFutureResult(Futures.immediateCheckedFuture(pmeResult)); return renderedServicePath; } /** * 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)} + * transaction collisions. If this operation is successful, class-map {@link ClassMap} and entry in policy-map + * {@link Class} is written * - * @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 + * @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 + * @param sourceSgt - source security group tag + * @param destinationSgt - destination security group tag + * @param context - contains policy-map location and status info * @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); - reversedRenderedPath = SfcProviderRenderedPathAPI.readRenderedServicePath(rspName); - if (reversedRenderedPath != null) { - return reversedRenderedPath; + public static RenderedServicePath resolveReversedRenderedServicePath(final ServiceFunctionPath sfp, final TenantId tenantId, + final DataBroker dataBroker, final Sgt sourceSgt, + final Sgt destinationSgt, final PolicyConfigurationContext context) { + // Get rendered service path + final RspName rspName = generateRspName(sfp, tenantId); + RenderedServicePath renderedServicePath = SfcProviderRenderedPathAPI.readRenderedServicePath(rspName); + if (renderedServicePath == null) { + LOG.info("Rendered service path with name {} not found, creating a new one ..", rspName.getValue()); + final CreateRenderedPathInput input = new CreateRenderedPathInputBuilder() + .setParentServiceFunctionPath(sfp.getName().getValue()) + .setName(rspName.getValue()) + .setSymmetric(sfp.isSymmetric()) + .build(); + renderedServicePath = SfcProviderRenderedPathAPI.createRenderedServicePathAndState(sfp, input); + LOG.info("Rendered service path {} created", rspName.getValue()); + checkRspManagerStatus(rspName, dataBroker); } - 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()); - checkRspManagerStatus(rspName, dataBroker); + // Get reversed rendered service path + final RspName reversedRspName = generateReversedRspName(sfp, tenantId); + RenderedServicePath reversedRenderedPath = SfcProviderRenderedPathAPI.readRenderedServicePath(reversedRspName); + if (reversedRenderedPath == null) { + LOG.info("Reversed rendered service path with name {} not found, creating a new one ..", reversedRspName.getValue()); + reversedRenderedPath = SfcProviderRenderedPathAPI.createReverseRenderedServicePathEntry(renderedServicePath); + LOG.info("Rendered service path {} created", reversedRspName.getValue()); + checkRspManagerStatus(reversedRspName, dataBroker); + } + // 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 = createPolicyMapEntry(classMapName, renderedServicePath, ActionCase.CHAIN); + boolean cmResult = PolicyWriterUtil.writeClassMap(classMap, context.getPolicyMapLocation()); + context.setFutureResult(Futures.immediateCheckedFuture(cmResult)); + boolean pmeResult = PolicyWriterUtil.writePolicyMapEntry(policyMapEntry, context.getPolicyMapLocation()); + context.setFutureResult(Futures.immediateCheckedFuture(pmeResult)); + resolveRemoteSfcComponents(renderedServicePath, context); return reversedRenderedPath; } + /** + * Removes all policy setup created according to rendered service path. + * + * @param rspName - rendered service path name + * @param sourceSgt - source security group tag + * @param destinationSgt - destination security group tag + * @param context - context with policy-map location + */ + private static void resolveRemovedRenderedServicePath(final RspName rspName, final Sgt sourceSgt, final Sgt destinationSgt, + final PolicyConfigurationContext context) { + final String classMapName = PolicyManagerUtil.generateClassMapName(sourceSgt.getValue(), destinationSgt.getValue()); + final ClassMap classMap = PolicyManagerUtil.createClassMap(classMapName, null); + final Class policyMapEntry = PolicyManagerUtil.createPolicyMapEntry(classMapName, null, PolicyManagerImpl.ActionCase.CHAIN); + PolicyWriterUtil.removePolicyMapEntry(policyMapEntry, context.getPolicyMapLocation()); + PolicyWriterUtil.removeClassMap(classMap, context.getPolicyMapLocation()); + 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(context.getPolicyMapLocation().getManagementIpAddress())) { + // Remove service chain and remote forwarder + final ServiceChain serviceChain = createServiceChain(renderedServicePath); + final ServiceFfName remoteForwarder = createRemoteForwarder(firstHopSff); + PolicyWriterUtil.removeServicePath(serviceChain, context.getPolicyMapLocation()); + PolicyWriterUtil.removeRemote(remoteForwarder, context.getPolicyMapLocation()); + } + } + } + static ServiceFfName createRemoteForwarder(ServiceFunctionForwarder firstHopSff) { final ServiceFfNameBuilder serviceFfNameBuilder = new ServiceFfNameBuilder(); serviceFfNameBuilder.setName(firstHopSff.getName().getValue()); @@ -584,10 +584,11 @@ public class ServiceChainingUtil { /** * Only for test purposes + * * @param value - set actual timeout value */ @VisibleForTesting public static void setTimeout(long value) { timeout = value; } -} +} \ No newline at end of file diff --git a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/StatusUtil.java b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/StatusUtil.java index 8f8cb2086..f6d811027 100644 --- a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/StatusUtil.java +++ b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/StatusUtil.java @@ -8,15 +8,17 @@ package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util; -import com.google.common.annotations.VisibleForTesting; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; +import com.google.common.annotations.VisibleForTesting; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyConfigurationContext; 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.has.unconfigured.rule.groups.UnconfiguredRuleGroup; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.unconfigured.rule.groups.UnconfiguredRuleGroupBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.unconfigured.rule.groups.unconfigured.rule.group.UnconfiguredResolvedRule; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.unconfigured.rule.groups.unconfigured.rule.group.UnconfiguredResolvedRuleBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Status; 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.renderer.endpoint.PeerEndpoint; @@ -46,46 +48,60 @@ public class StatusUtil { public static UnconfiguredRendererEndpoint assembleFullyNotConfigurableRendererEP(final PolicyConfigurationContext context, final String info) { final RendererEndpoint rendererEndpoint = context.getCurrentRendererEP(); - LOG.trace("fully not configurable EP: {}", info); + LOG.trace("Fully not configurable EP: {}", info); return new UnconfiguredRendererEndpointBuilder(rendererEndpoint) - .setUnconfiguredPeerEndpoint(assemblePeerEndpoint(rendererEndpoint.getPeerEndpoint().stream())) + .setUnconfiguredPeerEndpoint(assemblePeerEndpoint(rendererEndpoint.getPeerEndpoint().stream(), context)) .setInfo(info) .build(); } /** - * @param context holder of actual configuration state - * @param info detailed message for not configurable item + * @param context holder of actual configuration state + * @param peerEndpoint peer endpoint + * @param info detailed message for not configurable item * @return filtered collection of not configurable items under given endpoint and peer */ public static UnconfiguredRendererEndpoint assembleNotConfigurableRendererEPForPeer(final PolicyConfigurationContext context, final PeerEndpoint peerEndpoint, final String info) { final RendererEndpoint rendererEndpoint = context.getCurrentRendererEP(); - LOG.trace("not configurable EP for peer: {}", info); + LOG.trace("Not configurable EP for peer: {}", info); return new UnconfiguredRendererEndpointBuilder(rendererEndpoint) - .setUnconfiguredPeerEndpoint(assemblePeerEndpoint(Stream.of(peerEndpoint))) + .setUnconfiguredPeerEndpoint(assemblePeerEndpoint(Stream.of(peerEndpoint), context)) .setInfo(info) .build(); } @VisibleForTesting - static List assemblePeerEndpoint(final Stream peerEndpoint) { + static List assemblePeerEndpoint(final Stream peerEndpoint, + final PolicyConfigurationContext context) { return peerEndpoint .map((peerEP) -> new UnconfiguredPeerEndpointBuilder(peerEP) .setUnconfiguredRuleGroup( - assembleRuleGroups(peerEP.getRuleGroupWithRendererEndpointParticipation().stream()) + assembleRuleGroups(peerEP.getRuleGroupWithRendererEndpointParticipation().stream(), context) ).build()) .collect(Collectors.toList()); } @VisibleForTesting - static List assembleRuleGroups(final Stream stream) { + static List assembleRuleGroups(final Stream stream, + final PolicyConfigurationContext context) { return stream .filter(Objects::nonNull) .map((ruleGroup) -> new UnconfiguredRuleGroupBuilder(ruleGroup) .setRendererEndpointParticipation(ruleGroup.getRendererEndpointParticipation()) - // TODO: find rule-group and append names of resolved rules ...setUnconfiguredResolvedRule() + .setUnconfiguredResolvedRule(assembleResolvedRule(Stream.of(context.getCurrentUnconfiguredRule()), context)) + .build()) + .collect(Collectors.toList()); + } + + @VisibleForTesting + private static List assembleResolvedRule(final Stream stream, + final PolicyConfigurationContext context) { + return stream + .filter(Objects::nonNull) + .map((unconfiguredRule) -> new UnconfiguredResolvedRuleBuilder(context.getCurrentUnconfiguredRule()) + .setRuleName(context.getCurrentUnconfiguredRule().getRuleName()) .build()) .collect(Collectors.toList()); } diff --git a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/PolicyWriter.java b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/PolicyWriter.java deleted file mode 100644 index 6532cdb81..000000000 --- a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/PolicyWriter.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -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; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; -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; -import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfName; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class PolicyWriter { - - private static final Logger LOG = LoggerFactory.getLogger(PolicyWriter.class); - - private final DataBroker mountpoint; - // Local cache - private final Set classMapEntries; - private final Set policyMapEntries; - private final Set remoteForwarders; - private final Set serviceChains; - private final NodeId nodeId; - private final String interfaceName; - private final String policyMapName; - private final String managementIpAddress; - - public PolicyWriter(final DataBroker dataBroker, final String interfaceName, final String ipAddress, - final String policyMapName, final NodeId nodeId) { - classMapEntries = new HashSet<>(); - policyMapEntries = new HashSet<>(); - remoteForwarders = new HashSet<>(); - serviceChains = new HashSet<>(); - - this.nodeId = Preconditions.checkNotNull(nodeId); - mountpoint = Preconditions.checkNotNull(dataBroker); - managementIpAddress = Preconditions.checkNotNull(ipAddress); - this.interfaceName = Preconditions.checkNotNull(interfaceName); - this.policyMapName = Preconditions.checkNotNull(policyMapName); - } - - public CheckedFuture commitToDatastore() { - LOG.debug("Configuring policy on node {}, interface {} ... ", nodeId.getValue(), interfaceName); - if (policyMapEntries.isEmpty()) { - LOG.debug("Policy map {} is empty, skipping", policyMapName); - return Futures.immediateCheckedFuture(true); - } - // SFC - boolean remoteResult = PolicyWriterUtil.writeRemote(remoteForwarders, nodeId, mountpoint); - boolean servicePathsResult = PolicyWriterUtil.writeServicePaths(serviceChains, nodeId, mountpoint); - // GBP - maintain order! - boolean classMapResult = PolicyWriterUtil.writeClassMaps(classMapEntries, nodeId, mountpoint); - boolean policyMapResult = PolicyWriterUtil.writePolicyMap(policyMapName, policyMapEntries, nodeId, mountpoint); - boolean interfaceResult = PolicyWriterUtil.writeInterface(policyMapName, interfaceName, nodeId, mountpoint); - // Result - LOG.info("Policy-map created on node {}, interface {}", nodeId.getValue(), interfaceName); - return Futures.immediateCheckedFuture(classMapResult && policyMapResult && interfaceResult && remoteResult - && servicePathsResult); - } - - public CheckedFuture removeFromDatastore() { - LOG.debug("Removing policy from node {}, interface {} ... ", nodeId.getValue(), interfaceName); - if (policyMapEntries.isEmpty()) { - 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); - // SFC - boolean remoteSffResult = PolicyWriterUtil.removeRemote(remoteForwarders, nodeId, mountpoint); - boolean servicePathsResult = PolicyWriterUtil.removeServicePaths(serviceChains, nodeId, mountpoint); - // Result - LOG.info("Policy-map removed from node {}, interface {}", nodeId.getValue(), interfaceName); - return Futures.immediateCheckedFuture(classMapResult && policyMapEntriesResult && servicePathsResult - && 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 getMountpoint() { - return mountpoint; - } - - public NodeId getNodeId() { - return nodeId; - } -} diff --git a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/PolicyWriterUtil.java b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/PolicyWriterUtil.java index f2cd57259..b3aee3464 100644 --- a/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/PolicyWriterUtil.java +++ b/renderers/ios-xe/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/PolicyWriterUtil.java @@ -8,8 +8,8 @@ package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer; +import javax.annotation.Nonnull; import java.util.List; -import java.util.Set; import com.google.common.base.Optional; import com.google.common.util.concurrent.CheckedFuture; import org.opendaylight.controller.md.sal.binding.api.DataBroker; @@ -18,6 +18,7 @@ import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil; import org.opendaylight.yang.gen.v1.urn.ios.rev160308.ClassNameType; import org.opendaylight.yang.gen.v1.urn.ios.rev160308.Native; @@ -46,56 +47,53 @@ import org.slf4j.LoggerFactory; /** * Purpose: Util class for every policy writer */ -class PolicyWriterUtil { +public class PolicyWriterUtil { private static final Logger LOG = LoggerFactory.getLogger(PolicyWriterUtil.class); - static boolean writeClassMaps(final Set classMapEntries, final NodeId nodeId, final DataBroker mountpoint) { + public static boolean writeClassMap(@Nonnull final ClassMap classMap, + final PolicyManagerImpl.PolicyMapLocation policyMapLocation) { boolean result = true; - if (classMapEntries == null || classMapEntries.isEmpty()) { - return true; - } - for (ClassMap entry : classMapEntries) { - final InstanceIdentifier classMapIid = classMapInstanceIdentifier(entry); - netconfWrite(mountpoint, classMapIid, entry); - // Check - final java.util.Optional checkCreated = java.util.Optional.ofNullable(netconfRead(mountpoint, classMapIid)); - if (checkCreated.isPresent()) { - LOG.trace("Created class-map {} on node {}", entry.getName(), nodeId.getValue()); - } - else { - LOG.warn("Failed to create class-map {} on node {}", entry.getName(), nodeId.getValue()); - result = false; - } + final DataBroker mountpoint = policyMapLocation.getMountpoint(); + final NodeId nodeId = policyMapLocation.getNodeId(); + final InstanceIdentifier classMapIid = classMapInstanceIdentifier(classMap); + netconfWrite(mountpoint, classMapIid, classMap); + // Check + final java.util.Optional checkCreated = java.util.Optional.ofNullable(netconfRead(mountpoint, classMapIid)); + if (checkCreated.isPresent()) { + LOG.trace("Created class-map {} on node {}", classMap.getName(), nodeId.getValue()); + } else { + LOG.warn("Failed to create class-map {} on node {}", classMap.getName(), nodeId.getValue()); + result = false; + } return result; } - static boolean removeClassMaps(final Set classMapEntries, final NodeId nodeId, final DataBroker mountpoint) { + public static boolean removeClassMap(final ClassMap classMap, final PolicyManagerImpl.PolicyMapLocation location) { + final DataBroker mountpoint = location.getMountpoint(); + final NodeId nodeId = location.getNodeId(); boolean result = true; - if (classMapEntries == null || classMapEntries.isEmpty()) { + if (classMap == null) { return true; } - for (ClassMap entry : classMapEntries) { - final InstanceIdentifier classMapIid = classMapInstanceIdentifier(entry); - netconfDeleteIfPresent(mountpoint, classMapIid); - // Check - final java.util.Optional checkCreated = java.util.Optional.ofNullable(netconfRead(mountpoint, classMapIid)); - if (checkCreated.isPresent()) { - LOG.warn("Failed to remove class-map {} on node {}", entry.getName(), nodeId.getValue()); - result = false; - } - else { - LOG.trace("Class-map {} removed from node {}", entry.getName(), nodeId.getValue()); - } + final InstanceIdentifier classMapIid = classMapInstanceIdentifier(classMap); + netconfDeleteIfPresent(mountpoint, classMapIid); + // Check + final java.util.Optional checkCreated = java.util.Optional.ofNullable(netconfRead(mountpoint, classMapIid)); + if (checkCreated.isPresent()) { + LOG.warn("Failed to remove class-map {} on node {}", classMap.getName(), nodeId.getValue()); + result = false; + } else { + LOG.trace("Class-map {} removed from node {}", classMap.getName(), nodeId.getValue()); } return result; } - static boolean writePolicyMap(final String policyMapName, final Set policyMapEntries, NodeId nodeId, - final DataBroker mountpoint) { - final PolicyMap policyMap = PolicyManagerUtil.createPolicyMap(policyMapName, policyMapEntries); - final InstanceIdentifier policyMapIid = policyMapInstanceIdentifier(policyMapName); + public static boolean writePolicyMap(final PolicyMap policyMap, final PolicyManagerImpl.PolicyMapLocation location) { + final DataBroker mountpoint = location.getMountpoint(); + final NodeId nodeId = location.getNodeId(); + final InstanceIdentifier policyMapIid = policyMapInstanceIdentifier(policyMap.getName()); netconfWrite(mountpoint, policyMapIid, policyMap); // Check if (netconfRead(mountpoint, policyMapIid) == null) { @@ -106,130 +104,177 @@ class PolicyWriterUtil { return true; } - static boolean removePolicyMapEntries(final String policyMapName, final Set policyMapEntries, - final NodeId nodeId, final DataBroker mountpoint) { - if (policyMapEntries == null || policyMapEntries.isEmpty()) { + public static boolean removePolicyMap(final PolicyManagerImpl.PolicyMapLocation location) { + final String policyMapName = location.getPolicyMapName(); + final DataBroker mountpoint = location.getMountpoint(); + final NodeId nodeId = location.getNodeId(); + final InstanceIdentifier policyMapIid = policyMapInstanceIdentifier(policyMapName); + netconfDeleteIfPresent(mountpoint, policyMapIid); + // Check + if (netconfRead(mountpoint, policyMapIid) != null) { + LOG.warn("Failed to remove policy-map {} from node {}", policyMapName, nodeId.getValue()); + return false; + } + LOG.trace("Policy-map {} removed from node {}", policyMapName, nodeId.getValue()); + return true; + } + + public static boolean writePolicyMapEntry(final Class policyMapEntry, + final PolicyManagerImpl.PolicyMapLocation location) { + final String policyMapName = location.getPolicyMapName(); + final NodeId nodeId = location.getNodeId(); + final DataBroker mountpoint = location.getMountpoint(); + final ClassNameType entryName = policyMapEntry.getName(); + final InstanceIdentifier policyMapEntryIid = policyMapEntryInstanceIdentifier(policyMapName, entryName); + netconfWrite(mountpoint, policyMapEntryIid, policyMapEntry); + // Check + if (netconfRead(mountpoint, policyMapEntryIid) == null) { + LOG.warn("Failed to create entry in policy-map {} on node {}. Entry: {}", policyMapName, nodeId.getValue(), + policyMapEntry); + return false; + } + LOG.trace("Created entry in policy-map {} on node {}. Entry: {}", policyMapName, nodeId.getValue(), policyMapEntry); + return true; + } + + public static boolean removePolicyMapEntry(final Class policyMapEntry, final PolicyManagerImpl.PolicyMapLocation location) { + final String policyMapName = location.getPolicyMapName(); + final DataBroker mountpoint = location.getMountpoint(); + final NodeId nodeId = location.getNodeId(); + if (policyMapEntry == null) { return true; } boolean result = true; - for (Class entry : policyMapEntries) { - final InstanceIdentifier policyMapEntryIid = policyMapEntryInstanceIdentifier(policyMapName, entry.getName()); - if (netconfDeleteIfPresent(mountpoint, policyMapEntryIid)) { - LOG.trace("Policy-map entry {} removed from node {}", entry.getName(), nodeId.getValue()); - } - else { - LOG.warn("Failed to remove policy-map entry {} from node {}", entry.getName(), nodeId.getValue()); - result = false; - } + final InstanceIdentifier policyMapEntryIid = policyMapEntryInstanceIdentifier(policyMapName, policyMapEntry.getName()); + if (netconfDeleteIfPresent(mountpoint, policyMapEntryIid)) { + LOG.trace("Policy-map entry {} removed from node {}", policyMapEntry.getName(), nodeId.getValue()); + } else { + LOG.warn("Failed to remove policy-map entry {} from node {}", policyMapEntry.getName(), nodeId.getValue()); + result = false; } return result; } - static boolean writeInterface(final String policyMapName, final String interfaceName, final NodeId nodeId, - final DataBroker mountpoint) { + public static boolean writeInterface(final PolicyManagerImpl.PolicyMapLocation location) { + final String policyMapName = location.getPolicyMapName(); + final String interfaceName = location.getInterfaceName(); + final NodeId nodeId = location.getNodeId(); + final DataBroker mountpoint = location.getMountpoint(); final ServicePolicy servicePolicy = PolicyManagerUtil.createServicePolicy(policyMapName, Direction.Input); final InstanceIdentifier servicePolicyIid = interfaceInstanceIdentifier(interfaceName); if (netconfWrite(mountpoint, servicePolicyIid, servicePolicy)) { LOG.trace("Service-policy interface {}, bound to policy-map {} created on node {}", interfaceName, policyMapName, nodeId.getValue()); return true; - } - else { + } else { LOG.warn("Failed to write service-policy interface {} to policy-map {} on node {}", interfaceName, policyMapName, nodeId.getValue()); return false; } } - static boolean writeRemote(final Set remoteForwarders, final NodeId nodeId, - final DataBroker mountpoint) { - if (remoteForwarders == null || remoteForwarders.isEmpty()) { + public static boolean removeInterface(final PolicyManagerImpl.PolicyMapLocation location) { + final String policyMapName = location.getPolicyMapName(); + final String interfaceName = location.getInterfaceName(); + final DataBroker mountpoint = location.getMountpoint(); + final NodeId nodeId = location.getNodeId(); + final InstanceIdentifier servicePolicyIid = interfaceInstanceIdentifier(interfaceName); + if (netconfDeleteIfPresent(mountpoint, servicePolicyIid)) { + LOG.trace("Service-policy interface {}, removed from node {}", + interfaceName, policyMapName, nodeId.getValue()); + return true; + } else { + LOG.warn("Failed to remove service-policy interface {} from node {}", + interfaceName, policyMapName, nodeId.getValue()); + return false; + } + } + + public static boolean writeRemote(final ServiceFfName remoteForwarder, + final PolicyManagerImpl.PolicyMapLocation location) { + // TODO writeNE + final DataBroker mountpoint = location.getMountpoint(); + final NodeId nodeId = location.getNodeId(); + if (remoteForwarder == null) { return true; } boolean result = true; - for (ServiceFfName forwarder : remoteForwarders) { - final InstanceIdentifier forwarderIid = remoteSffInstanceIdentifier(forwarder); - if (netconfWrite(mountpoint, forwarderIid, forwarder)) { - LOG.trace("Remote forwarder {} created on node {}", forwarder.getName(), nodeId.getValue()); - } - else { - LOG.warn("Failed to create remote forwarder {} on node {}", forwarder.getName(), nodeId.getValue()); - result = false; - } + final InstanceIdentifier forwarderIid = remoteSffInstanceIdentifier(remoteForwarder); + if (netconfWrite(mountpoint, forwarderIid, remoteForwarder)) { + LOG.trace("Remote forwarder {} created on node {}", remoteForwarder.getName(), nodeId.getValue()); + } else { + LOG.warn("Failed to create remote forwarder {} on node {}", remoteForwarder.getName(), nodeId.getValue()); + result = false; } return result; } - static boolean removeRemote(final Set remoteForwarders, final NodeId nodeId, - final DataBroker mountpoint) { - if (remoteForwarders == null || remoteForwarders.isEmpty()) { + public static boolean removeRemote(final ServiceFfName remoteForwarder, final PolicyManagerImpl.PolicyMapLocation location) { + final DataBroker mountpoint = location.getMountpoint(); + final NodeId nodeId = location.getNodeId(); + if (remoteForwarder == null) { return true; } boolean result = true; - for (ServiceFfName forwarder : remoteForwarders) { - final InstanceIdentifier forwarderIid = remoteSffInstanceIdentifier(forwarder); - if (netconfDeleteIfPresent(mountpoint, forwarderIid)) { - LOG.trace("Remote forwarder {} removed from node {}", forwarder.getName(), nodeId.getValue()); - } - else { - LOG.warn("Failed to remove forwarder {} from node {}", forwarder.getName(), nodeId.getValue()); - result = false; - } + final InstanceIdentifier forwarderIid = remoteSffInstanceIdentifier(remoteForwarder); + if (netconfDeleteIfPresent(mountpoint, forwarderIid)) { + LOG.trace("Remote forwarder {} removed from node {}", remoteForwarder.getName(), nodeId.getValue()); + } else { + LOG.warn("Failed to remove forwarder {} from node {}", remoteForwarder.getName(), nodeId.getValue()); + result = false; } return result; } - static boolean writeServicePaths(final Set serviceChains, final NodeId nodeId, - final DataBroker mountpoint) { + public static boolean writeServicePath(final ServiceChain serviceChain, + final PolicyManagerImpl.PolicyMapLocation location) { + final DataBroker mountpoint = location.getMountpoint(); + final NodeId nodeId = location.getNodeId(); boolean result = true; - for (org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain serviceChain : serviceChains) { - for (ServicePath entry : serviceChain.getServicePath()) { - final InstanceIdentifier servicePathIid = servicePathInstanceIdentifier(entry.getKey()); - if (netconfWrite(mountpoint, servicePathIid, entry)) { - LOG.trace("Service-path with ID: {} created on node {}", entry.getServicePathId(), nodeId.getValue()); - } - else { - LOG.warn("Failed to create service-path with ID: {} on node {}", entry.getServicePathId(), nodeId.getValue()); - result = false; - } + for (ServicePath entry : serviceChain.getServicePath()) { + final InstanceIdentifier servicePathIid = servicePathInstanceIdentifier(entry.getKey()); + if (netconfWrite(mountpoint, servicePathIid, entry)) { + LOG.trace("Service-path with ID: {} created on node {}", entry.getServicePathId(), nodeId.getValue()); + } else { + LOG.warn("Failed to create service-path with ID: {} on node {}", entry.getServicePathId(), nodeId.getValue()); + result = false; } } return result; } - static boolean removeServicePaths(final Set serviceChains, final NodeId nodeId, - final DataBroker mountpoint) { - if (serviceChains == null || serviceChains.isEmpty()) { + public static boolean removeServicePath(final ServiceChain serviceChain, final PolicyManagerImpl.PolicyMapLocation location) { + final DataBroker mountpoint = location.getMountpoint(); + final NodeId nodeId = location.getNodeId(); + if (serviceChain == null) { return true; } boolean result = true; - for (ServiceChain chain : serviceChains) { - List servicePaths = chain.getServicePath(); - if (servicePaths == null || servicePaths.isEmpty()) { - continue; - } - for (ServicePath servicePath : servicePaths) { - final InstanceIdentifier servicePathIid = servicePathInstanceIdentifier(servicePath.getKey()); - if (netconfDeleteIfPresent(mountpoint, servicePathIid)) { - LOG.trace("Service-path with ID: {} removed from node {}", servicePath.getServicePathId(), - nodeId.getValue()); - } - else { - LOG.warn("Failed to remove service-path with ID: {} from node {}", servicePath.getServicePathId(), - nodeId.getValue()); - result = false; - } + List servicePaths = serviceChain.getServicePath(); + if (servicePaths == null || servicePaths.isEmpty()) { + return true; + } + for (ServicePath servicePath : servicePaths) { + final InstanceIdentifier servicePathIid = servicePathInstanceIdentifier(servicePath.getKey()); + if (netconfDeleteIfPresent(mountpoint, servicePathIid)) { + LOG.trace("Service-path with ID: {} removed from node {}", servicePath.getServicePathId(), + nodeId.getValue()); + } else { + LOG.warn("Failed to remove service-path with ID: {} from node {}", servicePath.getServicePathId(), + nodeId.getValue()); + result = false; } } return result; } + private static InstanceIdentifier classMapInstanceIdentifier(final ClassMap classMap) { return InstanceIdentifier.builder(Native.class) .child(ClassMap.class, new ClassMapKey(classMap.getName())).build(); } - private static InstanceIdentifier policyMapInstanceIdentifier(final String policyMapName) { + public static InstanceIdentifier policyMapInstanceIdentifier(final String policyMapName) { return InstanceIdentifier.builder(Native.class) .child(PolicyMap.class, new PolicyMapKey(policyMapName)).build(); } @@ -241,7 +286,7 @@ class PolicyWriterUtil { .child(Class.class, new ClassKey(classNameType)).build(); } - private static InstanceIdentifier interfaceInstanceIdentifier(final String ethernetName) { + public static InstanceIdentifier interfaceInstanceIdentifier(final String ethernetName) { return InstanceIdentifier.builder(Native.class) .child(Interface.class) .child(GigabitEthernet.class, new GigabitEthernetKey(ethernetName)) @@ -263,8 +308,9 @@ class PolicyWriterUtil { } private static boolean netconfWrite(final DataBroker mountpoint, - final InstanceIdentifier addIID, - final U data) { + final InstanceIdentifier addIID, + final U data) { + // TODO consider to move netconfWrite, netconfDeleteIfPresent and netconfRead methods (+ methods in NetconfTransactionCreator) to gbp base final java.util.Optional optionalWriteTransaction = NetconfTransactionCreator.netconfWriteOnlyTransaction(mountpoint); if (!optionalWriteTransaction.isPresent()) { @@ -312,8 +358,8 @@ class PolicyWriterUtil { return false; } - private static U netconfRead(final DataBroker mountpoint, - final InstanceIdentifier readIID) { + public static U netconfRead(final DataBroker mountpoint, + final InstanceIdentifier readIID) { final java.util.Optional optionalReadTransaction = NetconfTransactionCreator.netconfReadOnlyTransaction(mountpoint); if (!optionalReadTransaction.isPresent()) { diff --git a/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyManagerImplTest.java b/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyManagerImplTest.java index c58e86382..f28d307c0 100644 --- a/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyManagerImplTest.java +++ b/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/manager/PolicyManagerImplTest.java @@ -17,6 +17,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.RendererPolicyUtil; @@ -114,16 +115,16 @@ public class PolicyManagerImplTest { private PolicyManagerImpl policyManager; private DataBroker mountpoint; private NodeManager nodeManager; - private WriteTransaction writeTransaction; + private ReadWriteTransaction readWriteTransaction; @Before public void init() { mountpoint = mock(DataBroker.class); - writeTransaction = mock(WriteTransaction.class); + readWriteTransaction = mock(ReadWriteTransaction.class); nodeManager = mock(NodeManager.class); policyManager = new PolicyManagerImpl(mountpoint, nodeManager); - when(mountpoint.newWriteOnlyTransaction()).thenReturn(writeTransaction); - when(writeTransaction.submit()).thenReturn(Futures.immediateCheckedFuture((Void) null)); + when(mountpoint.newReadWriteTransaction()).thenReturn(readWriteTransaction); + when(readWriteTransaction.submit()).thenReturn(Futures.immediateCheckedFuture((Void) null)); } @Test @@ -265,7 +266,7 @@ public class PolicyManagerImplTest { ServiceFunctionPath sfp = createServiceFunctionPath(); stub(method(ServiceChainingUtil.class, "findServicePathFromParameterValues")).toReturn(sfp); RenderedServicePath rsp = createRenderedServicePath(); - stub(method(ServiceChainingUtil.class, "createRenderedPath")).toReturn(rsp); + stub(method(ServiceChainingUtil.class, "resolveRenderedServicePath")).toReturn(rsp); ServiceFunctionForwarder serviceFunctionForwarder = createServiceForwarder(); stub(method(SfcProviderServiceForwarderAPI.class, "readServiceFunctionForwarder")) .toReturn(serviceFunctionForwarder); diff --git a/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/PolicyManagerUtilTest.java b/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/PolicyManagerUtilTest.java index ac248b9bf..ac95a22ea 100644 --- a/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/PolicyManagerUtilTest.java +++ b/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/PolicyManagerUtilTest.java @@ -8,9 +8,11 @@ package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util; +import static org.junit.Assert.assertNotNull; + +import java.util.Collections; import com.google.common.base.Optional; import com.google.common.util.concurrent.Futures; -import java.util.Collections; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -25,6 +27,8 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; 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.sfc.provider.OpendaylightSfc; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfcName; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfpName; @@ -40,10 +44,10 @@ 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.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.sxp.database.rev160308.Sgt; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import static org.junit.Assert.assertNotNull; - /** * Test for {@link PolicyManagerUtil}. */ @@ -96,15 +100,23 @@ public class PolicyManagerUtilTest { @Test public void testCreateRenderedPath() throws Exception { + final String POLICY_MAP = "policy-map"; + final String INTERFACE = "interface"; + final NodeId nodeId = new NodeId("node-id"); + final String IP_ADDRESS = "ip-address"; final TenantId tenantId = new TenantId("tenant-id-01"); final RenderedServicePath renderedSP = new RenderedServicePathBuilder().build(); + final PolicyManagerImpl.PolicyMapLocation location = new PolicyManagerImpl.PolicyMapLocation(POLICY_MAP, INTERFACE, + nodeId, IP_ADDRESS, dataBroker); + final PolicyConfigurationContext context = new PolicyConfigurationContext(); + context.setPolicyMapLocation(location); Mockito.when(dataBroker.newReadOnlyTransaction()).thenReturn(roTx); Mockito.when(roTx.read(Matchers.eq(LogicalDatastoreType.OPERATIONAL), rendererServicePathIICaptor.capture())) .thenReturn(Futures.immediateCheckedFuture(Optional.of(renderedSP))); - final RenderedServicePath renderedPath = ServiceChainingUtil.createRenderedPath(serviceFunctionPath, tenantId, - dataBroker); + final RenderedServicePath renderedPath = ServiceChainingUtil.resolveRenderedServicePath(serviceFunctionPath, tenantId, + dataBroker, new Sgt(1), new Sgt(2), context); Assert.assertEquals(renderedSP, renderedPath); final InstanceIdentifier ii = rendererServicePathIICaptor.getValue(); Assert.assertEquals("sfp-name-01-tenant-id-01-gbp-rsp", ii.firstKeyOf(RenderedServicePath.class).getName().getValue()); @@ -112,6 +124,14 @@ public class PolicyManagerUtilTest { @Test public void testCreateSymmetricRenderedPath() throws Exception { + final String POLICY_MAP = "policy-map"; + final String INTERFACE = "interface"; + final NodeId nodeId = new NodeId("node-id"); + final String IP_ADDRESS = "ip-address"; + final PolicyManagerImpl.PolicyMapLocation location = new PolicyManagerImpl.PolicyMapLocation(POLICY_MAP, INTERFACE, + nodeId, IP_ADDRESS, dataBroker); + final PolicyConfigurationContext context = new PolicyConfigurationContext(); + context.setPolicyMapLocation(location); final RenderedServicePath renderedServicePath = new RenderedServicePathBuilder().build(); final TenantId tenantId = new TenantId("tenant-id-02"); @@ -119,9 +139,8 @@ public class PolicyManagerUtilTest { Mockito.when(roTx.read(Matchers.eq(LogicalDatastoreType.OPERATIONAL), rendererServicePathIICaptor.capture())) .thenReturn(Futures.immediateCheckedFuture(Optional.of(renderedServicePath))); - - final RenderedServicePath symmetricRenderedPath = ServiceChainingUtil.createReversedRenderedPath( - serviceFunctionPath, renderedServicePath, tenantId, dataBroker); + final RenderedServicePath symmetricRenderedPath = ServiceChainingUtil.resolveReversedRenderedServicePath( + serviceFunctionPath, tenantId, dataBroker, new Sgt(1), new Sgt(2), context); Assert.assertEquals(renderedServicePath, symmetricRenderedPath); final InstanceIdentifier ii = rendererServicePathIICaptor.getValue(); Assert.assertEquals("sfp-name-01-tenant-id-02-gbp-rsp-Reverse", ii.firstKeyOf(RenderedServicePath.class).getName().getValue()); diff --git a/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/ServiceChainingUtilTest.java b/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/ServiceChainingUtilTest.java index ddaa2e069..6e9f6746c 100644 --- a/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/ServiceChainingUtilTest.java +++ b/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/ServiceChainingUtilTest.java @@ -15,14 +15,14 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.verifyZeroInteractions; import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.ActionCase.ALLOW; import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.ActionCase.CHAIN; 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.PROVIDER; +import static org.powermock.api.mockito.PowerMockito.verifyStatic; import static org.powermock.api.support.membermodification.MemberMatcher.method; import static org.powermock.api.support.membermodification.MemberModifier.stub; @@ -41,9 +41,10 @@ import org.mockito.Mock; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; 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.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil.ActionInDirection; -import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriter; +import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriterUtil; import org.opendaylight.sfc.provider.api.SfcProviderRenderedPathAPI; import org.opendaylight.sfc.provider.api.SfcProviderServiceForwarderAPI; import org.opendaylight.sfc.provider.api.SfcProviderServicePathAPI; @@ -75,6 +76,7 @@ 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.function.forwarder.ServiceFfNameBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfNameKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.RuleName; 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; @@ -86,6 +88,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.r 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; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @@ -99,7 +102,7 @@ import org.powermock.modules.junit4.PowerMockRunner; SfcProviderServicePathAPI.class, SfcProviderRenderedPathAPI.class, PolicyManagerUtil.class, - PolicyWriter.class + PolicyWriterUtil.class }) public class ServiceChainingUtilTest { @@ -108,9 +111,10 @@ public class ServiceChainingUtilTest { private final String TENANT_ID = "tenant-id"; private final String IP_ADDRESS = "170.0.0.1"; private final String SERVICE_FUNCTION_FORWARDER = "service-function-forwarder"; + private final RuleName RULE_NAME = new RuleName("rule-name"); private DataBroker dataBroker; - private PolicyWriter policyWriter; + private PolicyWriterUtil policyWriterUtil; @Captor @@ -133,7 +137,7 @@ public class ServiceChainingUtilTest { @Before public void setUp() { dataBroker = mock(DataBroker.class); - policyWriter = mock(PolicyWriter.class); + policyWriterUtil = mock(PolicyWriterUtil.class); } @Test @@ -142,10 +146,10 @@ public class ServiceChainingUtilTest { final Action action = actionBuilder(null); final PolicyConfigurationContext context = policyConfigurationContextBuilder(); - ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sgtBuilder(10), sgtBuilder(20), - resolvedActionBuilder(ALLOW, action, In), context, dataBroker); + ServiceChainingUtil.newChainAction(peerEndpoint, sgtBuilder(10), sgtBuilder(20), + resolvedActionBuilder(RULE_NAME, ALLOW, action, In), context, dataBroker); - verifyNoMoreInteractions(policyWriter); + verifyNoMoreInteractions(policyWriterUtil); verifyNoMoreInteractions(dataBroker); } @@ -155,10 +159,10 @@ public class ServiceChainingUtilTest { final Action action = actionBuilder(null); final PolicyConfigurationContext context = policyConfigurationContextBuilder(); - ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sgtBuilder(10), sgtBuilder(20), - resolvedActionBuilder(CHAIN, action, In), context, dataBroker); + ServiceChainingUtil.newChainAction(peerEndpoint, sgtBuilder(10), sgtBuilder(20), + resolvedActionBuilder(RULE_NAME, CHAIN, action, In), context, dataBroker); - verifyNoMoreInteractions(policyWriter); + verifyNoMoreInteractions(policyWriterUtil); verifyNoMoreInteractions(dataBroker); } @@ -180,10 +184,10 @@ public class ServiceChainingUtilTest { stub(method(SfcProviderServicePathAPI.class, "readAllServiceFunctionPaths")).toReturn(pathsBuilder.build()); stub(method(PolicyManagerUtil.class, "getTenantId")).toReturn(null); - ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sgtBuilder(10), sgtBuilder(20), - resolvedActionBuilder(CHAIN, action, In), context, dataBroker); + ServiceChainingUtil.newChainAction(peerEndpoint, sgtBuilder(10), sgtBuilder(20), + resolvedActionBuilder(RULE_NAME, CHAIN, action, In), context, dataBroker); - verifyNoMoreInteractions(policyWriter); + verifyNoMoreInteractions(policyWriterUtil); verifyNoMoreInteractions(dataBroker); } @@ -206,10 +210,10 @@ public class ServiceChainingUtilTest { stub(method(SfcProviderServicePathAPI.class, "readAllServiceFunctionPaths")).toReturn(pathsBuilder.build()); stub(method(PolicyManagerUtil.class, "getTenantId")).toReturn(new TenantId(TENANT_ID)); - ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sgtBuilder(10), sgtBuilder(20), - resolvedActionBuilder(CHAIN, action, In), context, dataBroker); + ServiceChainingUtil.newChainAction(peerEndpoint, sgtBuilder(10), sgtBuilder(20), + resolvedActionBuilder(RULE_NAME, CHAIN, action, In), context, dataBroker); - verifyNoMoreInteractions(policyWriter); + verifyNoMoreInteractions(policyWriterUtil); verifyNoMoreInteractions(dataBroker); } @@ -230,16 +234,15 @@ public class ServiceChainingUtilTest { final PolicyConfigurationContext context = policyConfigurationContextBuilder(); stub(method(SfcProviderServicePathAPI.class, "readAllServiceFunctionPaths")).toReturn(pathsBuilder.build()); - stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(buildRsp(null)); - stub(method(PolicyManagerUtil.class, "getTenantId")).toReturn(new TenantId(TENANT_ID)); + stub(method(PolicyWriterUtil.class, "writeClassMap")).toReturn(true); + stub(method(PolicyWriterUtil.class, "writePolicyMapEntry")).toReturn(true); - ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sgtBuilder(10), sgtBuilder(20), - resolvedActionBuilder(CHAIN, action, Out), context, dataBroker); + ServiceChainingUtil.newChainAction(peerEndpoint, sgtBuilder(10), sgtBuilder(20), + resolvedActionBuilder(RULE_NAME, CHAIN, action, Out), context, dataBroker); - verify(policyWriter).cache(any(ClassMap.class)); - verify(policyWriter).cache(any(Class.class)); - verifyNoMoreInteractions(policyWriter); - verifyNoMoreInteractions(dataBroker); + verifyStatic(times(1)); + PolicyWriterUtil.writeClassMap(any(ClassMap.class), any(PolicyManagerImpl.PolicyMapLocation.class)); + PolicyWriterUtil.writePolicyMapEntry(any(Class.class), any(PolicyManagerImpl.PolicyMapLocation.class)); } @Test @@ -259,16 +262,15 @@ public class ServiceChainingUtilTest { final PolicyConfigurationContext context = policyConfigurationContextBuilder(); stub(method(SfcProviderServicePathAPI.class, "readAllServiceFunctionPaths")).toReturn(pathsBuilder.build()); - stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(buildRsp(null)); - stub(method(PolicyManagerUtil.class, "getTenantId")).toReturn(new TenantId(TENANT_ID)); + stub(method(PolicyWriterUtil.class, "writeClassMap")).toReturn(true); + stub(method(PolicyWriterUtil.class, "writePolicyMapEntry")).toReturn(true); - ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sgtBuilder(10), sgtBuilder(20), - resolvedActionBuilder(CHAIN, action, Out), context, dataBroker); + ServiceChainingUtil.newChainAction(peerEndpoint, sgtBuilder(10), sgtBuilder(20), + resolvedActionBuilder(RULE_NAME, CHAIN, action, Out), context, dataBroker); - verify(policyWriter).cache(any(ClassMap.class)); - verify(policyWriter).cache(any(Class.class)); - verifyNoMoreInteractions(policyWriter); - verifyNoMoreInteractions(dataBroker); + verifyStatic(times(1)); + PolicyWriterUtil.writeClassMap(any(ClassMap.class), any(PolicyManagerImpl.PolicyMapLocation.class)); + PolicyWriterUtil.writePolicyMapEntry(any(Class.class), any(PolicyManagerImpl.PolicyMapLocation.class)); } @Test @@ -288,31 +290,34 @@ public class ServiceChainingUtilTest { final PolicyConfigurationContext context = policyConfigurationContextBuilder(); stub(method(SfcProviderServicePathAPI.class, "readAllServiceFunctionPaths")).toReturn(pathsBuilder.build()); - stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(buildRsp(null)); - stub(method(PolicyManagerUtil.class, "getTenantId")).toReturn(new TenantId(TENANT_ID)); + stub(method(PolicyWriterUtil.class, "writeClassMap")).toReturn(true); + stub(method(PolicyWriterUtil.class, "writePolicyMapEntry")).toReturn(true); - ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sgtBuilder(10), sgtBuilder(20), - resolvedActionBuilder(CHAIN, action, In), context, dataBroker); + ServiceChainingUtil.newChainAction(peerEndpoint, sgtBuilder(10), sgtBuilder(20), + resolvedActionBuilder(RULE_NAME, CHAIN, action, In), context, dataBroker); - verify(policyWriter).cache(any(ClassMap.class)); - verify(policyWriter).cache(any(Class.class)); - verifyNoMoreInteractions(policyWriter); - verifyNoMoreInteractions(dataBroker); + verifyStatic(times(1)); + PolicyWriterUtil.writeClassMap(any(ClassMap.class), any(PolicyManagerImpl.PolicyMapLocation.class)); + PolicyWriterUtil.writePolicyMapEntry(any(Class.class), any(PolicyManagerImpl.PolicyMapLocation.class)); } @Test public void testResolveRemovedChainAction_noParameterValue() { + final PolicyConfigurationContext context = new PolicyConfigurationContext(); + context.setPolicyMapLocation(getLocation()); final PeerEndpoint peerEndpoint = peerEndpointBuilder(); final Action action = actionBuilder(null); ServiceChainingUtil.resolveRemovedChainAction(peerEndpoint, sgtBuilder(10), sgtBuilder(20), - resolvedActionBuilder(CHAIN, action, In), policyWriter); + resolvedActionBuilder(new RuleName("rule-name"), CHAIN, action, In), context); - verifyNoMoreInteractions(policyWriter); + verifyNoMoreInteractions(policyWriterUtil); } @Test public void testResolveRemovedChainAction_noTenantId() { + final PolicyConfigurationContext context = new PolicyConfigurationContext(); + context.setPolicyMapLocation(getLocation()); final ParameterValueBuilder parameterValueBuilder = new ParameterValueBuilder(); parameterValueBuilder.setName(new ParameterName(SFC_CHAIN_NAME)).setStringValue(SFC_CHAIN_NAME); final ParameterValue parameterValue = parameterValueBuilder.build(); @@ -329,13 +334,15 @@ public class ServiceChainingUtilTest { stub(method(PolicyManagerUtil.class, "getTenantId")).toReturn(null); ServiceChainingUtil.resolveRemovedChainAction(peerEndpoint, sgtBuilder(10), sgtBuilder(20), - resolvedActionBuilder(CHAIN, action, In), policyWriter); + resolvedActionBuilder(new RuleName("rule-name"), CHAIN, action, In), context); - verifyNoMoreInteractions(policyWriter); + verifyNoMoreInteractions(policyWriterUtil); } @Test public void testResolveRemovedChainAction_asymmetricChainOpposite() { + final PolicyConfigurationContext context = new PolicyConfigurationContext(); + context.setPolicyMapLocation(getLocation()); final ParameterValueBuilder parameterValueBuilder = new ParameterValueBuilder(); parameterValueBuilder.setName(new ParameterName(SFC_CHAIN_NAME)).setStringValue(SFC_CHAIN_NAME); final ParameterValue parameterValue = parameterValueBuilder.build(); @@ -353,13 +360,15 @@ public class ServiceChainingUtilTest { stub(method(PolicyManagerUtil.class, "getTenantId")).toReturn(new TenantId(TENANT_ID)); ServiceChainingUtil.resolveRemovedChainAction(peerEndpoint, sgtBuilder(10), sgtBuilder(20), - resolvedActionBuilder(CHAIN, action, In), policyWriter); + resolvedActionBuilder(new RuleName("rule-name"), CHAIN, action, In), context); - verifyNoMoreInteractions(policyWriter); + verifyNoMoreInteractions(policyWriterUtil); } @Test public void testResolveRemovedChainAction_asymmetricChainDirect() { + final PolicyConfigurationContext context = new PolicyConfigurationContext(); + context.setPolicyMapLocation(getLocation()); final ParameterValueBuilder parameterValueBuilder = new ParameterValueBuilder(); parameterValueBuilder.setName(new ParameterName(SFC_CHAIN_NAME)).setStringValue(SFC_CHAIN_NAME); final ParameterValue parameterValue = parameterValueBuilder.build(); @@ -372,29 +381,30 @@ public class ServiceChainingUtilTest { final Action action = actionBuilder(Collections.singletonList(parameterValue)); final RenderedServicePathHopBuilder hopBuilder = new RenderedServicePathHopBuilder(); hopBuilder.setServiceFunctionForwarder(new SffName(SERVICE_FUNCTION_FORWARDER)); - final List hops = Collections.singletonList(hopBuilder.build()); final ServiceFunctionForwarderBuilder forwarder = new ServiceFunctionForwarderBuilder(); forwarder.setName(new SffName(SERVICE_FUNCTION_FORWARDER)) .setIpMgmtAddress(new IpAddress(new Ipv4Address(IP_ADDRESS))); stub(method(SfcProviderServicePathAPI.class, "readAllServiceFunctionPaths")).toReturn(pathsBuilder.build()); - stub(method(SfcProviderServiceForwarderAPI.class, "readServiceFunctionForwarder")).toReturn(forwarder.build()); - stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(buildRsp(hops)); - stub(method(PolicyManagerUtil.class, "getTenantId")).toReturn(new TenantId(TENANT_ID)); + stub(method(PolicyWriterUtil.class, "removeClassMap")).toReturn(true); + stub(method(PolicyWriterUtil.class, "removePolicyMapEntry")).toReturn(true); + stub(method(PolicyWriterUtil.class, "removeServicePath")).toReturn(true); + stub(method(PolicyWriterUtil.class, "removeRemote")).toReturn(true); ServiceChainingUtil.resolveRemovedChainAction(peerEndpoint, sgtBuilder(10), sgtBuilder(20), - resolvedActionBuilder(CHAIN, action, Out), policyWriter); + resolvedActionBuilder(new RuleName("rule-name"), CHAIN, action, Out), context); - verify(policyWriter).cache(any(ClassMap.class)); - verify(policyWriter).cache(any(Class.class)); - verify(policyWriter).getManagementIpAddress(); - verify(policyWriter).cache(any(ServiceChain.class)); - verify(policyWriter).cache(any(ServiceFfName.class)); - verifyNoMoreInteractions(policyWriter); + verifyStatic(times(1)); + PolicyWriterUtil.removeClassMap(any(ClassMap.class), any(PolicyManagerImpl.PolicyMapLocation.class)); + PolicyWriterUtil.removePolicyMapEntry(any(Class.class), any(PolicyManagerImpl.PolicyMapLocation.class)); + PolicyWriterUtil.removeServicePath(any(ServiceChain.class), any(PolicyManagerImpl.PolicyMapLocation.class)); + PolicyWriterUtil.removeRemote(any(ServiceFfName.class), any(PolicyManagerImpl.PolicyMapLocation.class)); } @Test public void testResolveRemovedChainAction_symmetricChainDirect() { + final PolicyConfigurationContext context = new PolicyConfigurationContext(); + context.setPolicyMapLocation(getLocation()); final ParameterValueBuilder parameterValueBuilder = new ParameterValueBuilder(); parameterValueBuilder.setName(new ParameterName(SFC_CHAIN_NAME)).setStringValue(SFC_CHAIN_NAME); final ParameterValue parameterValue = parameterValueBuilder.build(); @@ -407,29 +417,30 @@ public class ServiceChainingUtilTest { final Action action = actionBuilder(Collections.singletonList(parameterValue)); final RenderedServicePathHopBuilder hopBuilder = new RenderedServicePathHopBuilder(); hopBuilder.setServiceFunctionForwarder(new SffName(SERVICE_FUNCTION_FORWARDER)); - final List hops = Collections.singletonList(hopBuilder.build()); final ServiceFunctionForwarderBuilder forwarder = new ServiceFunctionForwarderBuilder(); forwarder.setName(new SffName(SERVICE_FUNCTION_FORWARDER)) .setIpMgmtAddress(new IpAddress(new Ipv4Address(IP_ADDRESS))); stub(method(SfcProviderServicePathAPI.class, "readAllServiceFunctionPaths")).toReturn(pathsBuilder.build()); - stub(method(SfcProviderServiceForwarderAPI.class, "readServiceFunctionForwarder")).toReturn(forwarder.build()); - stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(buildRsp(hops)); - stub(method(PolicyManagerUtil.class, "getTenantId")).toReturn(new TenantId(TENANT_ID)); + stub(method(PolicyWriterUtil.class, "removeClassMap")).toReturn(true); + stub(method(PolicyWriterUtil.class, "removePolicyMapEntry")).toReturn(true); + stub(method(PolicyWriterUtil.class, "removeServicePath")).toReturn(true); + stub(method(PolicyWriterUtil.class, "removeRemote")).toReturn(true); ServiceChainingUtil.resolveRemovedChainAction(peerEndpoint, sgtBuilder(10), sgtBuilder(20), - resolvedActionBuilder(CHAIN, action, Out), policyWriter); + resolvedActionBuilder(new RuleName("rule-name"), CHAIN, action, Out), context); - verify(policyWriter).cache(any(ClassMap.class)); - verify(policyWriter).cache(any(Class.class)); - verify(policyWriter).getManagementIpAddress(); - verify(policyWriter).cache(any(ServiceChain.class)); - verify(policyWriter).cache(any(ServiceFfName.class)); - verifyNoMoreInteractions(policyWriter); + verifyStatic(times(1)); + PolicyWriterUtil.removeClassMap(any(ClassMap.class), any(PolicyManagerImpl.PolicyMapLocation.class)); + PolicyWriterUtil.removePolicyMapEntry(any(Class.class), any(PolicyManagerImpl.PolicyMapLocation.class)); + PolicyWriterUtil.removeServicePath(any(ServiceChain.class), any(PolicyManagerImpl.PolicyMapLocation.class)); + PolicyWriterUtil.removeRemote(any(ServiceFfName.class), any(PolicyManagerImpl.PolicyMapLocation.class)); } @Test public void testResolveRemovedChainAction_symmetricChainReversed() { + final PolicyConfigurationContext context = new PolicyConfigurationContext(); + context.setPolicyMapLocation(getLocation()); final ParameterValueBuilder parameterValueBuilder = new ParameterValueBuilder(); parameterValueBuilder.setName(new ParameterName(SFC_CHAIN_NAME)).setStringValue(SFC_CHAIN_NAME); final ParameterValue parameterValue = parameterValueBuilder.build(); @@ -442,35 +453,38 @@ public class ServiceChainingUtilTest { final Action action = actionBuilder(Collections.singletonList(parameterValue)); final RenderedServicePathHopBuilder hopBuilder = new RenderedServicePathHopBuilder(); hopBuilder.setServiceFunctionForwarder(new SffName(SERVICE_FUNCTION_FORWARDER)); - final List hops = Collections.singletonList(hopBuilder.build()); final ServiceFunctionForwarderBuilder forwarder = new ServiceFunctionForwarderBuilder(); forwarder.setName(new SffName(SERVICE_FUNCTION_FORWARDER)) .setIpMgmtAddress(new IpAddress(new Ipv4Address(IP_ADDRESS))); stub(method(SfcProviderServicePathAPI.class, "readAllServiceFunctionPaths")).toReturn(pathsBuilder.build()); - stub(method(SfcProviderServiceForwarderAPI.class, "readServiceFunctionForwarder")).toReturn(forwarder.build()); - stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(buildRsp(hops)); - stub(method(PolicyManagerUtil.class, "getTenantId")).toReturn(new TenantId(TENANT_ID)); + stub(method(PolicyWriterUtil.class, "removeClassMap")).toReturn(true); + stub(method(PolicyWriterUtil.class, "removePolicyMapEntry")).toReturn(true); + stub(method(PolicyWriterUtil.class, "removeServicePath")).toReturn(true); + stub(method(PolicyWriterUtil.class, "removeRemote")).toReturn(true); ServiceChainingUtil.resolveRemovedChainAction(peerEndpoint, sgtBuilder(10), sgtBuilder(20), - resolvedActionBuilder(CHAIN, action, In), policyWriter); + resolvedActionBuilder(new RuleName("rule-name"), CHAIN, action, In), context); - verify(policyWriter).cache(any(ClassMap.class)); - verify(policyWriter).cache(any(Class.class)); - verify(policyWriter).getManagementIpAddress(); - verify(policyWriter).cache(any(ServiceChain.class)); - verify(policyWriter).cache(any(ServiceFfName.class)); - verifyNoMoreInteractions(policyWriter); + verifyStatic(times(1)); + PolicyWriterUtil.removeClassMap(any(ClassMap.class), any(PolicyManagerImpl.PolicyMapLocation.class)); + PolicyWriterUtil.removePolicyMapEntry(any(Class.class), any(PolicyManagerImpl.PolicyMapLocation.class)); + PolicyWriterUtil.removeServicePath(any(ServiceChain.class), any(PolicyManagerImpl.PolicyMapLocation.class)); + PolicyWriterUtil.removeRemote(any(ServiceFfName.class), any(PolicyManagerImpl.PolicyMapLocation.class)); } @Test public void testResolveRemoteSfcComponents_noForwarder() { - boolean result = ServiceChainingUtil.resolveRemoteSfcComponents(buildRsp(null), policyWriter); + final PolicyConfigurationContext context = new PolicyConfigurationContext(); + context.setPolicyMapLocation(getLocation()); + boolean result = ServiceChainingUtil.resolveRemoteSfcComponents(buildRsp(), context); assertFalse(result); } @Test public void testResolveRemoteSfcComponents_noForwarderLocator() { + final PolicyConfigurationContext context = new PolicyConfigurationContext(); + context.setPolicyMapLocation(getLocation()); final ServiceFunctionForwarderBuilder forwarderBuilder = new ServiceFunctionForwarderBuilder(); forwarderBuilder.setName(new SffName(SERVICE_FUNCTION_FORWARDER)); final RenderedServicePathHopBuilder hopBuilder = new RenderedServicePathHopBuilder(); @@ -480,13 +494,14 @@ public class ServiceChainingUtilTest { stub(method(SfcProviderServiceForwarderAPI.class, "readServiceFunctionForwarder")).toReturn(forwarderBuilder.build()); - boolean result = ServiceChainingUtil.resolveRemoteSfcComponents(rspBuilder.build(), policyWriter); + boolean result = ServiceChainingUtil.resolveRemoteSfcComponents(rspBuilder.build(), context); assertFalse(result); - verifyZeroInteractions(policyWriter); } @Test public void testResolveRemoteSfcComponents_dplWithoutLocatorType() { + final PolicyConfigurationContext context = new PolicyConfigurationContext(); + context.setPolicyMapLocation(getLocation()); final DataPlaneLocatorBuilder dplBuilder = new DataPlaneLocatorBuilder(); final SffDataPlaneLocatorBuilder sffDplBuilder = new SffDataPlaneLocatorBuilder(); sffDplBuilder.setDataPlaneLocator(dplBuilder.build()); @@ -500,13 +515,14 @@ public class ServiceChainingUtilTest { stub(method(SfcProviderServiceForwarderAPI.class, "readServiceFunctionForwarder")).toReturn(forwarderBuilder.build()); - boolean result = ServiceChainingUtil.resolveRemoteSfcComponents(rspBuilder.build(), policyWriter); + boolean result = ServiceChainingUtil.resolveRemoteSfcComponents(rspBuilder.build(), context); assertFalse(result); - verifyZeroInteractions(policyWriter); } @Test public void testResolveRemoteSfcComponents_dplWithoutIp() { + final PolicyConfigurationContext context = new PolicyConfigurationContext(); + context.setPolicyMapLocation(getLocation()); final DataPlaneLocatorBuilder dplBuilder = new DataPlaneLocatorBuilder(); dplBuilder.setLocatorType(new IpBuilder().build()); final SffDataPlaneLocatorBuilder sffDplBuilder = new SffDataPlaneLocatorBuilder(); @@ -521,13 +537,14 @@ public class ServiceChainingUtilTest { stub(method(SfcProviderServiceForwarderAPI.class, "readServiceFunctionForwarder")).toReturn(forwarderBuilder.build()); - boolean result = ServiceChainingUtil.resolveRemoteSfcComponents(rspBuilder.build(), policyWriter); + boolean result = ServiceChainingUtil.resolveRemoteSfcComponents(rspBuilder.build(), context); assertFalse(result); - verifyZeroInteractions(policyWriter); } @Test public void testResolveRemoteSfcComponents_sffWithoutMgmtAddress() { + final PolicyConfigurationContext context = new PolicyConfigurationContext(); + context.setPolicyMapLocation(getLocation()); final DataPlaneLocatorBuilder dplBuilder = new DataPlaneLocatorBuilder(); dplBuilder.setLocatorType(new IpBuilder().setIp(new IpAddress(new Ipv4Address(IP_ADDRESS))).build()); final SffDataPlaneLocatorBuilder sffDplBuilder = new SffDataPlaneLocatorBuilder(); @@ -542,13 +559,14 @@ public class ServiceChainingUtilTest { stub(method(SfcProviderServiceForwarderAPI.class, "readServiceFunctionForwarder")).toReturn(forwarderBuilder.build()); - boolean result = ServiceChainingUtil.resolveRemoteSfcComponents(rspBuilder.build(), policyWriter); + boolean result = ServiceChainingUtil.resolveRemoteSfcComponents(rspBuilder.build(), context); assertFalse(result); - verifyZeroInteractions(policyWriter); } @Test public void testResolveRemoteSfcComponents_remoteCase() { + final PolicyConfigurationContext context = new PolicyConfigurationContext(); + context.setPolicyMapLocation(getLocation()); final DataPlaneLocatorBuilder dplBuilder = new DataPlaneLocatorBuilder(); dplBuilder.setLocatorType(new IpBuilder().setIp(new IpAddress(new Ipv4Address("190.1.1.12"))).build()); final SffDataPlaneLocatorBuilder sffDplBuilder = new SffDataPlaneLocatorBuilder(); @@ -563,13 +581,14 @@ public class ServiceChainingUtilTest { rspBuilder.setRenderedServicePathHop(Collections.singletonList(hopBuilder.build())); stub(method(SfcProviderServiceForwarderAPI.class, "readServiceFunctionForwarder")).toReturn(forwarderBuilder.build()); + stub(method(PolicyWriterUtil.class, "writeServicePath")).toReturn(true); + stub(method(PolicyWriterUtil.class, "writeRemote")).toReturn(true); - boolean result = ServiceChainingUtil.resolveRemoteSfcComponents(rspBuilder.build(), policyWriter); + boolean result = ServiceChainingUtil.resolveRemoteSfcComponents(rspBuilder.build(), context); assertTrue(result); - verify(policyWriter).getManagementIpAddress(); - verify(policyWriter).cache(any(ServiceChain.class)); - verify(policyWriter).cache(any(ServiceFfName.class)); - verifyNoMoreInteractions(policyWriter); + verifyStatic(times(1)); + PolicyWriterUtil.writeServicePath(any(ServiceChain.class), any(PolicyManagerImpl.PolicyMapLocation.class)); + PolicyWriterUtil.writeRemote(any(ServiceFfName.class), any(PolicyManagerImpl.PolicyMapLocation.class)); } @Test @@ -669,6 +688,10 @@ public class ServiceChainingUtilTest { @Test public void testCreateRenderedPath_renderedPathFound() { + final Sgt sourceSgt = new Sgt(1); + final Sgt destinationSgt = new Sgt(2); + final PolicyConfigurationContext context = new PolicyConfigurationContext(); + context.setPolicyMapLocation(getLocation()); final ServiceFunctionPathBuilder serviceFunctionPathBuilder = new ServiceFunctionPathBuilder(); serviceFunctionPathBuilder.setName(new SfpName(SFC_PATH_NAME)) .setSymmetric(true); @@ -677,13 +700,18 @@ public class ServiceChainingUtilTest { stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(new RenderedServicePathBuilder().build()); - final RenderedServicePath result = ServiceChainingUtil.createRenderedPath(serviceFunctionPath, tenantId, dataBroker); + final RenderedServicePath result = ServiceChainingUtil.resolveRenderedServicePath(serviceFunctionPath, tenantId, + dataBroker, sourceSgt, destinationSgt, context); assertNotNull(result); } @Test public void testCreateRenderedPath_renderedPathCreated() { ServiceChainingUtil.setTimeout(1L); + final Sgt sourceSgt = new Sgt(1); + final Sgt destinationSgt = new Sgt(2); + final PolicyConfigurationContext context = new PolicyConfigurationContext(); + context.setPolicyMapLocation(getLocation()); final ServiceFunctionPathBuilder serviceFunctionPathBuilder = new ServiceFunctionPathBuilder(); serviceFunctionPathBuilder.setName(new SfpName(SFC_PATH_NAME)) .setSymmetric(true); @@ -694,12 +722,17 @@ public class ServiceChainingUtilTest { stub(method(SfcProviderRenderedPathAPI.class, "createRenderedServicePathAndState", ServiceFunctionPath.class, CreateRenderedPathInput.class)).toReturn(new RenderedServicePathBuilder().build()); - final RenderedServicePath result = ServiceChainingUtil.createRenderedPath(serviceFunctionPath, tenantId, dataBroker); + final RenderedServicePath result = ServiceChainingUtil.resolveRenderedServicePath(serviceFunctionPath, tenantId, + dataBroker, sourceSgt, destinationSgt, context); assertNotNull(result); } @Test public void testCreateReversedRenderedPath_renderedPathFound() { + final Sgt sourceSgt = new Sgt(1); + final Sgt destinationSgt = new Sgt(2); + final PolicyConfigurationContext context = new PolicyConfigurationContext(); + context.setPolicyMapLocation(getLocation()); final ServiceFunctionPathBuilder serviceFunctionPathBuilder = new ServiceFunctionPathBuilder(); serviceFunctionPathBuilder.setName(new SfpName(SFC_PATH_NAME)) .setSymmetric(true); @@ -708,27 +741,30 @@ public class ServiceChainingUtilTest { stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(new RenderedServicePathBuilder().build()); - final RenderedServicePath result = ServiceChainingUtil.createReversedRenderedPath(serviceFunctionPath, null, - tenantId, dataBroker); + final RenderedServicePath result = ServiceChainingUtil.resolveReversedRenderedServicePath(serviceFunctionPath, + tenantId, dataBroker, sourceSgt, destinationSgt, context); assertNotNull(result); } @Test public void testCreateReversedRenderedPath_renderedPathCreated() { ServiceChainingUtil.setTimeout(1L); + final Sgt sourceSgt = new Sgt(1); + final Sgt destinationSgt = new Sgt(2); + final PolicyConfigurationContext context = new PolicyConfigurationContext(); + context.setPolicyMapLocation(getLocation()); final ServiceFunctionPathBuilder serviceFunctionPathBuilder = new ServiceFunctionPathBuilder(); serviceFunctionPathBuilder.setName(new SfpName(SFC_PATH_NAME)) .setSymmetric(true); final ServiceFunctionPath serviceFunctionPath = serviceFunctionPathBuilder.build(); final TenantId tenantId = new TenantId(TENANT_ID); - final RenderedServicePath renderedServicePath = new RenderedServicePathBuilder().build(); stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(null); stub(method(SfcProviderRenderedPathAPI.class, "createReverseRenderedServicePathEntry")) .toReturn(new RenderedServicePathBuilder().build()); - final RenderedServicePath result = ServiceChainingUtil.createReversedRenderedPath(serviceFunctionPath, renderedServicePath, - tenantId, dataBroker); + final RenderedServicePath result = ServiceChainingUtil.resolveReversedRenderedServicePath(serviceFunctionPath, + tenantId, dataBroker, sourceSgt, destinationSgt, context); assertNotNull(result); } @@ -745,7 +781,6 @@ public class ServiceChainingUtilTest { assertEquals(testForwarder, result); } - @Test public void testGetServicePath() throws Exception { final String sfcNameValue = "123"; @@ -771,13 +806,18 @@ public class ServiceChainingUtilTest { final String sfcNameValue = "123"; final ServiceFunctionPath sfp = createSfp(sfcNameValue); final TenantId tenantId = new TenantId("unit-tenant-01"); + final Sgt sourceSgt = new Sgt(1); + final Sgt destinationSgt = new Sgt(2); + final PolicyConfigurationContext context = new PolicyConfigurationContext(); + context.setPolicyMapLocation(getLocation()); final RenderedServicePath rsp = createRsp("unit-rsp-01"); PowerMockito.mockStatic(SfcProviderRenderedPathAPI.class); PowerMockito.when(SfcProviderRenderedPathAPI.readRenderedServicePath(rspNameCaptor.capture())).thenReturn(rsp); - final RenderedServicePath renderedPath = ServiceChainingUtil.createRenderedPath(sfp, tenantId, dataBroker); + final RenderedServicePath renderedPath = ServiceChainingUtil.resolveRenderedServicePath(sfp, tenantId, + dataBroker, sourceSgt, destinationSgt, context); assertEquals("123_plain-unit-tenant-01-gbp-rsp", rspNameCaptor.getValue().getValue()); assertEquals(rsp, renderedPath); @@ -788,11 +828,18 @@ public class ServiceChainingUtilTest { final ServiceFunctionPath sfp = createSfp("unit-sfp-02"); final RenderedServicePath rsp = createRsp("unit-rsp-02"); final TenantId tenantId = new TenantId("tenant-02"); + final Sgt sourceSgt = new Sgt(1); + final Sgt destinationSgt = new Sgt(2); + final PolicyConfigurationContext context = new PolicyConfigurationContext(); + context.setPolicyMapLocation(getLocation()); PowerMockito.mockStatic(SfcProviderRenderedPathAPI.class); PowerMockito.when(SfcProviderRenderedPathAPI.readRenderedServicePath(rspNameCaptor.capture())).thenReturn(rsp); + stub(method(SfcProviderServiceForwarderAPI.class, "readServiceFunctionForwarder")) + .toReturn(new ServiceFunctionForwarderBuilder().setName(new SffName("sff-name")).build()); - final RenderedServicePath symmetricRenderedPath = ServiceChainingUtil.createReversedRenderedPath(sfp, rsp, tenantId, dataBroker); + final RenderedServicePath symmetricRenderedPath = ServiceChainingUtil.resolveReversedRenderedServicePath(sfp, + tenantId, dataBroker, sourceSgt, destinationSgt, context); assertEquals("unit-sfp-02_plain-tenant-02-gbp-rsp-Reverse", rspNameCaptor.getValue().getValue()); assertEquals(rsp, symmetricRenderedPath); @@ -814,9 +861,9 @@ public class ServiceChainingUtilTest { // Auxiliary methods - private RenderedServicePath buildRsp(List hop) { + private RenderedServicePath buildRsp() { RenderedServicePathBuilder renderedServicePathBuilder = new RenderedServicePathBuilder(); - renderedServicePathBuilder.setRenderedServicePathHop(hop); + renderedServicePathBuilder.setRenderedServicePathHop(null); return renderedServicePathBuilder.build(); } @@ -850,17 +897,17 @@ public class ServiceChainingUtilTest { return peerEndpointBuilder.build(); } - private Map resolvedActionBuilder(@Nonnull final ActionCase actionCase, + private Map resolvedActionBuilder(@Nonnull final RuleName ruleName, + @Nonnull final ActionCase actionCase, @Nonnull final Action action, @Nonnull final Direction direction) { - final ActionInDirection actionInDirection = new ActionInDirection(action, PROVIDER, direction); + final ActionInDirection actionInDirection = new ActionInDirection(ruleName, action, PROVIDER, direction); return Collections.singletonMap(actionCase, actionInDirection); } private PolicyConfigurationContext policyConfigurationContextBuilder() { final RendererEndpointBuilder rendererEndpointBuilder = new RendererEndpointBuilder(); final PolicyConfigurationContext context = new PolicyConfigurationContext(); - context.setPolicyWriter(policyWriter); context.setCurrentRendererEP(rendererEndpointBuilder.build()); return context; } @@ -874,4 +921,12 @@ public class ServiceChainingUtilTest { actionBuilder.setParameterValue(parameters); return actionBuilder.build(); } + + private PolicyManagerImpl.PolicyMapLocation getLocation() { + final String POLICY_MAP = "policy-map"; + final String INTERFACE = "interface"; + final NodeId nodeId = new NodeId("node-id"); + final String IP_ADDRESS = "ip-address"; + return new PolicyManagerImpl.PolicyMapLocation(POLICY_MAP, INTERFACE, nodeId, IP_ADDRESS, dataBroker); + } } \ No newline at end of file diff --git a/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/StatusUtilTest.java b/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/StatusUtilTest.java index 9b1fdb022..569021d3a 100644 --- a/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/StatusUtilTest.java +++ b/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/util/StatusUtilTest.java @@ -19,6 +19,7 @@ import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.P import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.AddressEndpointKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.RuleName; 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.forwarding.l2_l3.rev160427.IpPrefixType; @@ -27,6 +28,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.r 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.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipationBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.unconfigured.rule.groups.UnconfiguredRuleGroup; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.unconfigured.rule.groups.unconfigured.rule.group.UnconfiguredResolvedRule; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.unconfigured.rule.groups.unconfigured.rule.group.UnconfiguredResolvedRuleBuilder; 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; @@ -39,14 +42,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.r */ public class StatusUtilTest { - public static final TenantId TENANT_ID = new TenantId("unit-tenant-1"); - public static final SubjectName SUBJECT_NAME = new SubjectName("unit-subject-1"); - public static final ContractId CONTRACT_ID = new ContractId("unit-contract-1"); - public static final String ADDRESS_1 = "unit-address-1"; - public static final ContextId CONTEXT_ID_1 = new ContextId("unit-context-1"); - public static final String ADDRESS_2 = "unit-address-2"; - public static final ContextId CONTEXT_ID_2 = new ContextId("unit-context-2"); - public static final String INFO_MESSAGE = "unit-info-1"; + private static final TenantId TENANT_ID = new TenantId("unit-tenant-1"); + private static final SubjectName SUBJECT_NAME = new SubjectName("unit-subject-1"); + private static final ContractId CONTRACT_ID = new ContractId("unit-contract-1"); + private static final String ADDRESS_1 = "unit-address-1"; + private static final ContextId CONTEXT_ID_1 = new ContextId("unit-context-1"); + private static final String ADDRESS_2 = "unit-address-2"; + private static final ContextId CONTEXT_ID_2 = new ContextId("unit-context-2"); + private static final String INFO_MESSAGE = "unit-info-1"; private PolicyConfigurationContext context; @Before @@ -117,7 +120,7 @@ public class StatusUtilTest { @Test public void testAssemblePeerEndpoint() throws Exception { final PeerEndpoint peerEndpoint = createPeer(ADDRESS_1, CONTEXT_ID_1); - final List gatheredPeers = StatusUtil.assemblePeerEndpoint(Stream.of(peerEndpoint)); + final List gatheredPeers = StatusUtil.assemblePeerEndpoint(Stream.of(peerEndpoint), null); Assert.assertEquals(1, gatheredPeers.size()); final UnconfiguredPeerEndpoint actual = gatheredPeers.get(0); @@ -134,6 +137,11 @@ public class StatusUtilTest { @Test public void testAssembleRuleGroups() throws Exception { + final UnconfiguredResolvedRuleBuilder unconfiguredResolvedRuleBuilder = new UnconfiguredResolvedRuleBuilder(); + unconfiguredResolvedRuleBuilder.setRuleName(new RuleName("rule-name")); + final UnconfiguredResolvedRule resolvedRule = unconfiguredResolvedRuleBuilder.build(); + final PolicyConfigurationContext context = new PolicyConfigurationContext(); + context.setCurrentUnconfiguredRule(resolvedRule); final RuleGroupWithRendererEndpointParticipation ruleGroup = new RuleGroupWithRendererEndpointParticipationBuilder() .setTenantId(TENANT_ID) @@ -141,14 +149,14 @@ public class StatusUtilTest { .setContractId(CONTRACT_ID) .setRendererEndpointParticipation(EndpointPolicyParticipation.CONSUMER) .build(); - final List gatheredRuleGroups = StatusUtil.assembleRuleGroups(Stream.of(ruleGroup)); + final List gatheredRuleGroups = StatusUtil.assembleRuleGroups(Stream.of(ruleGroup), context); Assert.assertEquals(1, gatheredRuleGroups.size()); final UnconfiguredRuleGroup actual = gatheredRuleGroups.get(0); Assert.assertEquals(TENANT_ID, actual.getTenantId()); Assert.assertEquals(SUBJECT_NAME, actual.getSubjectName()); Assert.assertEquals(CONTRACT_ID, actual.getContractId()); - Assert.assertEquals(null, actual.getUnconfiguredResolvedRule()); + Assert.assertEquals(Collections.singletonList(resolvedRule), actual.getUnconfiguredResolvedRule()); Assert.assertEquals(EndpointPolicyParticipation.CONSUMER, actual.getRendererEndpointParticipation()); } } \ No newline at end of file diff --git a/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/PolicyWriterUtilTest.java b/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/PolicyWriterUtilTest.java index 1e5510e14..4b2902697 100644 --- a/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/PolicyWriterUtilTest.java +++ b/renderers/ios-xe/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ios_xe_provider/impl/writer/PolicyWriterUtilTest.java @@ -24,10 +24,13 @@ 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.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.ServiceChainingUtil; import org.opendaylight.yang.gen.v1.urn.ios.rev160308.ClassNameType; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMapBuilder; +import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMap; +import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMapBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChainBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class; @@ -35,6 +38,7 @@ import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.ClassBu import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePathBuilder; 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.ServiceFfNameBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.powermock.api.mockito.PowerMockito; @@ -70,205 +74,175 @@ public class PolicyWriterUtilTest { } @Test - public void testWriteClassMaps() throws Exception { - LOG.debug("scenario: pass through with null classMapEntries collection"); - Assert.assertTrue(PolicyWriterUtil.writeClassMaps(null, NODE_ID, dataBroker)); - - LOG.debug("scenario: pass through with empty classMapEntries collection"); - final Set classMapEntries = new HashSet<>(); - Assert.assertTrue(PolicyWriterUtil.writeClassMaps(classMapEntries, NODE_ID, dataBroker)); - + public void testWriteClassMap() throws Exception { LOG.debug("scenario: fail with one entry, no writeOnlyTransaction"); - classMapEntries.add(new ClassMapBuilder().setName("unit-classMapEntry-name").build()); - Assert.assertFalse(PolicyWriterUtil.writeClassMaps(classMapEntries, NODE_ID, dataBroker)); + final ClassMap classMap = new ClassMapBuilder().setName("unit-classMapEntry-name").build(); + Assert.assertFalse(PolicyWriterUtil.writeClassMap(classMap, getLocation())); LOG.debug("scenario: fail with one entry, available writeOnlyTransaction, no readOnlyTransaction"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, "netconfWriteOnlyTransaction")).toReturn(wTxOptional); Mockito.when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); - Assert.assertFalse(PolicyWriterUtil.writeClassMaps(classMapEntries, NODE_ID, dataBroker)); + Assert.assertFalse(PolicyWriterUtil.writeClassMap(classMap, getLocation())); LOG.debug("scenario: succeed with one entry, available writeOnlyTransaction, available readOnlyTransaction"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, "netconfReadOnlyTransaction")).toReturn(rTxOptional); Mockito.when(rTx.read(Mockito.eq(LogicalDatastoreType.CONFIGURATION), Matchers.>any())) .thenReturn(Futures.immediateCheckedFuture(Optional.of( new ClassMapBuilder().setName("asd").build()))); - Assert.assertTrue(PolicyWriterUtil.writeClassMaps(classMapEntries, NODE_ID, dataBroker)); + Assert.assertTrue(PolicyWriterUtil.writeClassMap(classMap, getLocation())); LOG.debug("scenario: fail with one entry, available writeOnlyTransaction, available readOnlyTransaction, check->null"); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, "netconfRead")).toReturn(null); - Assert.assertFalse(PolicyWriterUtil.writeClassMaps(classMapEntries, NODE_ID, dataBroker)); + Assert.assertFalse(PolicyWriterUtil.writeClassMap(classMap, getLocation())); } @Test - public void testRemoveClassMaps() throws Exception { + public void testRemoveClassMap() throws Exception { LOG.debug("scenario: pass through with null classMapEntries collection"); - Assert.assertTrue(PolicyWriterUtil.removeClassMaps(null, NODE_ID, dataBroker)); + Assert.assertTrue(PolicyWriterUtil.removeClassMap(null, getLocation())); LOG.debug("scenario: pass through with empty classMapEntries collection"); - final Set classMapEntries = new HashSet<>(); - Assert.assertTrue(PolicyWriterUtil.removeClassMaps(classMapEntries, NODE_ID, dataBroker)); + final ClassMap classMap = new ClassMapBuilder().setName("unit-classMapEntry-name").build(); + Assert.assertTrue(PolicyWriterUtil.removeClassMap(classMap, getLocation())); LOG.debug("scenario: fail with one entry, no writeOnlyTransaction"); - classMapEntries.add(new ClassMapBuilder().setName("unit-classMapEntry-name").build()); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, "netconfRead")).toReturn(new ClassBuilder().build()); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, "netconfWriteOnlyTransaction")) .toReturn(java.util.Optional.empty()); - Assert.assertFalse(PolicyWriterUtil.removeClassMaps(classMapEntries, NODE_ID, dataBroker)); + Assert.assertFalse(PolicyWriterUtil.removeClassMap(classMap, getLocation())); LOG.debug("scenario: fail with one entry, available writeOnlyTransaction, no readOnlyTransaction"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, "netconfWriteOnlyTransaction")).toReturn(wTxOptional); Mockito.when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); - Assert.assertFalse(PolicyWriterUtil.removeClassMaps(classMapEntries, NODE_ID, dataBroker)); + Assert.assertFalse(PolicyWriterUtil.removeClassMap(classMap, getLocation())); LOG.debug("scenario: succeed with one entry, available writeOnlyTransaction, available readOnlyTransaction"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, "netconfReadOnlyTransaction")).toReturn(rTxOptional); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, "netconfRead")).toReturn(null); Mockito.when(rTx.read(Mockito.eq(LogicalDatastoreType.CONFIGURATION), Matchers.>any())) .thenReturn(Futures.immediateCheckedFuture(Optional.absent())); - Assert.assertTrue(PolicyWriterUtil.removeClassMaps(classMapEntries, NODE_ID, dataBroker)); + Assert.assertTrue(PolicyWriterUtil.removeClassMap(classMap, getLocation())); LOG.debug("scenario: fail with one entry, available writeOnlyTransaction, available readOnlyTransaction, check->false"); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, "netconfRead")).toReturn(new ClassBuilder().build()); - Assert.assertFalse(PolicyWriterUtil.removeClassMaps(classMapEntries, NODE_ID, dataBroker)); + Assert.assertFalse(PolicyWriterUtil.removeClassMap(classMap, getLocation())); } @Test public void testWritePolicyMap() throws Exception { - final Set classEntries = new HashSet<>(); - LOG.debug("scenario: fail with one entry, no writeOnlyTransaction"); - classEntries.add(new ClassBuilder().setName(new ClassNameType("unit-classEntry-name")).build()); - Assert.assertFalse(PolicyWriterUtil.writePolicyMap(POLICY_MAP_NAME, classEntries, NODE_ID, dataBroker)); + final PolicyMap policyMap = new PolicyMapBuilder().setName("unit-policyMap-name").build(); + Assert.assertFalse(PolicyWriterUtil.writePolicyMap(policyMap, getLocation())); LOG.debug("scenario: fail with one entry, available writeOnlyTransaction, no readOnlyTransaction"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, "netconfWriteOnlyTransaction")).toReturn(wTxOptional); Mockito.when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); - Assert.assertFalse(PolicyWriterUtil.writePolicyMap(POLICY_MAP_NAME, classEntries, NODE_ID, dataBroker)); - - LOG.debug("scenario: fail with null classEntries collection"); - try { - PolicyWriterUtil.writePolicyMap(POLICY_MAP_NAME, null, NODE_ID, dataBroker); - Assert.fail("expected NPE caused by classEntries parameter"); - } catch (Exception e) { - // expected - } + Assert.assertFalse(PolicyWriterUtil.writePolicyMap(policyMap, getLocation())); LOG.debug("scenario: fail with empty classEntries collection"); - Assert.assertFalse(PolicyWriterUtil.writePolicyMap(POLICY_MAP_NAME, classEntries, NODE_ID, dataBroker)); + Assert.assertFalse(PolicyWriterUtil.writePolicyMap(policyMap, getLocation())); LOG.debug("scenario: succeed with one entry, available writeOnlyTransaction, available readOnlyTransaction"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, "netconfReadOnlyTransaction")).toReturn(rTxOptional); Mockito.when(rTx.read(Mockito.eq(LogicalDatastoreType.CONFIGURATION), Matchers.>any())) .thenReturn(Futures.immediateCheckedFuture(Optional.of( new ClassMapBuilder().setName("asd").build()))); - Assert.assertTrue(PolicyWriterUtil.writePolicyMap(POLICY_MAP_NAME, classEntries, NODE_ID, dataBroker)); + Assert.assertTrue(PolicyWriterUtil.writePolicyMap(policyMap, getLocation())); LOG.debug("scenario: fail with one entry, available writeOnlyTransaction, available readOnlyTransaction, check->null"); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, "netconfRead")).toReturn(null); - Assert.assertFalse(PolicyWriterUtil.writePolicyMap(POLICY_MAP_NAME, classEntries, NODE_ID, dataBroker)); + Assert.assertFalse(PolicyWriterUtil.writePolicyMap(policyMap, getLocation())); } @Test - public void testRemovePolicyMapEntries() throws Exception { - LOG.debug("scenario: pass through with null classEntries collection"); - Assert.assertTrue(PolicyWriterUtil.removePolicyMapEntries(POLICY_MAP_NAME, null, NODE_ID, dataBroker)); - + public void testRemovePolicyMapEntry() throws Exception { LOG.debug("scenario: pass through with empty classEntries collection"); - final Set classEntries = new HashSet<>(); - Assert.assertTrue(PolicyWriterUtil.removePolicyMapEntries(POLICY_MAP_NAME, classEntries, NODE_ID, dataBroker)); + final Class entry = new ClassBuilder().setName(new ClassNameType("unit-class-name")).build(); + Assert.assertTrue(PolicyWriterUtil.removePolicyMapEntry(entry, getLocation())); LOG.debug("scenario: fail with one entry, no writeOnlyTransaction"); - classEntries.add(new ClassBuilder().setName(new ClassNameType("unit-classMapEntry-name")).build()); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, "netconfRead")).toReturn(new ClassBuilder().build()); - Assert.assertFalse(PolicyWriterUtil.removePolicyMapEntries(POLICY_MAP_NAME, classEntries, NODE_ID, dataBroker)); + Assert.assertFalse(PolicyWriterUtil.removePolicyMapEntry(entry, getLocation())); LOG.debug("scenario: fail with one entry, available writeOnlyTransaction, no readOnlyTransaction"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, "netconfWriteOnlyTransaction")).toReturn(wTxOptional); Mockito.when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); - Assert.assertTrue(PolicyWriterUtil.removePolicyMapEntries(POLICY_MAP_NAME, classEntries, NODE_ID, dataBroker)); + Assert.assertTrue(PolicyWriterUtil.removePolicyMapEntry(entry, getLocation())); } @Test public void testWriteInterface() throws Exception { LOG.debug("scenario: fail with no writeOnlyTransaction"); - final String interfaceName = "unit-interface-1"; - Assert.assertFalse(PolicyWriterUtil.writeInterface(POLICY_MAP_NAME, interfaceName, NODE_ID, dataBroker)); + Assert.assertFalse(PolicyWriterUtil.writeInterface(getLocation())); LOG.debug("scenario: fail - available writeOnlyTransaction, no submit future"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, "netconfWriteOnlyTransaction")).toReturn(wTxOptional); - Assert.assertFalse(PolicyWriterUtil.writeInterface(POLICY_MAP_NAME, interfaceName, NODE_ID, dataBroker)); + Assert.assertFalse(PolicyWriterUtil.writeInterface(getLocation())); LOG.debug("scenario: succeed - available writeOnlyTransaction, available future"); Mockito.when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); - Assert.assertTrue(PolicyWriterUtil.writeInterface(POLICY_MAP_NAME, interfaceName, NODE_ID, dataBroker)); + Assert.assertTrue(PolicyWriterUtil.writeInterface(getLocation())); } @Test public void testWriteRemote() throws Exception { - LOG.debug("scenario: succeed with null List"); - Assert.assertTrue(PolicyWriterUtil.writeRemote(null, NODE_ID, dataBroker)); - LOG.debug("scenario: succeed with empty List"); - Assert.assertTrue(PolicyWriterUtil.writeRemote(Collections.emptySet(), NODE_ID, dataBroker)); - - LOG.debug("scenario: fail with no writeOnlyTransaction"); - final Set remotes = Collections.singleton(new ServiceFfNameBuilder().build()); - Assert.assertFalse(PolicyWriterUtil.writeRemote(remotes, NODE_ID, dataBroker)); + final ServiceFfName forwarder = new ServiceFfNameBuilder().setName("unit-service-forwarder-name").build(); + Assert.assertFalse(PolicyWriterUtil.writeRemote(forwarder, getLocation())); LOG.debug("scenario: fail - available writeOnlyTransaction, no submit future"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, "netconfWriteOnlyTransaction")).toReturn(wTxOptional); - Assert.assertFalse(PolicyWriterUtil.writeRemote(remotes, NODE_ID, dataBroker)); + Assert.assertFalse(PolicyWriterUtil.writeRemote(forwarder, getLocation())); LOG.debug("scenario: succeed - available writeOnlyTransaction, available future"); Mockito.when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); - Assert.assertTrue(PolicyWriterUtil.writeRemote(remotes, NODE_ID, dataBroker)); + Assert.assertTrue(PolicyWriterUtil.writeRemote(forwarder, getLocation())); } @Test - public void testWriteServicePaths() throws Exception { - LOG.debug("scenario: succeed with empty List"); - Assert.assertTrue(PolicyWriterUtil.writeServicePaths(Collections.emptySet(), NODE_ID, dataBroker)); - + public void testWriteServicePath() throws Exception { LOG.debug("scenario: fail with no writeOnlyTransaction"); - final Set serviceChains = Collections.singleton(new ServiceChainBuilder() + final ServiceChain serviceChain = new ServiceChainBuilder() .setServicePath(Collections.singletonList(new ServicePathBuilder() .setServicePathId(42L) .build())) - .build()); - Assert.assertFalse(PolicyWriterUtil.writeServicePaths(serviceChains, NODE_ID, dataBroker)); + .build(); + Assert.assertFalse(PolicyWriterUtil.writeServicePath(serviceChain, getLocation())); LOG.debug("scenario: fail - available writeOnlyTransaction, no submit future"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, "netconfWriteOnlyTransaction")).toReturn(wTxOptional); - Assert.assertFalse(PolicyWriterUtil.writeServicePaths(serviceChains, NODE_ID, dataBroker)); + Assert.assertFalse(PolicyWriterUtil.writeServicePath(serviceChain, getLocation())); LOG.debug("scenario: succeed - available writeOnlyTransaction, available future"); Mockito.when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); - Assert.assertTrue(PolicyWriterUtil.writeServicePaths(serviceChains, NODE_ID, dataBroker)); + Assert.assertTrue(PolicyWriterUtil.writeServicePath(serviceChain, getLocation())); } @Test - public void testRemoveServicePaths() throws Exception { - LOG.debug("scenario: succeed with service path present null"); - Assert.assertTrue(PolicyWriterUtil.removeServicePaths(null, NODE_ID, dataBroker)); - - LOG.debug("scenario: succeed with no service path present"); - Assert.assertTrue(PolicyWriterUtil.removeServicePaths(Collections.emptySet(), NODE_ID, dataBroker)); - + public void testRemoveServicePath() throws Exception { LOG.debug("scenario: fail with service path present, no writeOnlyTransaction"); PowerMockito.stub(PowerMockito.method(PolicyWriterUtil.class, "netconfRead")).toReturn(new ClassBuilder().build()); - final Set serviceChains = Collections.singleton(new ServiceChainBuilder() + final ServiceChain serviceChain = new ServiceChainBuilder() .setServicePath(Collections.singletonList(new ServicePathBuilder() .setServicePathId(42L) .build())) - .build()); - Assert.assertFalse(PolicyWriterUtil.removeServicePaths(serviceChains, NODE_ID, dataBroker)); + .build(); + Assert.assertFalse(PolicyWriterUtil.removeServicePath(serviceChain, getLocation())); LOG.debug("scenario: fail with service path present, available writeOnlyTransaction, no submit future"); PowerMockito.stub(PowerMockito.method(NetconfTransactionCreator.class, "netconfWriteOnlyTransaction")).toReturn(wTxOptional); - Assert.assertFalse(PolicyWriterUtil.removeServicePaths(serviceChains, NODE_ID, dataBroker)); + Assert.assertFalse(PolicyWriterUtil.removeServicePath(serviceChain, getLocation())); LOG.debug("scenario: fail with service path present, available writeOnlyTransaction, available future"); Mockito.when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); - Assert.assertTrue(PolicyWriterUtil.removeServicePaths(serviceChains, NODE_ID, dataBroker)); + Assert.assertTrue(PolicyWriterUtil.removeServicePath(serviceChain, getLocation())); + } + + private PolicyManagerImpl.PolicyMapLocation getLocation() { + final String POLICY_MAP = "policy-map"; + final String INTERFACE = "interface"; + final NodeId nodeId = new NodeId("node-id"); + final String IP_ADDRESS = "ip-address"; + return new PolicyManagerImpl.PolicyMapLocation(POLICY_MAP, INTERFACE, nodeId, IP_ADDRESS, dataBroker); } } \ No newline at end of file -- 2.36.6