Search in sources :

Example 6 with FlowProcessingException

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

the class UpdateYFlowRulesAction method perform.

@Override
protected void perform(State from, State to, Event event, FlowPathSwapContext context, FlowPathSwapFsm stateMachine) {
    String flowId = stateMachine.getFlowId();
    Flow flow = getFlow(flowId);
    String yFlowId = flow.getYFlowId();
    if (yFlowId == null) {
        stateMachine.saveActionToHistory("No need to update y-flow rules - it's not a sub-flow");
        stateMachine.fire(Event.SKIP_YFLOW_RULES_UPDATE);
        return;
    }
    YFlow yFlow = yFlowRepository.findById(yFlowId).orElseThrow(() -> new FlowProcessingException(ErrorType.INTERNAL_ERROR, format("Y-flow %s not found in persistent storage", yFlowId)));
    stateMachine.clearPendingAndRetriedAndFailedCommands();
    SwitchId sharedEndpoint = yFlow.getSharedEndpoint().getSwitchId();
    InstallSpeakerCommandsRequest installRequest = buildYFlowInstallRequest(sharedEndpoint, stateMachine.getNewPrimaryForwardPath(), stateMachine.getCommandContext());
    stateMachine.addInstallSpeakerCommand(installRequest.getCommandId(), installRequest);
    DeleteSpeakerCommandsRequest deleteRequest = buildYFlowDeleteRequest(sharedEndpoint, stateMachine.getOldPrimaryForwardPath(), stateMachine.getCommandContext());
    stateMachine.addDeleteSpeakerCommand(deleteRequest.getCommandId(), deleteRequest);
    // emitting
    Stream.of(installRequest, deleteRequest).forEach(command -> {
        stateMachine.getCarrier().sendSpeakerRequest(command);
        stateMachine.addPendingCommand(command.getCommandId(), command.getSwitchId());
    });
    stateMachine.saveActionToHistory("Commands for updating y-flow rules have been sent");
}
Also used : YFlow(org.openkilda.model.YFlow) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) InstallSpeakerCommandsRequest(org.openkilda.floodlight.api.request.rulemanager.InstallSpeakerCommandsRequest) SwitchId(org.openkilda.model.SwitchId) Flow(org.openkilda.model.Flow) YFlow(org.openkilda.model.YFlow) DeleteSpeakerCommandsRequest(org.openkilda.floodlight.api.request.rulemanager.DeleteSpeakerCommandsRequest)

Example 7 with FlowProcessingException

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

the class ValidateRequestAction method performWithResponse.

@Override
protected Optional<Message> performWithResponse(State from, State to, Event event, FlowMirrorPointDeleteContext context, FlowMirrorPointDeleteFsm stateMachine) {
    String flowId = stateMachine.getFlowId();
    PathId mirrorPathId = new PathId(context.getFlowMirrorPointId());
    stateMachine.setMirrorPathId(mirrorPathId);
    dashboardLogger.onFlowMirrorPointDelete(flowId, context.getFlowMirrorPointId());
    FlowMirrorPointResponse response = transactionManager.doInTransaction(() -> {
        Flow foundFlow = getFlow(flowId);
        if (foundFlow.getStatus() == FlowStatus.IN_PROGRESS) {
            throw new FlowProcessingException(ErrorType.REQUEST_INVALID, format("Flow %s is in progress now", flowId));
        }
        stateMachine.setFlowStatus(foundFlow.getStatus());
        flowRepository.updateStatus(flowId, FlowStatus.IN_PROGRESS);
        FlowMirrorPath flowMirrorPath = flowMirrorPathRepository.findById(mirrorPathId).orElseThrow(() -> new FlowProcessingException(ErrorType.NOT_FOUND, format("Flow mirror point %s not found", mirrorPathId)));
        if (flowMirrorPath.getStatus() == FlowPathStatus.IN_PROGRESS) {
            throw new FlowProcessingException(ErrorType.REQUEST_INVALID, format("Flow mirror point %s is in progress now", mirrorPathId));
        }
        stateMachine.setOriginalFlowMirrorPathStatus(flowMirrorPath.getStatus());
        flowMirrorPathRepository.updateStatus(mirrorPathId, FlowPathStatus.IN_PROGRESS);
        String direction = flowMirrorPath.getFlowMirrorPoints().getFlowPath().isForward() ? "forward" : "reverse";
        return FlowMirrorPointResponse.builder().flowId(foundFlow.getFlowId()).mirrorPointId(flowMirrorPath.getPathId().getId()).mirrorPointDirection(direction).mirrorPointSwitchId(flowMirrorPath.getMirrorSwitchId()).sinkEndpoint(FlowEndpoint.builder().switchId(flowMirrorPath.getEgressSwitchId()).portNumber(flowMirrorPath.getEgressPort()).innerVlanId(flowMirrorPath.getEgressInnerVlan()).outerVlanId(flowMirrorPath.getEgressOuterVlan()).build()).build();
    });
    stateMachine.saveNewEventToHistory("Flow was validated successfully", FlowEventData.Event.FLOW_MIRROR_POINT_DELETE);
    CommandContext commandContext = stateMachine.getCommandContext();
    return Optional.of(new InfoMessage(response, commandContext.getCreateTime(), commandContext.getCorrelationId()));
}
Also used : PathId(org.openkilda.model.PathId) FlowMirrorPointResponse(org.openkilda.messaging.info.flow.FlowMirrorPointResponse) CommandContext(org.openkilda.wfm.CommandContext) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) InfoMessage(org.openkilda.messaging.info.InfoMessage) FlowMirrorPath(org.openkilda.model.FlowMirrorPath) Flow(org.openkilda.model.Flow)

