Search in sources :

Example 1 with FlowPathPair

use of org.openkilda.wfm.topology.flow.model.FlowPathPair in project open-kilda by telstra.

the class CompleteFlowPathRemovalAction method perform.

@Override
protected void perform(State from, State to, Event event, FlowDeleteContext context, FlowDeleteFsm stateMachine) {
    Flow flow = transactionManager.doInTransaction(() -> {
        Flow foundFlow = getFlow(stateMachine.getFlowId());
        Stream.of(foundFlow.getForwardPath(), foundFlow.getReversePath()).map(FlowPath::getFlowMirrorPointsSet).flatMap(Collection::stream).forEach(mirrorPoints -> {
            Set<Long> cookies = new HashSet<>();
            mirrorPoints.getMirrorPaths().forEach(mirrorPath -> {
                cookies.add(mirrorPath.getCookie().getFlowEffectiveId());
                flowMirrorPathRepository.remove(mirrorPath);
            });
            stateMachine.getFlowMirrorPathResources().add(FlowMirrorPathResources.builder().flowPathId(mirrorPoints.getFlowPathId()).mirrorSwitchId(mirrorPoints.getMirrorSwitchId()).unmaskedCookies(cookies).build());
            flowMirrorPointsRepository.remove(mirrorPoints);
        });
        return foundFlow;
    });
    // Iterate to remove each path in a dedicated transaction.
    flow.getPathIds().forEach(pathId -> {
        Optional<FlowPath> deletedPath = flowPathRepository.remove(pathId);
        deletedPath.ifPresent(path -> {
            updateIslsForFlowPath(path);
            saveRemovalActionWithDumpToHistory(stateMachine, flow, new FlowPathPair(path, path));
        });
    });
}
Also used : FlowPath(org.openkilda.model.FlowPath) Flow(org.openkilda.model.Flow) HashSet(java.util.HashSet) FlowPathPair(org.openkilda.wfm.topology.flow.model.FlowPathPair)

Example 2 with FlowPathPair

use of org.openkilda.wfm.topology.flow.model.FlowPathPair in project open-kilda by telstra.

the class AllocateProtectedResourcesAction method allocate.

