Search in sources :

Example 6 with IslEndpoint

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

the class RerouteServiceTest method handlePathNoFoundException.

@Test
public void handlePathNoFoundException() {
    PathNode islSide = new PathNode(SWITCH_A.getSwitchId(), 1, 0);
    FlowPathRepository pathRepository = mock(FlowPathRepository.class);
    when(pathRepository.findBySegmentEndpoint(eq(islSide.getSwitchId()), eq(islSide.getPortNo()))).thenReturn(asList(regularFlow.getForwardPath(), regularFlow.getReversePath()));
    FlowRepository flowRepository = mock(FlowRepository.class);
    RepositoryFactory repositoryFactory = mock(RepositoryFactory.class);
    when(repositoryFactory.createPathSegmentRepository()).thenReturn(mock(PathSegmentRepository.class));
    when(repositoryFactory.createFlowPathRepository()).thenReturn(pathRepository);
    when(repositoryFactory.createFlowRepository()).thenReturn(flowRepository);
    PersistenceManager persistenceManager = mock(PersistenceManager.class);
    when(persistenceManager.getRepositoryFactory()).thenReturn(repositoryFactory);
    when(persistenceManager.getTransactionManager()).thenReturn(transactionManager);
    RerouteService rerouteService = new RerouteService(persistenceManager);
    RerouteAffectedFlows request = new RerouteAffectedFlows(islSide, "dummy-reason - unittest");
    rerouteService.rerouteAffectedFlows(carrier, CORRELATION_ID, request);
    verify(flowRepository).updateStatusSafe(eq(regularFlow), eq(FlowStatus.DOWN), any());
    FlowThrottlingData expected = FlowThrottlingData.builder().correlationId(CORRELATION_ID).priority(regularFlow.getPriority()).timeCreate(regularFlow.getTimeCreate()).affectedIsl(Collections.singleton(new IslEndpoint(islSide.getSwitchId(), islSide.getPortNo()))).force(false).effectivelyDown(true).reason(request.getReason()).build();
    verify(carrier).emitRerouteCommand(eq(regularFlow.getFlowId()), eq(expected));
}
Also used : FlowPathRepository(org.openkilda.persistence.repositories.FlowPathRepository) FlowRepository(org.openkilda.persistence.repositories.FlowRepository) YFlowRepository(org.openkilda.persistence.repositories.YFlowRepository) IslEndpoint(org.openkilda.model.IslEndpoint) PathSegmentRepository(org.openkilda.persistence.repositories.PathSegmentRepository) PersistenceManager(org.openkilda.persistence.PersistenceManager) FlowThrottlingData(org.openkilda.wfm.topology.reroute.model.FlowThrottlingData) RepositoryFactory(org.openkilda.persistence.repositories.RepositoryFactory) RerouteAffectedFlows(org.openkilda.messaging.command.reroute.RerouteAffectedFlows) PathNode(org.openkilda.messaging.info.event.PathNode) Test(org.junit.Test)

Example 7 with IslEndpoint

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

the class RerouteQueueServiceTest method shouldMergeAndSendRetryWithPendingRequestWhenReceivedFailedRuleInstallResponseOnTransitSwitch.

