Search in sources :

Example 16 with FlowPath

use of org.openkilda.model.FlowPath 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 17 with FlowPath

use of org.openkilda.model.FlowPath 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 18 with FlowPath

use of org.openkilda.model.FlowPath 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 19 with FlowPath

use of org.openkilda.model.FlowPath in project open-kilda by telstra.

the class InstallNonIngressRulesAction method perform.

@Override
protected void perform(State from, State to, Event event, FlowRerouteContext context, FlowRerouteFsm stateMachine) {
    String flowId = stateMachine.getFlowId();
    Flow flow = getFlow(flowId);
    // Detach the entity to avoid propagation to the database.
    flowRepository.detach(flow);
    if (stateMachine.getNewEncapsulationType() != null) {
        // This is for commandBuilder.buildAllExceptIngress() to use proper (updated) encapsulation type.
        flow.setEncapsulationType(stateMachine.getNewEncapsulationType());
    }
    FlowCommandBuilder commandBuilder = commandBuilderFactory.getBuilder(flow.getEncapsulationType());
    Collection<FlowSegmentRequestFactory> requestFactories = new ArrayList<>();
    if (stateMachine.getNewPrimaryForwardPath() != null && stateMachine.getNewPrimaryReversePath() != null) {
        FlowPath newForward = getFlowPath(flow, stateMachine.getNewPrimaryForwardPath());
        FlowPath newReverse = getFlowPath(flow, stateMachine.getNewPrimaryReversePath());
        requestFactories.addAll(commandBuilder.buildAllExceptIngress(stateMachine.getCommandContext(), flow, newForward, newReverse));
    }
    if (stateMachine.getNewProtectedForwardPath() != null && stateMachine.getNewProtectedReversePath() != null) {
        FlowPath newForward = getFlowPath(flow, stateMachine.getNewProtectedForwardPath());
        FlowPath newReverse = getFlowPath(flow, stateMachine.getNewProtectedReversePath());
        requestFactories.addAll(commandBuilder.buildAllExceptIngress(stateMachine.getCommandContext(), flow, newForward, newReverse));
    }
    stateMachine.clearPendingAndRetriedAndFailedCommands();
    if (requestFactories.isEmpty()) {
        stateMachine.saveActionToHistory("No need to install non ingress rules");
        stateMachine.fire(Event.RULES_INSTALLED);
    } else {
        Map<UUID, FlowSegmentRequestFactory> requestsStorage = stateMachine.getNonIngressCommands();
        for (FlowSegmentRequestFactory factory : requestFactories) {
            FlowSegmentRequest request = factory.makeInstallRequest(commandIdGenerator.generate());
            // TODO ensure no conflicts
            requestsStorage.put(request.getCommandId(), factory);
            stateMachine.getCarrier().sendSpeakerRequest(request);
        }
        requestsStorage.forEach((key, value) -> stateMachine.addPendingCommand(key, value.getSwitchId()));
        stateMachine.saveActionToHistory("Commands for installing non ingress rules have been sent");
    }
}
Also used : FlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.FlowSegmentRequestFactory) FlowSegmentRequest(org.openkilda.floodlight.api.request.FlowSegmentRequest) ArrayList(java.util.ArrayList) FlowCommandBuilder(org.openkilda.wfm.topology.flowhs.service.FlowCommandBuilder) FlowPath(org.openkilda.model.FlowPath) UUID(java.util.UUID) Flow(org.openkilda.model.Flow)

Example 20 with FlowPath

use of org.openkilda.model.FlowPath in project open-kilda by telstra.

the class OnSubFlowAllocatedAction method buildRerouteResponseMessage.