@Override
protected void allocate(FlowUpdateFsm stateMachine) throws RecoverableException, UnroutableFlowException, ResourceAllocationException {
    String flowId = stateMachine.getFlowId();
    Set<String> flowIds = Sets.newHashSet(flowId);
    if (stateMachine.getBulkUpdateFlowIds() != null) {
        flowIds.addAll(stateMachine.getBulkUpdateFlowIds());
    }
    log.debug("Finding protected path ids for flows {}", flowIds);
    List<PathId> pathIdsToReuse = new ArrayList<>(flowPathRepository.findActualPathIdsByFlowIds(flowIds));
    pathIdsToReuse.addAll(stateMachine.getRejectedPaths());
    Flow tmpFlow = getFlow(flowId);
    FlowPathPair oldPaths = new FlowPathPair(tmpFlow.getProtectedForwardPath(), tmpFlow.getProtectedReversePath());
    FlowPath primaryForward = getFlowPath(tmpFlow, stateMachine.getNewPrimaryForwardPath());
    FlowPath primaryReverse = getFlowPath(tmpFlow, stateMachine.getNewPrimaryReversePath());
    Predicate<GetPathsResult> testNonOverlappingPath = path -> (primaryForward == null || !flowPathBuilder.arePathsOverlapped(path.getForward(), primaryForward)) && (primaryReverse == null || !flowPathBuilder.arePathsOverlapped(path.getReverse(), primaryReverse));
    PathId newForwardPathId = resourcesManager.generatePathId(flowId);
    PathId newReversePathId = resourcesManager.generatePathId(flowId);
    log.debug("Finding a new protected path for flow {}", flowId);
    GetPathsResult allocatedPaths = allocatePathPair(tmpFlow, newForwardPathId, newReversePathId, false, pathIdsToReuse, oldPaths, true, stateMachine.getSharedBandwidthGroupId(), testNonOverlappingPath);
    if (allocatedPaths == null) {
        throw new ResourceAllocationException("Unable to allocate a path");
    }
    if (!testNonOverlappingPath.test(allocatedPaths)) {
        stateMachine.saveActionToHistory("Couldn't find non overlapping protected path");
    } else {
        log.debug("New protected paths have been allocated: {}", allocatedPaths);
        stateMachine.setNewProtectedForwardPath(newForwardPathId);
        stateMachine.setNewProtectedReversePath(newReversePathId);
        stateMachine.setBackUpProtectedPathComputationWayUsed(allocatedPaths.isBackUpPathComputationWayUsed());
        log.debug("Allocating resources for a new protected path of flow {}", flowId);
        FlowResources flowResources = allocateFlowResources(tmpFlow, newForwardPathId, newReversePathId);
        stateMachine.setNewProtectedResources(flowResources);
        FlowPathPair createdPaths = createFlowPathPair(flowId, flowResources, allocatedPaths, false, stateMachine.getSharedBandwidthGroupId());
        log.debug("New protected path has been created: {}", createdPaths);
        saveAllocationActionWithDumpsToHistory(stateMachine, tmpFlow, "protected", createdPaths);
    }
}
Also used : BaseResourceAllocationAction(org.openkilda.wfm.topology.flowhs.fsm.common.actions.BaseResourceAllocationAction) FlowPath(org.openkilda.model.FlowPath) ResourceAllocationException(org.openkilda.wfm.share.flow.resources.ResourceAllocationException) RecoverableException(org.openkilda.pce.exception.RecoverableException) ArrayList(java.util.ArrayList) UnroutableFlowException(org.openkilda.pce.exception.UnroutableFlowException) Flow(org.openkilda.model.Flow) FlowPathPair(org.openkilda.wfm.topology.flow.model.FlowPathPair) PersistenceManager(org.openkilda.persistence.PersistenceManager) PathId(org.openkilda.model.PathId) FlowOperationsDashboardLogger(org.openkilda.wfm.share.logger.FlowOperationsDashboardLogger) ErrorType(org.openkilda.messaging.error.ErrorType) Predicate(java.util.function.Predicate) FlowUpdateFsm(org.openkilda.wfm.topology.flowhs.fsm.update.FlowUpdateFsm) Set(java.util.Set) State(org.openkilda.wfm.topology.flowhs.fsm.update.FlowUpdateFsm.State) FlowResources(org.openkilda.wfm.share.flow.resources.FlowResources) Sets(com.google.common.collect.Sets) Event(org.openkilda.wfm.topology.flowhs.fsm.update.FlowUpdateFsm.Event) Slf4j(lombok.extern.slf4j.Slf4j) List(java.util.List) FlowUpdateContext(org.openkilda.wfm.topology.flowhs.fsm.update.FlowUpdateContext) PathComputer(org.openkilda.pce.PathComputer) FlowResourcesManager(org.openkilda.wfm.share.flow.resources.FlowResourcesManager) GetPathsResult(org.openkilda.pce.GetPathsResult) FlowResources(org.openkilda.wfm.share.flow.resources.FlowResources) ArrayList(java.util.ArrayList) Flow(org.openkilda.model.Flow) FlowPathPair(org.openkilda.wfm.topology.flow.model.FlowPathPair) GetPathsResult(org.openkilda.pce.GetPathsResult) PathId(org.openkilda.model.PathId) FlowPath(org.openkilda.model.FlowPath) ResourceAllocationException(org.openkilda.wfm.share.flow.resources.ResourceAllocationException)

Example 3 with FlowPathPair

use of org.openkilda.wfm.topology.flow.model.FlowPathPair in project open-kilda by telstra.

the class CompleteFlowPathRemovalAction method removeOldProtectedFlowPaths.

private void removeOldProtectedFlowPaths(Flow originalFlow, FlowUpdateFsm stateMachine) {
    PathId oldProtectedForwardPathId = stateMachine.getOldProtectedForwardPath();
    PathId oldProtectedReversePathId = stateMachine.getOldProtectedReversePath();
    if (oldProtectedForwardPathId != null || oldProtectedReversePathId != null) {
        FlowPath oldProtectedForward = flowPathRepository.remove(oldProtectedForwardPathId).orElse(null);
        FlowPath oldProtectedReverse = flowPathRepository.remove(oldProtectedReversePathId).orElse(null);
        FlowPathPair removedPaths = null;
        if (oldProtectedForward != null) {
            if (oldProtectedReverse != null) {
                log.debug("Removed the flow paths {} / {}", oldProtectedForward, oldProtectedReverse);
                removedPaths = new FlowPathPair(oldProtectedForward, oldProtectedReverse);
                updateIslsForFlowPath(removedPaths.getForward(), removedPaths.getReverse());
            } else {
                log.debug("Removed the flow path {} (no reverse pair)", oldProtectedForward);
                // TODO: History dumps require paired paths, fix it to support any (without opposite one).
                removedPaths = new FlowPathPair(oldProtectedForward, oldProtectedForward);
                updateIslsForFlowPath(removedPaths.getForward());
            }
        } else if (oldProtectedReverse != null) {
            log.debug("Removed the flow path {} (no forward pair)", oldProtectedReverse);
            // TODO: History dumps require paired paths, fix it to support any (without opposite one).
            removedPaths = new FlowPathPair(oldProtectedReverse, oldProtectedReverse);
            updateIslsForFlowPath(removedPaths.getReverse());
        }
        if (removedPaths != null) {
            saveRemovalActionWithDumpToHistory(stateMachine, originalFlow, removedPaths);
        }
    }
}
Also used : PathId(org.openkilda.model.PathId) FlowPath(org.openkilda.model.FlowPath) FlowPathPair(org.openkilda.wfm.topology.flow.model.FlowPathPair)

