Search in sources :

Example 16 with IslEndpoint

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

the class ValidateFlowAction method performWithResponse.

@TimedExecution("fsm.validate_flow")
@Override
protected Optional<Message> performWithResponse(State from, State to, Event event, FlowRerouteContext context, FlowRerouteFsm stateMachine) {
    String flowId = stateMachine.getFlowId();
    Set<IslEndpoint> affectedIsl = new HashSet<>(Optional.ofNullable(context.getAffectedIsl()).orElse(emptySet()));
    dashboardLogger.onFlowPathReroute(flowId, affectedIsl, context.isForceReroute());
    String rerouteReason = context.getRerouteReason();
    stateMachine.saveNewEventToHistory("Started flow validation", FlowEventData.Event.REROUTE, rerouteReason == null ? FlowEventData.Initiator.NB : FlowEventData.Initiator.AUTO, rerouteReason == null ? null : "Reason: " + rerouteReason);
    stateMachine.setRerouteReason(rerouteReason);
    Flow flow = transactionManager.doInTransaction(() -> {
        Flow foundFlow = getFlow(flowId);
        if (foundFlow.getStatus() == FlowStatus.IN_PROGRESS) {
            String message = format("Flow %s is in progress now", flowId);
            stateMachine.setRerouteError(new RerouteError(message));
            throw new FlowProcessingException(ErrorType.REQUEST_INVALID, message);
        }
        if (!foundFlow.getSrcSwitch().isActive()) {
            String message = format("Flow's %s src switch is not active", flowId);
            stateMachine.setRerouteError(new RerouteError(message));
            throw new FlowProcessingException(ErrorType.UNPROCESSABLE_REQUEST, message);
        }
        if (!foundFlow.getDestSwitch().isActive()) {
            String message = format("Flow's %s dest switch is not active", flowId);
            stateMachine.setRerouteError(new RerouteError(message));
            throw new FlowProcessingException(ErrorType.UNPROCESSABLE_REQUEST, message);
        }
        stateMachine.setOriginalFlowStatus(foundFlow.getStatus());
        stateMachine.setOriginalFlowStatusInfo(foundFlow.getStatusInfo());
        stateMachine.setOriginalEncapsulationType(foundFlow.getEncapsulationType());
        stateMachine.setOriginalPathComputationStrategy(foundFlow.getPathComputationStrategy());
        stateMachine.setRecreateIfSamePath(!foundFlow.isActive() || context.isForceReroute());
        stateMachine.setOriginalFlow(RequestedFlowMapper.INSTANCE.toRequestedFlow(foundFlow));
        stateMachine.setPeriodicPingsEnabled(foundFlow.isPeriodicPings());
        if (foundFlow.getTargetPathComputationStrategy() != null) {
            foundFlow.setPathComputationStrategy(foundFlow.getTargetPathComputationStrategy());
            foundFlow.setTargetPathComputationStrategy(null);
        }
        foundFlow.setStatus(FlowStatus.IN_PROGRESS);
        return foundFlow;
    });
    if (featureTogglesRepository.getOrDefault().getFlowsRerouteUsingDefaultEncapType()) {
        stateMachine.setNewEncapsulationType(kildaConfigurationRepository.getOrDefault().getFlowEncapsulationType());
    }
    boolean reroutePrimary;
    boolean rerouteProtected;
    if (affectedIsl.isEmpty()) {
        // no know affected ISLs
        reroutePrimary = true;
        rerouteProtected = true;
    } else {
        reroutePrimary = checkIsPathAffected(flow.getForwardPath(), affectedIsl) || checkIsPathAffected(flow.getReversePath(), affectedIsl);
        rerouteProtected = checkIsPathAffected(flow.getProtectedForwardPath(), affectedIsl) || checkIsPathAffected(flow.getProtectedReversePath(), affectedIsl);
    }
    // check protected path presence
    rerouteProtected &= flow.isAllocateProtectedPath();
    if (!reroutePrimary && !rerouteProtected) {
        throw new FlowProcessingException(ErrorType.NOT_FOUND, format("No paths of the flow %s are affected by failure on %s", flowId, affectedIsl.stream().map(IslEndpoint::toString).collect(Collectors.joining(","))));
    }
    if (reroutePrimary) {
        log.info("Reroute for the flow {} will affect primary paths: {} / {}", flowId, flow.getForwardPathId(), flow.getReversePathId());
    }
    if (rerouteProtected) {
        log.info("Reroute for the flow {} will affect protected paths: {} / {}", flowId, flow.getProtectedForwardPathId(), flow.getProtectedReversePathId());
    }
    stateMachine.setReroutePrimary(reroutePrimary);
    stateMachine.setRerouteProtected(rerouteProtected);
    stateMachine.setEffectivelyDown(context.isEffectivelyDown());
    if (stateMachine.isRerouteProtected() && flow.isPinned()) {
        throw new FlowProcessingException(ErrorType.REQUEST_INVALID, format("Flow %s is pinned, fail to reroute its protected paths", flowId));
    }
    stateMachine.setAffectedIsls(context.getAffectedIsl());
    stateMachine.setForceReroute(context.isForceReroute());
    stateMachine.setIgnoreBandwidth(context.isIgnoreBandwidth());
    stateMachine.saveActionToHistory("Flow was validated successfully");
    return Optional.empty();
}
Also used : IslEndpoint(org.openkilda.model.IslEndpoint) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) RerouteError(org.openkilda.messaging.info.reroute.error.RerouteError) HashSet(java.util.HashSet) Flow(org.openkilda.model.Flow) TimedExecution(org.openkilda.wfm.share.metrics.TimedExecution)

