Search in sources :

Example 11 with FlowStatus

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

the class YFlowRerouteServiceTest method verifyYFlowStatus.

protected YFlow verifyYFlowStatus(String yFlowId, FlowStatus expectedStatus, FlowStatus expectedFirstSubFlowStatus, FlowStatus expectedSecondSubFlowStatus) {
    YFlow flow = getYFlow(yFlowId);
    assertEquals(expectedStatus, flow.getStatus());
    Set<FlowStatus> expectedSubFlowStatuses = Stream.of(expectedFirstSubFlowStatus, expectedSecondSubFlowStatus).collect(Collectors.toSet());
    Set<FlowStatus> actualSubFlowStatuses = flow.getSubFlows().stream().map(YSubFlow::getFlow).map(Flow::getStatus).collect(Collectors.toSet());
    assertEquals(expectedSubFlowStatuses, actualSubFlowStatuses);
    return flow;
}
Also used : YFlow(org.openkilda.model.YFlow) FlowStatus(org.openkilda.model.FlowStatus) YSubFlow(org.openkilda.model.YSubFlow)

Example 12 with FlowStatus

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

the class UpdateYFlowAction method perform.

@Override
protected void perform(State from, State to, Event event, YFlowUpdateContext context, YFlowUpdateFsm stateMachine) {
    YFlowRequest targetFlow = stateMachine.getTargetFlow();
    stateMachine.setDiverseFlowId(targetFlow.getDiverseFlowId());
    FlowStatus flowStatus = transactionManager.doInTransaction(() -> {
        YFlow yFlow = getYFlow(targetFlow.getYFlowId());
        saveOldResources(stateMachine, yFlow);
        stateMachine.setDeleteOldYFlowCommands(buildYFlowDeleteCommands(yFlow, stateMachine.getCommandContext()));
        updateFlow(yFlow, YFlowRequestMapper.INSTANCE.toYFlow(targetFlow));
        return yFlow.getStatus();
    });
    stateMachine.saveActionToHistory(format("The y-flow was updated. The status %s", flowStatus));
}
Also used : YFlow(org.openkilda.model.YFlow) YFlowRequest(org.openkilda.messaging.command.yflow.YFlowRequest) FlowStatus(org.openkilda.model.FlowStatus)

Example 13 with FlowStatus

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

the class RerouteService method rerouteInactiveFlows.

/**
 * Handles reroute on ISL up events.
 *
 * @param sender transport sender
 * @param correlationId correlation id to pass through
 * @param command origin command
 */