Example 8 with FlowProcessingException

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

the class FlowValidateAction method performWithResponse.

@Override
protected Optional<Message> performWithResponse(State from, State to, Event event, FlowPathSwapContext context, FlowPathSwapFsm stateMachine) throws FlowProcessingException {
    transactionManager.doInTransaction(() -> {
        String flowId = stateMachine.getFlowId();
        Flow flow = flowRepository.findById(flowId).orElseThrow(() -> new FlowProcessingException(ErrorType.NOT_FOUND, format("Could not swap paths: Flow %s not found", flowId)));
        dashboardLogger.onFlowPathsSwap(flow);
        stateMachine.setPeriodicPingsEnabled(flow.isPeriodicPings());
        if (!flow.isAllocateProtectedPath()) {
            throw new FlowProcessingException(ErrorType.REQUEST_INVALID, format("Could not swap paths: Flow %s doesn't have protected path", flowId));
        }
        if (FlowPathStatus.ACTIVE != flow.getProtectedForwardPath().getStatus() || FlowPathStatus.ACTIVE != flow.getProtectedReversePath().getStatus()) {
            throw new FlowProcessingException(ErrorType.REQUEST_INVALID, format("Could not swap paths: Protected flow path %s is not in ACTIVE state", flowId));
        }
        stateMachine.setOldPrimaryForwardPath(flow.getForwardPathId());
        stateMachine.setOldPrimaryForwardPathStatus(flow.getForwardPath().getStatus());
        stateMachine.setOldPrimaryReversePath(flow.getReversePathId());
        stateMachine.setOldPrimaryReversePathStatus(flow.getReversePath().getStatus());
        stateMachine.setOldProtectedForwardPath(flow.getProtectedForwardPathId());
        stateMachine.setOldProtectedForwardPathStatus(flow.getProtectedForwardPath().getStatus());
        stateMachine.setOldPrimaryReversePath(flow.getProtectedReversePathId());
        stateMachine.setOldProtectedReversePathStatus(flow.getProtectedReversePath().getStatus());
        flow.setStatus(FlowStatus.IN_PROGRESS);
        flow.getForwardPath().setStatus(FlowPathStatus.IN_PROGRESS);
        flow.getReversePath().setStatus(FlowPathStatus.IN_PROGRESS);
        flow.getProtectedForwardPath().setStatus(FlowPathStatus.IN_PROGRESS);
        flow.getProtectedReversePath().setStatus(FlowPathStatus.IN_PROGRESS);
    });
    stateMachine.saveNewEventToHistory("Flow was validated successfully", FlowEventData.Event.PATH_SWAP);
    return Optional.empty();
}
Also used : FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) Flow(org.openkilda.model.Flow)

Example 9 with FlowProcessingException

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

the class ResourcesDeallocationAction method perform.