Example 17 with IslEndpoint

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

the class SwitchOperationsBolt method updateSwitchUnderMaintenanceFlag.

private List<GetSwitchResponse> updateSwitchUnderMaintenanceFlag(UpdateSwitchUnderMaintenanceRequest request, Tuple tuple) {
    SwitchId switchId = request.getSwitchId();
    boolean underMaintenance = request.isUnderMaintenance();
    boolean evacuate = request.isEvacuate();
    Switch sw;
    try {
        sw = switchOperationsService.updateSwitchUnderMaintenanceFlag(switchId, underMaintenance);
    } catch (SwitchNotFoundException e) {
        throw new MessageException(ErrorType.NOT_FOUND, e.getMessage(), "Switch was not found.");
    }
    if (underMaintenance && evacuate) {
        Collection<FlowPath> paths = flowOperationsService.getFlowPathsForSwitch(switchId);
        Set<IslEndpoint> affectedIslEndpoint = new HashSet<>(switchOperationsService.getSwitchIslEndpoints(switchId));
        String reason = format("evacuated due to switch maintenance %s", switchId);
        for (FlowRerouteRequest reroute : flowOperationsService.makeRerouteRequests(paths, affectedIslEndpoint, reason)) {
            CommandContext forkedContext = getCommandContext().fork(reroute.getFlowId());
            getOutput().emit(StreamType.REROUTE.toString(), tuple, new Values(reroute, forkedContext.getCorrelationId()));
        }
    }
    return Collections.singletonList(new GetSwitchResponse(sw));
}
Also used : IslEndpoint(org.openkilda.model.IslEndpoint) GetSwitchResponse(org.openkilda.messaging.nbtopology.response.GetSwitchResponse) CommandContext(org.openkilda.wfm.CommandContext) Values(org.apache.storm.tuple.Values) SwitchId(org.openkilda.model.SwitchId) SwitchNotFoundException(org.openkilda.wfm.error.SwitchNotFoundException) Switch(org.openkilda.model.Switch) MessageException(org.openkilda.messaging.error.MessageException) FlowRerouteRequest(org.openkilda.messaging.command.flow.FlowRerouteRequest) FlowPath(org.openkilda.model.FlowPath) HashSet(java.util.HashSet)

Example 18 with IslEndpoint

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

the class LinkOperationsBolt method islBfdPropertiesChanged.