Example 4 with FlowPathPair

use of org.openkilda.wfm.topology.flow.model.FlowPathPair in project open-kilda by telstra.

the class CompleteFlowPathRemovalAction method removeOldPrimaryFlowPaths.

private void removeOldPrimaryFlowPaths(Flow originalFlow, FlowUpdateFsm stateMachine) {
    PathId oldPrimaryForwardPathId = stateMachine.getOldPrimaryForwardPath();
    PathId oldPrimaryReversePathId = stateMachine.getOldPrimaryReversePath();
    if (oldPrimaryForwardPathId != null || oldPrimaryReversePathId != null) {
        FlowPath oldPrimaryForward = flowPathRepository.remove(oldPrimaryForwardPathId).orElse(null);
        FlowPath oldPrimaryReverse = flowPathRepository.remove(oldPrimaryReversePathId).orElse(null);
        FlowPathPair removedPaths = null;
        if (oldPrimaryForward != null) {
            if (oldPrimaryReverse != null) {
                log.debug("Removed the flow paths {} / {}", oldPrimaryForward, oldPrimaryReverse);
                removedPaths = new FlowPathPair(oldPrimaryForward, oldPrimaryReverse);
                updateIslsForFlowPath(removedPaths.getForward(), removedPaths.getReverse());
            } else {
                log.debug("Removed the flow path {} (no reverse pair)", oldPrimaryForward);
                // TODO: History dumps require paired paths, fix it to support any (without opposite one).
                removedPaths = new FlowPathPair(oldPrimaryForward, oldPrimaryForward);
                updateIslsForFlowPath(removedPaths.getForward());
            }
        } else if (oldPrimaryReverse != null) {
            log.debug("Removed the flow path {} (no forward pair)", oldPrimaryReverse);
            // TODO: History dumps require paired paths, fix it to support any (without opposite one).
            removedPaths = new FlowPathPair(oldPrimaryReverse, oldPrimaryReverse);
            updateIslsForFlowPath(removedPaths.getReverse());
        }
        if (removedPaths != null) {
            saveRemovalActionWithDumpToHistory(stateMachine, originalFlow, removedPaths);
        }
    }
}
Also used : PathId(org.openkilda.model.PathId) FlowPath(org.openkilda.model.FlowPath) FlowPathPair(org.openkilda.wfm.topology.flow.model.FlowPathPair)

Example 5 with FlowPathPair

use of org.openkilda.wfm.topology.flow.model.FlowPathPair in project open-kilda by telstra.

the class BaseResourceAllocationAction method allocatePathPair.

