Search in sources :

Example 21 with FlowThrottlingData

use of org.openkilda.wfm.topology.reroute.model.FlowThrottlingData 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 22 with FlowThrottlingData

use of org.openkilda.wfm.topology.reroute.model.FlowThrottlingData in project open-kilda by telstra.

the class RerouteService method processRerouteRequest.

/**
 * Process manual y-flow reroute request.
 */
public void processRerouteRequest(MessageSender sender, String correlationId, YFlowRerouteRequest request) {
    Optional<YFlow> flow = yFlowRepository.findById(request.getYFlowId());
    FlowThrottlingData flowThrottlingData = getFlowThrottlingDataBuilder(flow.orElse(null)).correlationId(correlationId).affectedIsl(request.getAffectedIsl()).force(request.isForce()).reason(request.getReason()).build();
    sender.emitManualRerouteCommand(request.getYFlowId(), flowThrottlingData);
}
Also used : YFlow(org.openkilda.model.YFlow) FlowThrottlingData(org.openkilda.wfm.topology.reroute.model.FlowThrottlingData)

Example 23 with FlowThrottlingData

use of org.openkilda.wfm.topology.reroute.model.FlowThrottlingData 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)

Example 24 with FlowThrottlingData

use of org.openkilda.wfm.topology.reroute.model.FlowThrottlingData in project open-kilda by telstra.

the class RerouteQueueServiceTest method shouldMergeAndSendRetryWithPendingRequestWhenReceivedFailedRuleInstallResponseOnTransitSwitchYFlow.

@Test
public void shouldMergeAndSendRetryWithPendingRequestWhenReceivedFailedRuleInstallResponseOnTransitSwitchYFlow() {
    FlowThrottlingData inProgress = getFlowThrottlingData(yFlow, CORRELATION_ID).build();
    FlowThrottlingData pending = FlowThrottlingData.builder().correlationId("pending").priority(7).timeCreate(yFlow.getTimeCreate()).affectedIsl(Collections.singleton(new IslEndpoint(SWITCH_ID_A, 1))).force(false).effectivelyDown(true).reason("another reason").yFlow(true).build();
    RerouteQueue rerouteQueue = RerouteQueue.builder().inProgress(inProgress).pending(pending).build();
    rerouteQueueService.getReroutes().put(YFLOW_ID, rerouteQueue);
    RerouteResultInfoData rerouteResultInfoData = RerouteResultInfoData.builder().flowId(YFLOW_ID).success(false).rerouteError(new SpeakerRequestError("Failed to install rules", Collections.singleton(SWITCH_C.getSwitchId()))).yFlow(true).build();
    rerouteQueueService.processRerouteResult(rerouteResultInfoData, CORRELATION_ID);
    String retryCorrelationId = CORRELATION_ID + " : retry #1 ignore_bw false";
    FlowThrottlingData expected = getFlowThrottlingData(yFlow, retryCorrelationId).build();
    expected.setPriority(pending.getPriority());
    expected.setReason(pending.getReason());
    assertEquals(expected, rerouteQueue.getInProgress());
    assertNull(rerouteQueue.getPending());
    assertNull(rerouteQueue.getThrottling());
    YFlowRerouteRequest expectedRequest = getYFlowRerouteRequest(YFLOW_ID, expected);
    verify(carrier).sendRerouteRequest(eq(retryCorrelationId), eq(expectedRequest));
}
Also used : IslEndpoint(org.openkilda.model.IslEndpoint) FlowThrottlingData(org.openkilda.wfm.topology.reroute.model.FlowThrottlingData) RerouteQueue(org.openkilda.wfm.topology.reroute.model.RerouteQueue) YFlowRerouteRequest(org.openkilda.messaging.command.yflow.YFlowRerouteRequest) RerouteResultInfoData(org.openkilda.messaging.info.reroute.RerouteResultInfoData) SpeakerRequestError(org.openkilda.messaging.info.reroute.error.SpeakerRequestError) Test(org.junit.Test)

Example 25 with FlowThrottlingData

use of org.openkilda.wfm.topology.reroute.model.FlowThrottlingData in project open-kilda by telstra.

the class RerouteQueueServiceTest method shouldSendCorrectErrorMessageForManualRerouteRequestForPinnedYFlow.

@Test
public void shouldSendCorrectErrorMessageForManualRerouteRequestForPinnedYFlow() {
    String flowId = "test flow";
    when(yFlowRepository.findById(flowId)).thenReturn(Optional.of(YFlow.builder().yFlowId(flowId).sharedEndpoint(new SharedEndpoint(SWITCH_A.getSwitchId(), 10)).priority(2).pinned(true).build()));
    FlowThrottlingData actual = getFlowThrottlingData(yFlow, CORRELATION_ID).build();
    rerouteQueueService.processManualRequest(flowId, actual);
    assertEquals(0, rerouteQueueService.getReroutes().size());
    verify(carrier).emitFlowRerouteError(argThat(pinnedYFlowErrorData(flowId)));
}
Also used : FlowThrottlingData(org.openkilda.wfm.topology.reroute.model.FlowThrottlingData) SharedEndpoint(org.openkilda.model.YFlow.SharedEndpoint) Test(org.junit.Test)

Aggregations

FlowThrottlingData (org.openkilda.wfm.topology.reroute.model.FlowThrottlingData)34 Test (org.junit.Test)26 RerouteQueue (org.openkilda.wfm.topology.reroute.model.RerouteQueue)17 YFlowRerouteRequest (org.openkilda.messaging.command.yflow.YFlowRerouteRequest)9 IslEndpoint (org.openkilda.model.IslEndpoint)8 PersistenceManager (org.openkilda.persistence.PersistenceManager)7 FlowRerouteRequest (org.openkilda.messaging.command.flow.FlowRerouteRequest)6 RerouteResultInfoData (org.openkilda.messaging.info.reroute.RerouteResultInfoData)6 RepositoryFactory (org.openkilda.persistence.repositories.RepositoryFactory)6 YFlowRepository (org.openkilda.persistence.repositories.YFlowRepository)6 YFlow (org.openkilda.model.YFlow)5 PathNode (org.openkilda.messaging.info.event.PathNode)4 SpeakerRequestError (org.openkilda.messaging.info.reroute.error.SpeakerRequestError)4 Flow (org.openkilda.model.Flow)4 FlowPathRepository (org.openkilda.persistence.repositories.FlowPathRepository)4 FlowRepository (org.openkilda.persistence.repositories.FlowRepository)4 SwitchId (org.openkilda.model.SwitchId)3 HashMap (java.util.HashMap)2 Set (java.util.Set)2 RerouteAffectedFlows (org.openkilda.messaging.command.reroute.RerouteAffectedFlows)2