@Test
public void shouldMergeAndSendRetryWithPendingRequestWhenReceivedFailedRuleInstallResponseOnTransitSwitch() {
    FlowThrottlingData inProgress = getFlowThrottlingData(flow, CORRELATION_ID).build();
    FlowThrottlingData pending = FlowThrottlingData.builder().correlationId("pending").priority(7).timeCreate(flow.getTimeCreate()).affectedIsl(Collections.singleton(new IslEndpoint(SWITCH_ID_A, 1))).force(false).effectivelyDown(true).reason("another reason").build();
    RerouteQueue rerouteQueue = RerouteQueue.builder().inProgress(inProgress).pending(pending).build();
    rerouteQueueService.getReroutes().put(FLOW_ID, rerouteQueue);
    RerouteResultInfoData rerouteResultInfoData = RerouteResultInfoData.builder().flowId(FLOW_ID).success(false).rerouteError(new SpeakerRequestError("Failed to install rules", Collections.singleton(SWITCH_C.getSwitchId()))).build();
    rerouteQueueService.processRerouteResult(rerouteResultInfoData, CORRELATION_ID);
    String retryCorrelationId = CORRELATION_ID + " : retry #1 ignore_bw false";
    FlowThrottlingData expected = getFlowThrottlingData(flow, retryCorrelationId).build();
    expected.setPriority(pending.getPriority());
    expected.setReason(pending.getReason());
    assertEquals(expected, rerouteQueue.getInProgress());
    assertNull(rerouteQueue.getPending());
    assertNull(rerouteQueue.getThrottling());
    FlowRerouteRequest expectedRequest = getFlowRerouteRequest(FLOW_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) FlowRerouteRequest(org.openkilda.messaging.command.flow.FlowRerouteRequest) 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 8 with IslEndpoint

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

the class ValidateYFlowAction method performWithResponse.

@Override
protected Optional<Message> performWithResponse(State from, State to, Event event, YFlowRerouteContext context, YFlowRerouteFsm stateMachine) {
    boolean isOperationAllowed = featureTogglesRepository.getOrDefault().getModifyYFlowEnabled();
    if (!isOperationAllowed) {
        throw new FlowProcessingException(ErrorType.NOT_PERMITTED, "Y-flow reroute feature is disabled");
    }
    YFlowRerouteRequest request = context.getRerouteRequest();
    String yFlowId = request.getYFlowId();
    Set<IslEndpoint> affectedIsls = new HashSet<>(Optional.ofNullable(request.getAffectedIsl()).orElse(emptySet()));
    dashboardLogger.onYFlowReroute(yFlowId, affectedIsls, request.isForce());
    stateMachine.setAffectedIsls(affectedIsls);
    stateMachine.setRerouteReason(request.getReason());
    stateMachine.setForceReroute(request.isForce());
    stateMachine.setIgnoreBandwidth(request.isIgnoreBandwidth());
    YFlow yFlow = transactionManager.doInTransaction(() -> {
        YFlow result = yFlowRepository.findById(yFlowId).orElseThrow(() -> new FlowProcessingException(ErrorType.NOT_FOUND, format("Y-flow %s not found", yFlowId)));
        if (result.getStatus() == FlowStatus.IN_PROGRESS) {
            throw new FlowProcessingException(ErrorType.REQUEST_INVALID, format("Y-flow %s is in progress now", yFlowId));
        }
        // Keep it, just in case we have to revert it.
        stateMachine.setOriginalYFlowStatus(result.getStatus());
        result.setStatus(FlowStatus.IN_PROGRESS);
        return result;
    });
    Collection<Flow> subFlows = yFlow.getSubFlows().stream().map(YSubFlow::getFlow).collect(Collectors.toList());
    Flow mainAffinitySubFlow = subFlows.stream().filter(flow -> flow.getFlowId().equals(flow.getAffinityGroupId())).findFirst().orElseThrow(() -> new FlowProcessingException(ErrorType.DATA_INVALID, format("Main affinity sub-flow of the y-flow %s not found", yFlowId)));
    stateMachine.setMainAffinityFlowId(mainAffinitySubFlow.getFlowId());
    boolean mainAffinitySubFlowIsAffected = isFlowAffected(mainAffinitySubFlow, affectedIsls);
    Set<String> affectedFlowIds = subFlows.stream().filter(flow -> mainAffinitySubFlowIsAffected || isFlowAffected(flow, affectedIsls)).map(Flow::getFlowId).collect(Collectors.toSet());
    stateMachine.setTargetSubFlowIds(affectedFlowIds);
    stateMachine.saveNewEventToHistory("Y-flow was validated successfully", FlowEventData.Event.REROUTE);
    return Optional.empty();
}
Also used : YFlow(org.openkilda.model.YFlow) IslEndpoint(org.openkilda.model.IslEndpoint) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) YFlowRerouteRequest(org.openkilda.messaging.command.yflow.YFlowRerouteRequest) HashSet(java.util.HashSet) Flow(org.openkilda.model.Flow) YFlow(org.openkilda.model.YFlow) YSubFlow(org.openkilda.model.YSubFlow)