@SneakyThrows
protected GetPathsResult allocatePathPair(Flow flow, PathId newForwardPathId, PathId newReversePathId, boolean forceToIgnoreBandwidth, List<PathId> pathsToReuseBandwidth, FlowPathPair oldPaths, boolean allowOldPaths, String sharedBandwidthGroupId, Predicate<GetPathsResult> whetherCreatePathSegments) throws RecoverableException, UnroutableFlowException, ResourceAllocationException {
    // Lazy initialisable map with reused bandwidth...
    Supplier<Map<IslEndpoints, Long>> reuseBandwidthPerIsl = Suppliers.memoize(() -> {
        Map<IslEndpoints, Long> result = new HashMap<>();
        if (pathsToReuseBandwidth != null && !pathsToReuseBandwidth.isEmpty()) {
            pathsToReuseBandwidth.stream().map(pathId -> flow.getPath(pathId).orElse(flowPathRepository.findById(pathId).orElse(null))).filter(Objects::nonNull).flatMap(path -> path.getSegments().stream()).forEach(segment -> {
                IslEndpoints isl = new IslEndpoints(segment.getSrcSwitchId().toString(), segment.getSrcPort(), segment.getDestSwitchId().toString(), segment.getDestPort());
                result.put(isl, result.getOrDefault(isl, 0L) + segment.getBandwidth());
            });
        }
        return result;
    });
    RetryPolicy<GetPathsResult> pathAllocationRetryPolicy = new RetryPolicy<GetPathsResult>().handle(RecoverableException.class).handle(ResourceAllocationException.class).handle(UnroutableFlowException.class).handle(PersistenceException.class).onRetry(e -> log.warn("Failure in path allocation. Retrying #{}...", e.getAttemptCount(), e.getLastFailure())).onRetriesExceeded(e -> log.warn("Failure in path allocation. No more retries", e.getFailure())).withMaxRetries(pathAllocationRetriesLimit);
    if (pathAllocationRetryDelay > 0) {
        pathAllocationRetryPolicy.withDelay(Duration.ofMillis(pathAllocationRetryDelay));
    }
    try {
        return Failsafe.with(pathAllocationRetryPolicy).get(() -> {
            GetPathsResult potentialPath;
            if (forceToIgnoreBandwidth) {
                boolean originalIgnoreBandwidth = flow.isIgnoreBandwidth();
                flow.setIgnoreBandwidth(true);
                potentialPath = pathComputer.getPath(flow);
                flow.setIgnoreBandwidth(originalIgnoreBandwidth);
            } else {
                potentialPath = pathComputer.getPath(flow, pathsToReuseBandwidth);
            }
            boolean newPathFound = isNotSamePath(potentialPath, oldPaths);
            if (allowOldPaths || newPathFound) {
                if (!newPathFound) {
                    log.debug("Found the same path for flow {}. Proceed with recreating it", flow.getFlowId());
                }
                if (whetherCreatePathSegments.test(potentialPath)) {
                    boolean ignoreBandwidth = forceToIgnoreBandwidth || flow.isIgnoreBandwidth();
                    List<PathSegment> forwardSegments = flowPathBuilder.buildPathSegments(newForwardPathId, potentialPath.getForward(), flow.getBandwidth(), ignoreBandwidth, sharedBandwidthGroupId);
                    List<PathSegment> reverseSegments = flowPathBuilder.buildPathSegments(newReversePathId, potentialPath.getReverse(), flow.getBandwidth(), ignoreBandwidth, sharedBandwidthGroupId);
                    transactionManager.doInTransaction(() -> {
                        createPathSegments(forwardSegments, reuseBandwidthPerIsl);
                        createPathSegments(reverseSegments, reuseBandwidthPerIsl);
                    });
                }
                return potentialPath;
            }
            return null;
        });
    } catch (FailsafeException ex) {
        throw ex.getCause();
    }
}
Also used : FlowPath(org.openkilda.model.FlowPath) HistoryMapper(org.openkilda.wfm.share.mappers.HistoryMapper) SneakyThrows(lombok.SneakyThrows) ResourceAllocationException(org.openkilda.wfm.share.flow.resources.ResourceAllocationException) FlowPathStatus(org.openkilda.model.FlowPathStatus) UnroutableFlowException(org.openkilda.pce.exception.UnroutableFlowException) FlowPathSwappingFsm(org.openkilda.wfm.topology.flowhs.fsm.common.FlowPathSwappingFsm) FailsafeException(net.jodah.failsafe.FailsafeException) Flow(org.openkilda.model.Flow) Duration(java.time.Duration) Map(java.util.Map) FlowPathPair(org.openkilda.wfm.topology.flow.model.FlowPathPair) DumpType(org.openkilda.wfm.share.history.model.FlowDumpData.DumpType) Path(org.openkilda.pce.Path) SwitchProperties(org.openkilda.model.SwitchProperties) IslEndpoints(org.openkilda.persistence.repositories.IslRepository.IslEndpoints) Predicate(java.util.function.Predicate) Collection(java.util.Collection) RetryPolicy(net.jodah.failsafe.RetryPolicy) PersistenceException(org.openkilda.persistence.exceptions.PersistenceException) FlowResources(org.openkilda.wfm.share.flow.resources.FlowResources) String.format(java.lang.String.format) Objects(java.util.Objects) SwitchPropertiesRepository(org.openkilda.persistence.repositories.SwitchPropertiesRepository) Slf4j(lombok.extern.slf4j.Slf4j) List(java.util.List) FlowDumpData(org.openkilda.wfm.share.history.model.FlowDumpData) PathComputer(org.openkilda.pce.PathComputer) Optional(java.util.Optional) ConstraintViolationException(org.openkilda.persistence.exceptions.ConstraintViolationException) SwitchRepository(org.openkilda.persistence.repositories.SwitchRepository) FlowSegmentCookieBuilder(org.openkilda.model.cookie.FlowSegmentCookie.FlowSegmentCookieBuilder) Message(org.openkilda.messaging.Message) PathSegment(org.openkilda.model.PathSegment) KildaConfigurationRepository(org.openkilda.persistence.repositories.KildaConfigurationRepository) HashMap(java.util.HashMap) Supplier(java.util.function.Supplier) RecoverableException(org.openkilda.pce.exception.RecoverableException) ArrayList(java.util.ArrayList) FlowPathDirection(org.openkilda.model.FlowPathDirection) PathSegmentRepository(org.openkilda.persistence.repositories.PathSegmentRepository) IslRepository(org.openkilda.persistence.repositories.IslRepository) Suppliers(com.google.common.base.Suppliers) FlowSegmentCookie(org.openkilda.model.cookie.FlowSegmentCookie) PersistenceManager(org.openkilda.persistence.PersistenceManager) PathId(org.openkilda.model.PathId) DetectConnectedDevices(org.openkilda.model.DetectConnectedDevices) FlowOperationsDashboardLogger(org.openkilda.wfm.share.logger.FlowOperationsDashboardLogger) ErrorType(org.openkilda.messaging.error.ErrorType) IslStatus(org.openkilda.model.IslStatus) Failsafe(net.jodah.failsafe.Failsafe) RepositoryFactory(org.openkilda.persistence.repositories.RepositoryFactory) FlowPathBuilder(org.openkilda.wfm.topology.flowhs.service.FlowPathBuilder) SwitchId(org.openkilda.model.SwitchId) FlowResourcesManager(org.openkilda.wfm.share.flow.resources.FlowResourcesManager) GetPathsResult(org.openkilda.pce.GetPathsResult) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Isl(org.openkilda.model.Isl) LazyMap(org.apache.commons.collections4.map.LazyMap) HashMap(java.util.HashMap) FailsafeException(net.jodah.failsafe.FailsafeException) PathSegment(org.openkilda.model.PathSegment) GetPathsResult(org.openkilda.pce.GetPathsResult) IslEndpoints(org.openkilda.persistence.repositories.IslRepository.IslEndpoints) Objects(java.util.Objects) PersistenceException(org.openkilda.persistence.exceptions.PersistenceException) ResourceAllocationException(org.openkilda.wfm.share.flow.resources.ResourceAllocationException) Map(java.util.Map) HashMap(java.util.HashMap) LazyMap(org.apache.commons.collections4.map.LazyMap) SneakyThrows(lombok.SneakyThrows)