@TimedExecution("reroute_inactive_flows")
public void rerouteInactiveFlows(MessageSender sender, String correlationId, RerouteInactiveFlows command) {
    PathNode pathNode = command.getPathNode();
    int port = pathNode.getPortNo();
    SwitchId switchId = pathNode.getSwitchId();
    Map<String, FlowThrottlingData> flowsForReroute = transactionManager.doInTransaction(() -> {
        Map<String, FlowThrottlingData> forReroute = new HashMap<>();
        Map<Flow, Set<PathId>> flowsForRerouting = getInactiveFlowsForRerouting();
        for (Entry<Flow, Set<PathId>> entry : flowsForRerouting.entrySet()) {
            Flow flow = entry.getKey();
            Set<IslEndpoint> allAffectedIslEndpoints = new HashSet<>();
            for (FlowPath flowPath : flow.getPaths()) {
                Set<IslEndpoint> affectedIslEndpoints = new HashSet<>();
                PathSegment firstSegment = null;
                int failedSegmentsCount = 0;
                for (PathSegment pathSegment : flowPath.getSegments()) {
                    if (firstSegment == null) {
                        firstSegment = pathSegment;
                    }
                    if (pathSegment.isFailed()) {
                        affectedIslEndpoints.add(new IslEndpoint(pathSegment.getSrcSwitchId(), pathSegment.getSrcPort()));
                        affectedIslEndpoints.add(new IslEndpoint(pathSegment.getDestSwitchId(), pathSegment.getDestPort()));
                        if (pathSegment.containsNode(switchId, port)) {
                            pathSegment.setFailed(false);
                            pathSegmentRepository.updateFailedStatus(flowPath, pathSegment, false);
                        } else {
                            failedSegmentsCount++;
                        }
                    }
                }
                if (flowPath.getStatus().equals(FlowPathStatus.INACTIVE) && failedSegmentsCount == 0) {
                    updateFlowPathStatus(flowPath, FlowPathStatus.ACTIVE);
                    // force reroute of failed path only (required due to inaccurate path/segment state management)
                    if (affectedIslEndpoints.isEmpty() && firstSegment != null) {
                        affectedIslEndpoints.add(new IslEndpoint(firstSegment.getSrcSwitchId(), firstSegment.getSrcPort()));
                    }
                }
                allAffectedIslEndpoints.addAll(affectedIslEndpoints);
            }
            FlowStatus flowStatus = flow.computeFlowStatus();
            String flowStatusInfo = null;
            if (!FlowStatus.UP.equals(flowStatus)) {
                flowStatusInfo = command.getReason();
            }
            flowRepository.updateStatusSafe(flow, flowStatus, flowStatusInfo);
            if (flow.isPinned()) {
                log.info("Skipping reroute command for pinned flow {}", flow.getFlowId());
            } else if (flow.getYFlow() != null) {
                YFlow yFlow = flow.getYFlow();
                log.info("Create reroute command (attempt to restore inactive flows) request for {} " + "(affected ISL endpoints: {})", yFlow.getYFlowId(), allAffectedIslEndpoints);
                FlowThrottlingData flowThrottlingData = getFlowThrottlingDataBuilder(yFlow).correlationId(correlationId).affectedIsl(allAffectedIslEndpoints).force(false).effectivelyDown(true).reason(command.getReason()).build();
                sender.emitRerouteCommand(yFlow.getYFlowId(), flowThrottlingData);
            } else {
                log.info("Create reroute command (attempt to restore inactive flows) request for {} (affected ISL " + "endpoints: {})", flow.getFlowId(), allAffectedIslEndpoints);
                FlowThrottlingData flowThrottlingData = getFlowThrottlingDataBuilder(flow).correlationId(correlationId).affectedIsl(allAffectedIslEndpoints).force(false).effectivelyDown(true).reason(command.getReason()).build();
                forReroute.put(flow.getFlowId(), flowThrottlingData);
            }
        }
        return forReroute;
    });
    for (Entry<String, FlowThrottlingData> entry : flowsForReroute.entrySet()) {
        log.info("Produce reroute (attempt to restore inactive flows) request for {} (affected ISL endpoints: {})", entry.getKey(), entry.getValue().getAffectedIsl());
        sender.emitRerouteCommand(entry.getKey(), entry.getValue());
    }
}
Also used : YFlow(org.openkilda.model.YFlow) IslEndpoint(org.openkilda.model.IslEndpoint) HashSet(java.util.HashSet) Collectors.toSet(java.util.stream.Collectors.toSet) Set(java.util.Set) HashMap(java.util.HashMap) SwitchId(org.openkilda.model.SwitchId) PathSegment(org.openkilda.model.PathSegment) PathNode(org.openkilda.messaging.info.event.PathNode) IslEndpoint(org.openkilda.model.IslEndpoint) FlowStatus(org.openkilda.model.FlowStatus) Flow(org.openkilda.model.Flow) YFlow(org.openkilda.model.YFlow) FlowThrottlingData(org.openkilda.wfm.topology.reroute.model.FlowThrottlingData) FlowPath(org.openkilda.model.FlowPath) HashSet(java.util.HashSet) TimedExecution(org.openkilda.wfm.share.metrics.TimedExecution)

Example 14 with FlowStatus

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

the class RerouteService method processSingleSwitchFlowStatusUpdate.

/**
 * Handles request to update single switch flow status.
 */
public void processSingleSwitchFlowStatusUpdate(SwitchStateChanged request) {
    transactionManager.doInTransaction(() -> {
        Collection<Flow> affectedFlows = flowRepository.findOneSwitchFlows(request.getSwitchId());
        FlowStatus newFlowStatus = request.getStatus() == SwitchStatus.ACTIVE ? FlowStatus.UP : FlowStatus.DOWN;
        String newFlowStatusInfo = request.getStatus() == SwitchStatus.ACTIVE ? null : format("Switch %s is inactive", request.getSwitchId());
        FlowPathStatus newFlowPathStatus = request.getStatus() == SwitchStatus.ACTIVE ? FlowPathStatus.ACTIVE : FlowPathStatus.INACTIVE;
        for (Flow flow : affectedFlows) {
            log.info("Updating flow and path statuses for flow {} to {}, {}", flow.getFlowId(), newFlowStatus, newFlowPathStatus);
            flowDashboardLogger.onFlowStatusUpdate(flow.getFlowId(), newFlowStatus);
            flow.setStatus(newFlowStatus);
            flow.setStatusInfo(newFlowStatusInfo);
            flow.getForwardPath().setStatus(newFlowPathStatus);
            flow.getReversePath().setStatus(newFlowPathStatus);
        }
    });
}
Also used : FlowPathStatus(org.openkilda.model.FlowPathStatus) FlowStatus(org.openkilda.model.FlowStatus) Flow(org.openkilda.model.Flow) YFlow(org.openkilda.model.YFlow)

Example 15 with FlowStatus

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

the class RerouteService method rerouteAffectedFlows.

/**
 * Handles reroute on ISL down events.
 *
 * @param sender transport sender
 * @param correlationId correlation id to pass through
 * @param command origin command
 */