Example 9 with IslEndpoint

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

the class PersistenceDummyEntityFactory method makePathSegments.

private List<PathSegment> makePathSegments(PathId pathId, SwitchId sourceSwitchId, SwitchId destSwitchId, List<IslDirectionalReference> pathHint) {
    List<PathSegment> results = new ArrayList<>();
    IslDirectionalReference first = null;
    IslDirectionalReference last = null;
    for (IslDirectionalReference entry : pathHint) {
        last = entry;
        if (first == null) {
            first = entry;
        }
        IslEndpoint source = entry.getSourceEndpoint();
        Switch sourceSwitch = fetchOrCreateSwitch(source.getSwitchId());
        IslEndpoint dest = entry.getDestEndpoint();
        Switch destSwitch = fetchOrCreateSwitch(dest.getSwitchId());
        fetchOrCreateIsl(entry);
        results.add(PathSegment.builder().pathId(pathId).srcSwitch(sourceSwitch).srcPort(source.getPortNumber()).destSwitch(destSwitch).destPort(dest.getPortNumber()).build());
    }
    if (first != null && !sourceSwitchId.equals(first.getSourceEndpoint().getSwitchId())) {
        throw new IllegalArgumentException(String.format("Flow's trace do not start on flow endpoint (a-end switch %s, first path's hint entry %s)", sourceSwitchId, first));
    }
    if (last != null && !destSwitchId.equals(last.getDestEndpoint().getSwitchId())) {
        throw new IllegalArgumentException(String.format("Flow's trace do not end on flow endpoint (z-end switch %s, last path's hint entry %s)", destSwitchId, last));
    }
    return results;
}
Also used : IslEndpoint(org.openkilda.model.IslEndpoint) Switch(org.openkilda.model.Switch) ArrayList(java.util.ArrayList) PathSegment(org.openkilda.model.PathSegment)

Example 10 with IslEndpoint

use of org.openkilda.model.IslEndpoint 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)

Aggregations

IslEndpoint (org.openkilda.model.IslEndpoint)27 Test (org.junit.Test)13 Flow (org.openkilda.model.Flow)9 FlowThrottlingData (org.openkilda.wfm.topology.reroute.model.FlowThrottlingData)8 FlowRerouteRequest (org.openkilda.messaging.command.flow.FlowRerouteRequest)7 HashSet (java.util.HashSet)6 YFlowRerouteRequest (org.openkilda.messaging.command.yflow.YFlowRerouteRequest)6 FlowPath (org.openkilda.model.FlowPath)6 SwitchId (org.openkilda.model.SwitchId)5 PathNode (org.openkilda.messaging.info.event.PathNode)4 TimedExecution (org.openkilda.wfm.share.metrics.TimedExecution)4 RerouteQueue (org.openkilda.wfm.topology.reroute.model.RerouteQueue)4 Values (org.apache.storm.tuple.Values)3 YFlowRequest (org.openkilda.messaging.command.yflow.YFlowRequest)3 MessageException (org.openkilda.messaging.error.MessageException)3 PathSegment (org.openkilda.model.PathSegment)3 YFlow (org.openkilda.model.YFlow)3 AbstractYFlowTest (org.openkilda.wfm.topology.flowhs.service.AbstractYFlowTest)3 ArrayList (java.util.ArrayList)2 FlowSegmentRequest (org.openkilda.floodlight.api.request.FlowSegmentRequest)2