Aggregations

FlowPathPair (org.openkilda.wfm.topology.flow.model.FlowPathPair)12 PathId (org.openkilda.model.PathId)10 FlowPath (org.openkilda.model.FlowPath)9 Flow (org.openkilda.model.Flow)7 GetPathsResult (org.openkilda.pce.GetPathsResult)5 FlowResources (org.openkilda.wfm.share.flow.resources.FlowResources)5 ResourceAllocationException (org.openkilda.wfm.share.flow.resources.ResourceAllocationException)4 ArrayList (java.util.ArrayList)3 List (java.util.List)3 Predicate (java.util.function.Predicate)3 Slf4j (lombok.extern.slf4j.Slf4j)3 ErrorType (org.openkilda.messaging.error.ErrorType)3 PathComputer (org.openkilda.pce.PathComputer)3 RecoverableException (org.openkilda.pce.exception.RecoverableException)3 UnroutableFlowException (org.openkilda.pce.exception.UnroutableFlowException)3 PersistenceManager (org.openkilda.persistence.PersistenceManager)3 FlowResourcesManager (org.openkilda.wfm.share.flow.resources.FlowResourcesManager)3 FlowOperationsDashboardLogger (org.openkilda.wfm.share.logger.FlowOperationsDashboardLogger)3 TimedExecution (org.openkilda.wfm.share.metrics.TimedExecution)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1