@Override
public void islBfdPropertiesChanged(Endpoint source, Endpoint destination) {
    IslBfdPropertiesChangeNotification notification = new IslBfdPropertiesChangeNotification(new IslEndpoint(source.getDatapath(), source.getPortNumber()), new IslEndpoint(destination.getDatapath(), destination.getPortNumber()));
    getOutput().emit(StreamType.DISCO.toString(), getCurrentTuple(), new Values(notification, getCorrelationId()));
}
Also used : IslBfdPropertiesChangeNotification(org.openkilda.messaging.info.event.IslBfdPropertiesChangeNotification) IslEndpoint(org.openkilda.model.IslEndpoint) Values(org.apache.storm.tuple.Values)

Example 19 with IslEndpoint

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

the class FlowOperationsBolt method processRerouteFlowsForLinkRequest.

@TimedExecution("reroute_flows_for_link")
private List<FlowsResponse> processRerouteFlowsForLinkRequest(RerouteFlowsForIslRequest message) {
    SwitchId srcSwitch = message.getSource().getDatapath();
    Integer srcPort = message.getSource().getPortNumber();
    SwitchId dstSwitch = message.getDestination().getDatapath();
    Integer dstPort = message.getDestination().getPortNumber();
    Collection<FlowPath> paths;
    try {
        paths = flowOperationsService.getFlowPathsForLink(srcSwitch, srcPort, dstSwitch, dstPort);
    } catch (IslNotFoundException e) {
        throw new MessageException(ErrorType.NOT_FOUND, e.getMessage(), "ISL was not found.");
    }
    Set<IslEndpoint> affectedIslEndpoints = new HashSet<>();
    affectedIslEndpoints.add(new IslEndpoint(srcSwitch, srcPort));
    affectedIslEndpoints.add(new IslEndpoint(dstSwitch, dstPort));
    sendRerouteRequest(paths, affectedIslEndpoints, format("initiated via Northbound, reroute all flows that go over the link %s_%d - %s_%d", srcSwitch, srcPort, dstSwitch, dstPort));
    List<String> flowIds = paths.stream().map(FlowPath::getFlow).map(Flow::getFlowId).distinct().collect(Collectors.toList());
    return Collections.singletonList(new FlowsResponse(flowIds));
}
Also used : IslEndpoint(org.openkilda.model.IslEndpoint) FlowsResponse(org.openkilda.messaging.info.flow.FlowsResponse) SwitchId(org.openkilda.model.SwitchId) Flow(org.openkilda.model.Flow) MessageException(org.openkilda.messaging.error.MessageException) IslNotFoundException(org.openkilda.wfm.error.IslNotFoundException) FlowPath(org.openkilda.model.FlowPath) HashSet(java.util.HashSet) TimedExecution(org.openkilda.wfm.share.metrics.TimedExecution)

Example 20 with IslEndpoint

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

the class RerouteServiceTest method handlePathNoFoundExceptionForSubYFlow.

@Test
public void handlePathNoFoundExceptionForSubYFlow() {
    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(subFlow.getForwardPath(), subFlow.getReversePath()));
    FlowRepository flowRepository = mock(FlowRepository.class);
    YFlowRepository yFlowRepository = mock(YFlowRepository.class);
    RepositoryFactory repositoryFactory = mock(RepositoryFactory.class);
    when(repositoryFactory.createPathSegmentRepository()).thenReturn(mock(PathSegmentRepository.class));
    when(repositoryFactory.createFlowPathRepository()).thenReturn(pathRepository);
    when(repositoryFactory.createFlowRepository()).thenReturn(flowRepository);
    when(repositoryFactory.createYFlowRepository()).thenReturn(yFlowRepository);
    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(subFlow), eq(FlowStatus.DOWN), any());
    FlowThrottlingData expected = FlowThrottlingData.builder().correlationId(CORRELATION_ID).priority(regularYFlow.getPriority()).timeCreate(regularYFlow.getTimeCreate()).affectedIsl(Collections.singleton(new IslEndpoint(islSide.getSwitchId(), islSide.getPortNo()))).force(false).effectivelyDown(true).reason(request.getReason()).yFlow(true).build();
    verify(carrier).emitRerouteCommand(eq(regularYFlow.getYFlowId()), 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) YFlowRepository(org.openkilda.persistence.repositories.YFlowRepository) 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)

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