@Override
protected void perform(State from, State to, Event event, FlowCreateContext context, FlowCreateFsm stateMachine) {
    try {
        transactionManager.doInTransaction(() -> {
            Flow flow = getFlow(stateMachine.getFlowId());
            flow.resetPaths();
        });
    } catch (FlowProcessingException e) {
        stateMachine.saveActionToHistory("Skip resources deallocation", format("Skip resources deallocation. Flow %s has already been deleted: %s", stateMachine.getFlowId(), e.getMessage()));
        return;
    }
    Collection<FlowResources> flowResources = stateMachine.getFlowResources();
    for (FlowResources resources : flowResources) {
        List<PathSegment> removedSegments = new ArrayList<>();
        Stream.of(resources.getForward().getPathId(), resources.getReverse().getPathId()).forEach(pathId -> flowPathRepository.remove(pathId).ifPresent(path -> removedSegments.addAll(path.getSegments())));
        updateIslsForSegments(removedSegments);
        transactionManager.doInTransaction(() -> resourcesManager.deallocatePathResources(resources));
    }
    if (!stateMachine.isPathsBeenAllocated()) {
        flowRepository.remove(stateMachine.getFlowId());
    }
    stateMachine.saveActionToHistory("The resources have been deallocated");
}
Also used : PathSegment(org.openkilda.model.PathSegment) FlowProcessingWithHistorySupportAction(org.openkilda.wfm.topology.flowhs.fsm.common.actions.FlowProcessingWithHistorySupportAction) Event(org.openkilda.wfm.topology.flowhs.fsm.create.FlowCreateFsm.Event) Collection(java.util.Collection) FlowCreateFsm(org.openkilda.wfm.topology.flowhs.fsm.create.FlowCreateFsm) FlowResources(org.openkilda.wfm.share.flow.resources.FlowResources) String.format(java.lang.String.format) ArrayList(java.util.ArrayList) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) Slf4j(lombok.extern.slf4j.Slf4j) List(java.util.List) Stream(java.util.stream.Stream) Flow(org.openkilda.model.Flow) State(org.openkilda.wfm.topology.flowhs.fsm.create.FlowCreateFsm.State) IslRepository(org.openkilda.persistence.repositories.IslRepository) FlowCreateContext(org.openkilda.wfm.topology.flowhs.fsm.create.FlowCreateContext) FlowResourcesManager(org.openkilda.wfm.share.flow.resources.FlowResourcesManager) PersistenceManager(org.openkilda.persistence.PersistenceManager) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) FlowResources(org.openkilda.wfm.share.flow.resources.FlowResources) ArrayList(java.util.ArrayList) PathSegment(org.openkilda.model.PathSegment) Flow(org.openkilda.model.Flow)

Example 10 with FlowProcessingException

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

the class ResourcesAllocationAction method performWithResponse.

@Override
protected Optional<Message> performWithResponse(State from, State to, Event event, FlowCreateContext context, FlowCreateFsm stateMachine) throws FlowProcessingException {
    try {
        String flowId = stateMachine.getFlowId();
        log.debug("Allocation resources has been started");
        stateMachine.setPathsBeenAllocated(false);
        if (context != null && context.getTargetFlow() != null) {
            createFlow(context.getTargetFlow());
        } else if (!flowRepository.exists(flowId)) {
            log.warn("Flow {} has been deleted while creation was in progress", flowId);
            return Optional.empty();
        }
        createPaths(stateMachine);
        log.debug("Resources allocated successfully for the flow {}", flowId);
        stateMachine.setPathsBeenAllocated(true);
        Flow resultFlow = getFlow(flowId);
        createSpeakerRequestFactories(stateMachine, resultFlow);
        saveHistory(stateMachine, resultFlow);
        if (resultFlow.isOneSwitchFlow()) {
            stateMachine.fire(Event.SKIP_NON_INGRESS_RULES_INSTALL);
        } else {
            stateMachine.fireNext(context);
        }
        // Notify about successful allocation.
        stateMachine.notifyEventListeners(listener -> listener.onResourcesAllocated(flowId));
        return Optional.of(buildResponseMessage(resultFlow, stateMachine.getCommandContext()));
    } catch (UnroutableFlowException | RecoverableException e) {
        throw new FlowProcessingException(ErrorType.NOT_FOUND, "Not enough bandwidth or no path found. " + e.getMessage(), e);
    } catch (ResourceAllocationException e) {
        throw new FlowProcessingException(ErrorType.INTERNAL_ERROR, "Failed to allocate flow resources. " + e.getMessage(), e);
    } catch (FlowNotFoundException e) {
        throw new FlowProcessingException(ErrorType.NOT_FOUND, "Couldn't find the diverse flow. " + e.getMessage(), e);
    } catch (FlowAlreadyExistException e) {
        if (!stateMachine.retryIfAllowed()) {
            throw new FlowProcessingException(ErrorType.INTERNAL_ERROR, e.getMessage(), e);
        } else {
            // we have retried the operation, no need to respond.
            log.debug(e.getMessage(), e);
            return Optional.empty();
        }
    }
}
Also used : FlowNotFoundException(org.openkilda.wfm.error.FlowNotFoundException) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) FlowAlreadyExistException(org.openkilda.wfm.error.FlowAlreadyExistException) UnroutableFlowException(org.openkilda.pce.exception.UnroutableFlowException) ResourceAllocationException(org.openkilda.wfm.share.flow.resources.ResourceAllocationException) RecoverableException(org.openkilda.pce.exception.RecoverableException) Flow(org.openkilda.model.Flow) YSubFlow(org.openkilda.model.YSubFlow) RequestedFlow(org.openkilda.wfm.topology.flowhs.model.RequestedFlow) YFlow(org.openkilda.model.YFlow)

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