private Message buildRerouteResponseMessage(YFlowRerouteFsm stateMachine) {
    String yFlowId = stateMachine.getYFlowId();
    List<Long> oldFlowPathCookies = stateMachine.getOldYFlowPathCookies();
    List<FlowPath> flowPaths = transactionManager.doInTransaction(() -> {
        YFlow yflow = yFlowRepository.findById(yFlowId).orElseThrow(() -> new FlowProcessingException(ErrorType.NOT_FOUND, format("Y-flow %s not found", yFlowId)));
        SwitchId sharedSwitchId = yflow.getSharedEndpoint().getSwitchId();
        List<FlowPath> paths = new ArrayList<>();
        for (YSubFlow subFlow : yflow.getSubFlows()) {
            Flow flow = subFlow.getFlow();
            FlowPath flowPath = flow.getPaths().stream().filter(path -> sharedSwitchId.equals(path.getSrcSwitchId()) && !path.isProtected() && !oldFlowPathCookies.contains(path.getCookie().getValue())).findFirst().orElse(sharedSwitchId.equals(flow.getForwardPath().getSrcSwitchId()) ? flow.getForwardPath() : flow.getReversePath());
            paths.add(flowPath);
        }
        return paths;
    });
    List<PathSegment> sharedPathSegments = IntersectionComputer.calculatePathIntersectionFromSource(flowPaths);
    PathInfoData sharedPath = FlowPathMapper.INSTANCE.map(sharedPathSegments);
    List<SubFlowPathDto> subFlowPathDtos = flowPaths.stream().map(flowPath -> new SubFlowPathDto(flowPath.getFlowId(), FlowPathMapper.INSTANCE.map(flowPath))).sorted(Comparator.comparing(SubFlowPathDto::getFlowId)).collect(Collectors.toList());
    PathInfoData oldSharedPath = stateMachine.getOldSharedPath();
    List<SubFlowPathDto> oldSubFlowPathDtos = stateMachine.getOldSubFlowPathDtos();
    YFlowRerouteResponse response = new YFlowRerouteResponse(sharedPath, subFlowPathDtos, !(sharedPath.equals(oldSharedPath) && subFlowPathDtos.equals(oldSubFlowPathDtos)));
    CommandContext commandContext = stateMachine.getCommandContext();
    return new InfoMessage(response, commandContext.getCreateTime(), commandContext.getCorrelationId());
}
Also used : YFlow(org.openkilda.model.YFlow) CommandContext(org.openkilda.wfm.CommandContext) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) ArrayList(java.util.ArrayList) SwitchId(org.openkilda.model.SwitchId) PathSegment(org.openkilda.model.PathSegment) YSubFlow(org.openkilda.model.YSubFlow) Flow(org.openkilda.model.Flow) YFlow(org.openkilda.model.YFlow) YSubFlow(org.openkilda.model.YSubFlow) PathInfoData(org.openkilda.messaging.info.event.PathInfoData) YFlowRerouteResponse(org.openkilda.messaging.command.yflow.YFlowRerouteResponse) InfoMessage(org.openkilda.messaging.info.InfoMessage) FlowPath(org.openkilda.model.FlowPath) SubFlowPathDto(org.openkilda.messaging.command.yflow.SubFlowPathDto)

Aggregations

FlowPath (org.openkilda.model.FlowPath)229 Flow (org.openkilda.model.Flow)128 Test (org.junit.Test)108 PathId (org.openkilda.model.PathId)65 PathSegment (org.openkilda.model.PathSegment)42 SwitchId (org.openkilda.model.SwitchId)40 ArrayList (java.util.ArrayList)39 FlowSegmentCookie (org.openkilda.model.cookie.FlowSegmentCookie)33 InMemoryGraphBasedTest (org.openkilda.persistence.inmemory.InMemoryGraphBasedTest)29 Switch (org.openkilda.model.Switch)28 FlowSpeakerData (org.openkilda.rulemanager.FlowSpeakerData)27 SpeakerData (org.openkilda.rulemanager.SpeakerData)27 Action (org.openkilda.rulemanager.action.Action)26 PopVlanAction (org.openkilda.rulemanager.action.PopVlanAction)26 PopVxlanAction (org.openkilda.rulemanager.action.PopVxlanAction)26 PortOutAction (org.openkilda.rulemanager.action.PortOutAction)26 PushVlanAction (org.openkilda.rulemanager.action.PushVlanAction)26 SetFieldAction (org.openkilda.rulemanager.action.SetFieldAction)26 MeterId (org.openkilda.model.MeterId)20 YFlow (org.openkilda.model.YFlow)19