Search in sources :

Example 31 with FlowProcessingException

use of org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException 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 32 with FlowProcessingException

use of org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException in project open-kilda by telstra.

the class OnSubFlowAllocatedAction method performWithResponse.

@Override
protected Optional<Message> performWithResponse(State from, State to, Event event, YFlowCreateContext context, YFlowCreateFsm stateMachine) {
    String subFlowId = context.getSubFlowId();
    if (!stateMachine.isCreatingSubFlow(subFlowId)) {
        throw new IllegalStateException("Received an event for non-pending sub-flow " + subFlowId);
    }
    String yFlowId = stateMachine.getYFlowId();
    stateMachine.saveActionToHistory("Creating a sub-flow", format("Allocated resources for sub-flow %s of y-flow %s", subFlowId, yFlowId));
    stateMachine.addAllocatedSubFlow(subFlowId);
    SubFlowDto subFlowDto = stateMachine.getTargetFlow().getSubFlows().stream().filter(f -> f.getFlowId().equals(subFlowId)).findAny().orElseThrow(() -> new FlowProcessingException(ErrorType.INTERNAL_ERROR, format("Can't find definition of created sub-flow %s", subFlowId)));
    SubFlowSharedEndpointEncapsulation sharedEndpoint = subFlowDto.getSharedEndpoint();
    FlowEndpoint endpoint = subFlowDto.getEndpoint();
    log.debug("Start creating sub-flow references from {} to y-flow {}", subFlowId, stateMachine.getYFlowId());
    YFlow result = transactionManager.doInTransaction(() -> {
        YFlow yFlow = yFlowRepository.findById(yFlowId).orElseThrow(() -> new FlowProcessingException(ErrorType.INTERNAL_ERROR, format("Y-flow %s not found", yFlowId)));
        Flow flow = flowRepository.findById(subFlowId).orElseThrow(() -> new FlowProcessingException(ErrorType.INTERNAL_ERROR, format("Flow %s not found", subFlowId)));
        YSubFlow subFlow = YSubFlow.builder().yFlow(yFlow).flow(flow).sharedEndpointVlan(sharedEndpoint.getVlanId()).sharedEndpointInnerVlan(sharedEndpoint.getInnerVlanId()).endpointSwitchId(endpoint.getSwitchId()).endpointPort(endpoint.getPortNumber()).endpointVlan(endpoint.getOuterVlanId()).endpointInnerVlan(endpoint.getInnerVlanId()).build();
        yFlow.addSubFlow(subFlow);
        return yFlow;
    });
    if (subFlowId.equals(stateMachine.getMainAffinityFlowId())) {
        stateMachine.getRequestedFlows().forEach(requestedFlow -> {
            String requestedFlowId = requestedFlow.getFlowId();
            if (!requestedFlowId.equals(subFlowId)) {
                stateMachine.addSubFlow(requestedFlowId);
                stateMachine.addCreatingSubFlow(requestedFlowId);
                stateMachine.notifyEventListeners(listener -> listener.onSubFlowProcessingStart(yFlowId, requestedFlowId));
                CommandContext flowContext = stateMachine.getCommandContext().fork(requestedFlowId);
                requestedFlow.setAffinityFlowId(stateMachine.getMainAffinityFlowId());
                flowCreateService.startFlowCreation(flowContext, requestedFlow, yFlowId);
            }
        });
    }
    if (stateMachine.getAllocatedSubFlows().size() == stateMachine.getSubFlows().size()) {
        return Optional.of(buildResponseMessage(result, stateMachine.getCommandContext()));
    } else {
        return Optional.empty();
    }
}
Also used : YFlow(org.openkilda.model.YFlow) FlowEndpoint(org.openkilda.model.FlowEndpoint) CommandContext(org.openkilda.wfm.CommandContext) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) SubFlowSharedEndpointEncapsulation(org.openkilda.messaging.command.yflow.SubFlowSharedEndpointEncapsulation) SubFlowDto(org.openkilda.messaging.command.yflow.SubFlowDto) YSubFlow(org.openkilda.model.YSubFlow) Flow(org.openkilda.model.Flow) YFlow(org.openkilda.model.YFlow) YSubFlow(org.openkilda.model.YSubFlow)

Example 33 with FlowProcessingException

use of org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException in project open-kilda by telstra.

the class OnSubFlowAllocatedAction method convertToYFlowDto.

private YFlowDto convertToYFlowDto(YFlow yFlow) {
    Flow mainAffinityFlow = yFlow.getSubFlows().stream().map(YSubFlow::getFlow).filter(flow -> flow.getFlowId().equals(flow.getAffinityGroupId())).findFirst().orElseThrow(() -> new FlowProcessingException(ErrorType.INTERNAL_ERROR, "Main affinity flow not found"));
    Collection<Flow> diverseWithFlow = getDiverseWithFlow(mainAffinityFlow);
    Set<String> diverseFlows = diverseWithFlow.stream().filter(flow -> flow.getYFlowId() == null).map(Flow::getFlowId).collect(Collectors.toSet());
    Set<String> diverseYFlows = diverseWithFlow.stream().map(Flow::getYFlowId).filter(Objects::nonNull).collect(Collectors.toSet());
    return YFlowMapper.INSTANCE.toYFlowDto(yFlow, diverseFlows, diverseYFlows);
}
Also used : FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) Flow(org.openkilda.model.Flow) YFlow(org.openkilda.model.YFlow) YSubFlow(org.openkilda.model.YSubFlow)