@TimedExecution("reroute_affected_flows")
public void rerouteAffectedFlows(MessageSender sender, String correlationId, RerouteAffectedFlows command) {
    // TODO(surabujin): need better/more detailed representation of failed ISL
    PathNode pathNode = command.getPathNode();
    int port = pathNode.getPortNo();
    SwitchId switchId = pathNode.getSwitchId();
    final IslEndpoint affectedIsl = new IslEndpoint(switchId, port);
    RerouteResult rerouteResult = transactionManager.doInTransaction(() -> {
        RerouteResult result = new RerouteResult();
        Collection<FlowPath> affectedFlowPaths = getAffectedFlowPaths(pathNode.getSwitchId(), pathNode.getPortNo());
        // swapping affected primary paths with available protected
        List<FlowPath> pathsForSwapping = getPathsForSwapping(affectedFlowPaths);
        for (FlowPath path : pathsForSwapping) {
            result.flowIdsForSwapPaths.add(path.getFlowId());
        }
        for (FlowWithAffectedPaths entry : groupPathsForRerouting(affectedFlowPaths)) {
            Flow flow = entry.getFlow();
            boolean rerouteRequired = updateFlowPathsStateForFlow(switchId, port, entry.getAffectedPaths());
            FlowStatus flowStatus = flow.computeFlowStatus();
            String flowStatusInfo = null;
            if (!FlowStatus.UP.equals(flowStatus)) {
                flowStatusInfo = command.getReason();
            }
            flowRepository.updateStatusSafe(flow, flowStatus, flowStatusInfo);
            if (rerouteRequired) {
                if (flow.getYFlow() != null) {
                    result.yFlowsForReroute.add(flow.getYFlow());
                } else {
                    result.flowsForReroute.add(flow);
                }
            }
        }
        Set<Flow> affectedPinnedFlows = groupAffectedPinnedFlows(affectedFlowPaths);
        for (Flow flow : affectedPinnedFlows) {
            List<FlowPath> flowPaths = new ArrayList<>(flow.getPaths());
            updateFlowPathsStateForFlow(switchId, port, flowPaths);
            if (flow.getStatus() != FlowStatus.DOWN) {
                flowDashboardLogger.onFlowStatusUpdate(flow.getFlowId(), FlowStatus.DOWN);
                flowRepository.updateStatusSafe(flow, FlowStatus.DOWN, command.getReason());
            }
        }
        return result;
    });
    for (String flowId : rerouteResult.flowIdsForSwapPaths) {
        sender.emitPathSwapCommand(correlationId, flowId, command.getReason());
    }
    for (Flow flow : rerouteResult.flowsForReroute) {
        FlowThrottlingData flowThrottlingData = getFlowThrottlingDataBuilder(flow).correlationId(correlationId).affectedIsl(Collections.singleton(affectedIsl)).force(false).effectivelyDown(true).reason(command.getReason()).build();
        sender.emitRerouteCommand(flow.getFlowId(), flowThrottlingData);
    }
    for (YFlow yFlow : rerouteResult.yFlowsForReroute) {
        FlowThrottlingData flowThrottlingData = getFlowThrottlingDataBuilder(yFlow).correlationId(correlationId).affectedIsl(Collections.singleton(affectedIsl)).force(false).effectivelyDown(true).reason(command.getReason()).build();
        sender.emitRerouteCommand(yFlow.getYFlowId(), flowThrottlingData);
    }
}
Also used : YFlow(org.openkilda.model.YFlow) IslEndpoint(org.openkilda.model.IslEndpoint) ArrayList(java.util.ArrayList) SwitchId(org.openkilda.model.SwitchId) PathNode(org.openkilda.messaging.info.event.PathNode) IslEndpoint(org.openkilda.model.IslEndpoint) FlowStatus(org.openkilda.model.FlowStatus) Flow(org.openkilda.model.Flow) YFlow(org.openkilda.model.YFlow) FlowThrottlingData(org.openkilda.wfm.topology.reroute.model.FlowThrottlingData) FlowPath(org.openkilda.model.FlowPath) TimedExecution(org.openkilda.wfm.share.metrics.TimedExecution)

Aggregations

FlowStatus (org.openkilda.model.FlowStatus)22 YFlow (org.openkilda.model.YFlow)11 Flow (org.openkilda.model.Flow)9 FlowPath (org.openkilda.model.FlowPath)4 FlowPathStatus (org.openkilda.model.FlowPathStatus)3 TimedExecution (org.openkilda.wfm.share.metrics.TimedExecution)3 YFlowRequest (org.openkilda.messaging.command.yflow.YFlowRequest)2 PathNode (org.openkilda.messaging.info.event.PathNode)2 IslEndpoint (org.openkilda.model.IslEndpoint)2 PathSegment (org.openkilda.model.PathSegment)2 SwitchId (org.openkilda.model.SwitchId)2 YSubFlow (org.openkilda.model.YSubFlow)2 FlowThrottlingData (org.openkilda.wfm.topology.reroute.model.FlowThrottlingData)2 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Set (java.util.Set)1 Collectors.toSet (java.util.stream.Collectors.toSet)1 Test (org.junit.Test)1 PersistenceManager (org.openkilda.persistence.PersistenceManager)1