Example 34 with FlowProcessingException

use of org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException in project open-kilda by telstra.

the class RevertFlowAction method revertFlow.

private void revertFlow(Flow flow, FlowUpdateFsm stateMachine) {
    flow.setDiverseGroupId(stateMachine.getOriginalDiverseFlowGroup());
    flow.setAffinityGroupId(stateMachine.getOriginalAffinityFlowGroup());
    RequestedFlow originalFlow = stateMachine.getOriginalFlow();
    Switch srcSwitch = switchRepository.findById(originalFlow.getSrcSwitch()).orElseThrow(() -> new FlowProcessingException(ErrorType.NOT_FOUND, format("Switch %s not found", originalFlow.getSrcSwitch())));
    flow.setSrcSwitch(srcSwitch);
    flow.setSrcPort(originalFlow.getSrcPort());
    flow.setSrcVlan(originalFlow.getSrcVlan());
    Switch destSwitch = switchRepository.findById(originalFlow.getDestSwitch()).orElseThrow(() -> new FlowProcessingException(ErrorType.NOT_FOUND, format("Switch %s not found", originalFlow.getDestSwitch())));
    flow.setDestSwitch(destSwitch);
    flow.setDestPort(originalFlow.getDestPort());
    flow.setDestVlan(originalFlow.getDestVlan());
    flow.setPriority(originalFlow.getPriority());
    flow.setPinned(originalFlow.isPinned());
    flow.setAllocateProtectedPath(originalFlow.isAllocateProtectedPath());
    flow.setDescription(originalFlow.getDescription());
    flow.setBandwidth(originalFlow.getBandwidth());
    flow.setIgnoreBandwidth(originalFlow.isIgnoreBandwidth());
    flow.setMaxLatency(originalFlow.getMaxLatency());
    flow.setPeriodicPings(originalFlow.isPeriodicPings());
    flow.setEncapsulationType(originalFlow.getFlowEncapsulationType());
    flow.setPathComputationStrategy(originalFlow.getPathComputationStrategy());
    flow.setTargetPathComputationStrategy(stateMachine.getOldTargetPathComputationStrategy());
}
Also used : Switch(org.openkilda.model.Switch) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) RequestedFlow(org.openkilda.wfm.topology.flowhs.model.RequestedFlow)

Example 35 with FlowProcessingException

use of org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException in project open-kilda by telstra.

the class ValidateYFlowAction method performWithResponse.

@Override
protected Optional<Message> performWithResponse(State from, State to, Event event, YFlowDeleteContext context, YFlowDeleteFsm stateMachine) {
    String yFlowId = stateMachine.getYFlowId();
    dashboardLogger.onYFlowDelete(yFlowId);
    boolean isOperationAllowed = featureTogglesRepository.getOrDefault().getModifyYFlowEnabled();
    if (!isOperationAllowed) {
        throw new FlowProcessingException(ErrorType.NOT_PERMITTED, "Y-flow delete feature is disabled");
    }
    YFlow result = transactionManager.doInTransaction(() -> {
        YFlow yFlow = yFlowRepository.findById(yFlowId).orElseThrow(() -> new FlowProcessingException(ErrorType.NOT_FOUND, format("Y-flow %s not found", yFlowId)));
        if (yFlow.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(yFlow.getStatus());
        yFlow.setStatus(FlowStatus.IN_PROGRESS);
        return yFlow;
    });
    stateMachine.saveNewEventToHistory("Y-flow was validated successfully", FlowEventData.Event.DELETE);
    return Optional.of(buildResponseMessage(result, stateMachine.getCommandContext()));
}
Also used : YFlow(org.openkilda.model.YFlow) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException)

Aggregations

FlowProcessingException (org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException)40 Flow (org.openkilda.model.Flow)24 YFlow (org.openkilda.model.YFlow)20 YSubFlow (org.openkilda.model.YSubFlow)11 SwitchId (org.openkilda.model.SwitchId)7 CommandContext (org.openkilda.wfm.CommandContext)7 FlowEndpoint (org.openkilda.model.FlowEndpoint)6 PathId (org.openkilda.model.PathId)6 RequestedFlow (org.openkilda.wfm.topology.flowhs.model.RequestedFlow)6 InvalidFlowException (org.openkilda.wfm.topology.flowhs.validation.InvalidFlowException)6 UnavailableFlowEndpointException (org.openkilda.wfm.topology.flowhs.validation.UnavailableFlowEndpointException)6 ArrayList (java.util.ArrayList)5 YFlowRequest (org.openkilda.messaging.command.yflow.YFlowRequest)5 Switch (org.openkilda.model.Switch)5 SubFlowDto (org.openkilda.messaging.command.yflow.SubFlowDto)4 SubFlowSharedEndpointEncapsulation (org.openkilda.messaging.command.yflow.SubFlowSharedEndpointEncapsulation)4 FlowMirrorPath (org.openkilda.model.FlowMirrorPath)4 FlowMirrorPoints (org.openkilda.model.FlowMirrorPoints)4 FlowPath (org.openkilda.model.FlowPath)4 InfoMessage (org.openkilda.messaging.info.InfoMessage)3