Search in sources :

Example 11 with FlowProcessingException

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

the class UpdateFlowAction method updateFlow.

private RequestedFlow updateFlow(Flow flow, RequestedFlow targetFlow) {
    if (targetFlow.getDiverseFlowId() != null) {
        if (targetFlow.getDiverseFlowId().isEmpty()) {
            flow.setDiverseGroupId(null);
        } else {
            flow.setDiverseGroupId(getOrCreateDiverseFlowGroupId(targetFlow.getDiverseFlowId()));
        }
    } else if (targetFlow.isAllocateProtectedPath()) {
        if (flow.getDiverseGroupId() == null) {
            flow.setDiverseGroupId(getOrCreateDiverseFlowGroupId(flow.getFlowId()));
        }
    }
    if (targetFlow.getAffinityFlowId() != null) {
        if (targetFlow.getAffinityFlowId().isEmpty()) {
            flow.setAffinityGroupId(null);
        } else {
            flow.setAffinityGroupId(getOrCreateAffinityFlowGroupId(targetFlow.getAffinityFlowId()));
        }
    }
    Switch srcSwitch = switchRepository.findById(targetFlow.getSrcSwitch()).orElseThrow(() -> new FlowProcessingException(ErrorType.NOT_FOUND, format("Switch %s not found", targetFlow.getSrcSwitch())));
    flow.setSrcSwitch(srcSwitch);
    flow.setSrcPort(targetFlow.getSrcPort());
    flow.setSrcVlan(targetFlow.getSrcVlan());
    flow.setSrcInnerVlan(targetFlow.getSrcInnerVlan());
    DetectConnectedDevices.DetectConnectedDevicesBuilder detectConnectedDevices = flow.getDetectConnectedDevices().toBuilder();
    detectConnectedDevices.srcLldp(targetFlow.getDetectConnectedDevices().isSrcLldp());
    detectConnectedDevices.srcArp(targetFlow.getDetectConnectedDevices().isSrcArp());
    Switch destSwitch = switchRepository.findById(targetFlow.getDestSwitch()).orElseThrow(() -> new FlowProcessingException(ErrorType.NOT_FOUND, format("Switch %s not found", targetFlow.getDestSwitch())));
    flow.setDestSwitch(destSwitch);
    flow.setDestPort(targetFlow.getDestPort());
    flow.setDestVlan(targetFlow.getDestVlan());
    flow.setDestInnerVlan(targetFlow.getDestInnerVlan());
    detectConnectedDevices.dstLldp(targetFlow.getDetectConnectedDevices().isDstLldp());
    detectConnectedDevices.dstArp(targetFlow.getDetectConnectedDevices().isDstArp());
    flow.setDetectConnectedDevices(detectConnectedDevices.build());
    if (targetFlow.getPriority() != null) {
        flow.setPriority(targetFlow.getPriority());
    }
    flow.setPinned(targetFlow.isPinned());
    flow.setAllocateProtectedPath(targetFlow.isAllocateProtectedPath());
    if (targetFlow.getDescription() != null) {
        flow.setDescription(targetFlow.getDescription());
    }
    flow.setBandwidth(targetFlow.getBandwidth());
    flow.setIgnoreBandwidth(targetFlow.isIgnoreBandwidth());
    flow.setStrictBandwidth(targetFlow.isStrictBandwidth());
    if (targetFlow.getMaxLatency() != null) {
        flow.setMaxLatency(targetFlow.getMaxLatency());
    }
    if (targetFlow.getMaxLatencyTier2() != null) {
        flow.setMaxLatencyTier2(targetFlow.getMaxLatencyTier2());
    }
    flow.setPeriodicPings(targetFlow.isPeriodicPings());
    if (targetFlow.getFlowEncapsulationType() != null) {
        flow.setEncapsulationType(targetFlow.getFlowEncapsulationType());
    } else {
        targetFlow.setFlowEncapsulationType(flow.getEncapsulationType());
    }
    if (targetFlow.getPathComputationStrategy() != null) {
        flow.setPathComputationStrategy(targetFlow.getPathComputationStrategy());
        flow.setTargetPathComputationStrategy(null);
    } else {
        if (flow.getTargetPathComputationStrategy() != null) {
            targetFlow.setPathComputationStrategy(flow.getTargetPathComputationStrategy());
            flow.setPathComputationStrategy(flow.getTargetPathComputationStrategy());
            flow.setTargetPathComputationStrategy(null);
        } else {
            targetFlow.setPathComputationStrategy(flow.getPathComputationStrategy());
        }
    }
    flow.setLoopSwitchId(targetFlow.getLoopSwitchId());
    return targetFlow;
}
Also used : Switch(org.openkilda.model.Switch) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) DetectConnectedDevices(org.openkilda.model.DetectConnectedDevices)

Example 12 with FlowProcessingException

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

the class ValidateFlowAction method performWithResponse.

@Override
protected Optional<Message> performWithResponse(State from, State to, Event event, FlowUpdateContext context, FlowUpdateFsm stateMachine) {
    String flowId = stateMachine.getFlowId();
    RequestedFlow targetFlow = context.getTargetFlow();
    String diverseFlowId = targetFlow.getDiverseFlowId();
    dashboardLogger.onFlowUpdate(flowId, targetFlow.getSrcSwitch(), targetFlow.getSrcPort(), targetFlow.getSrcVlan(), targetFlow.getDestSwitch(), targetFlow.getDestPort(), targetFlow.getDestVlan(), diverseFlowId, targetFlow.getBandwidth());
    boolean isOperationAllowed = featureTogglesRepository.getOrDefault().getUpdateFlowEnabled();
    if (!isOperationAllowed) {
        throw new FlowProcessingException(ErrorType.NOT_PERMITTED, "Flow update feature is disabled");
    }
    stateMachine.setTargetFlow(targetFlow);
    stateMachine.setBulkUpdateFlowIds(context.getBulkUpdateFlowIds());
    stateMachine.setDoNotRevert(context.isDoNotRevert());
    Flow flow = getFlow(flowId);
    try {
        flowValidator.validate(targetFlow, stateMachine.getBulkUpdateFlowIds());
    } catch (InvalidFlowException e) {
        throw new FlowProcessingException(e.getType(), e.getMessage(), e);
    } catch (UnavailableFlowEndpointException e) {
        throw new FlowProcessingException(ErrorType.DATA_INVALID, e.getMessage(), e);
    }
    if ((!targetFlow.getSrcSwitch().equals(flow.getSrcSwitchId()) || !targetFlow.getDestSwitch().equals(flow.getDestSwitchId())) && (!flow.getForwardPath().getFlowMirrorPointsSet().isEmpty() || !flow.getReversePath().getFlowMirrorPointsSet().isEmpty())) {
        throw new FlowProcessingException(ErrorType.REQUEST_INVALID, "The current implementation of flow mirror points does not allow allocating paths. " + "Therefore, remove the flow mirror points before changing the endpoint switch.");
    }
    if (diverseFlowId != null && targetFlow.getSrcSwitch().equals(targetFlow.getDestSwitch())) {
        throw new FlowProcessingException(ErrorType.DATA_INVALID, "Couldn't add one-switch flow into diverse group");
    }
    transactionManager.doInTransaction(() -> {
        if (diverseFlowId != null && !diverseFlowId.isEmpty()) {
            Flow diverseFlow = getFlow(diverseFlowId);
            if (diverseFlow.isOneSwitchFlow()) {
                throw new FlowProcessingException(ErrorType.PARAMETERS_INVALID, "Couldn't create diverse group with one-switch flow");
            }
        }
        Flow foundFlow = getFlow(flowId);
        if (foundFlow.getStatus() == FlowStatus.IN_PROGRESS && stateMachine.getBulkUpdateFlowIds().isEmpty()) {
            throw new FlowProcessingException(ErrorType.REQUEST_INVALID, format("Flow %s is in progress now", flowId));
        }
        // Keep it, just in case we have to revert it.
        stateMachine.setOriginalFlowStatus(foundFlow.getStatus());
        stateMachine.setOriginalFlowStatusInfo(foundFlow.getStatusInfo());
        foundFlow.setStatus(FlowStatus.IN_PROGRESS);
        foundFlow.setStatusInfo("");
        return foundFlow;
    });
    stateMachine.saveNewEventToHistory("Flow was validated successfully", FlowEventData.Event.UPDATE);
    return Optional.empty();
}
Also used : UnavailableFlowEndpointException(org.openkilda.wfm.topology.flowhs.validation.UnavailableFlowEndpointException) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) RequestedFlow(org.openkilda.wfm.topology.flowhs.model.RequestedFlow) InvalidFlowException(org.openkilda.wfm.topology.flowhs.validation.InvalidFlowException) Flow(org.openkilda.model.Flow) RequestedFlow(org.openkilda.wfm.topology.flowhs.model.RequestedFlow)

Example 13 with FlowProcessingException

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

the class RevertYFlowRulesAction 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 revert y-flow rules - it's not a sub-flow");
        stateMachine.fire(Event.SKIP_YFLOW_RULES_REVERT);
        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.getOldPrimaryForwardPath(), stateMachine.getCommandContext());
    stateMachine.addInstallSpeakerCommand(installRequest.getCommandId(), installRequest);
    DeleteSpeakerCommandsRequest deleteRequest = buildYFlowDeleteRequest(sharedEndpoint, stateMachine.getNewPrimaryForwardPath(), 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 reverting 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 14 with FlowProcessingException

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

the class ValidateFlowsAction method perform.

@Override
protected void perform(State from, State to, Event event, FlowSwapEndpointsContext context, FlowSwapEndpointsFsm stateMachine) {
    RequestedFlow firstTargetFlow = stateMachine.getFirstTargetFlow();
    RequestedFlow secondTargetFlow = stateMachine.getSecondTargetFlow();
    if (!featureTogglesRepository.getOrDefault().getUpdateFlowEnabled()) {
        throw new FlowProcessingException(ErrorType.NOT_PERMITTED, "Flow update feature is disabled");
    }
    try {
        flowValidator.validateForSwapEndpoints(firstTargetFlow, secondTargetFlow);
    } catch (InvalidFlowException e) {
        stateMachine.fireValidationError(new ErrorData(e.getType(), FlowSwapEndpointsFsm.GENERIC_ERROR_MESSAGE, e.getMessage()));
        return;
    } catch (UnavailableFlowEndpointException e) {
        stateMachine.fireValidationError(new ErrorData(ErrorType.DATA_INVALID, FlowSwapEndpointsFsm.GENERIC_ERROR_MESSAGE, e.getMessage()));
        return;
    }
    try {
        transactionManager.doInTransaction(() -> {
            Flow foundFirstFlow = checkAndGetFlow(stateMachine.getFirstFlowId());
            Flow foundSecondFlow = checkAndGetFlow(stateMachine.getSecondFlowId());
            stateMachine.setFirstOriginalFlow(foundFirstFlow);
            stateMachine.setSecondOriginalFlow(foundSecondFlow);
            foundFirstFlow.setStatus(FlowStatus.IN_PROGRESS);
            foundSecondFlow.setStatus(FlowStatus.IN_PROGRESS);
        });
    } catch (FlowProcessingException e) {
        stateMachine.fireValidationError(new ErrorData(e.getErrorType(), FlowSwapEndpointsFsm.GENERIC_ERROR_MESSAGE, e.getMessage()));
        return;
    }
    stateMachine.saveNewEventToHistory(stateMachine.getFirstFlowId(), format("Current flow and flow %s were validated successfully", stateMachine.getSecondFlowId()), FlowEventData.Event.SWAP_ENDPOINTS);
    stateMachine.saveNewEventToHistory(stateMachine.getSecondFlowId(), format("Current flow and flow %s were validated successfully", stateMachine.getFirstFlowId()), FlowEventData.Event.SWAP_ENDPOINTS);
    stateMachine.fireNext();
}
Also used : UnavailableFlowEndpointException(org.openkilda.wfm.topology.flowhs.validation.UnavailableFlowEndpointException) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) RequestedFlow(org.openkilda.wfm.topology.flowhs.model.RequestedFlow) InvalidFlowException(org.openkilda.wfm.topology.flowhs.validation.InvalidFlowException) ErrorData(org.openkilda.messaging.error.ErrorData) Flow(org.openkilda.model.Flow) RequestedFlow(org.openkilda.wfm.topology.flowhs.model.RequestedFlow)

Example 15 with FlowProcessingException

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

the class OnSubFlowAllocatedAction method buildRerouteResponseMessage.

private Message buildRerouteResponseMessage(YFlowRerouteFsm stateMachine) {
    String yFlowId = stateMachine.getYFlowId();
    List<Long> oldFlowPathCookies = stateMachine.getOldYFlowPathCookies();
    List<FlowPath> flowPaths = transactionManager.doInTransaction(() -> {
        YFlow yflow = yFlowRepository.findById(yFlowId).orElseThrow(() -> new FlowProcessingException(ErrorType.NOT_FOUND, format("Y-flow %s not found", yFlowId)));
        SwitchId sharedSwitchId = yflow.getSharedEndpoint().getSwitchId();
        List<FlowPath> paths = new ArrayList<>();
        for (YSubFlow subFlow : yflow.getSubFlows()) {
            Flow flow = subFlow.getFlow();
            FlowPath flowPath = flow.getPaths().stream().filter(path -> sharedSwitchId.equals(path.getSrcSwitchId()) && !path.isProtected() && !oldFlowPathCookies.contains(path.getCookie().getValue())).findFirst().orElse(sharedSwitchId.equals(flow.getForwardPath().getSrcSwitchId()) ? flow.getForwardPath() : flow.getReversePath());
            paths.add(flowPath);
        }
        return paths;
    });
    List<PathSegment> sharedPathSegments = IntersectionComputer.calculatePathIntersectionFromSource(flowPaths);
    PathInfoData sharedPath = FlowPathMapper.INSTANCE.map(sharedPathSegments);
    List<SubFlowPathDto> subFlowPathDtos = flowPaths.stream().map(flowPath -> new SubFlowPathDto(flowPath.getFlowId(), FlowPathMapper.INSTANCE.map(flowPath))).sorted(Comparator.comparing(SubFlowPathDto::getFlowId)).collect(Collectors.toList());
    PathInfoData oldSharedPath = stateMachine.getOldSharedPath();
    List<SubFlowPathDto> oldSubFlowPathDtos = stateMachine.getOldSubFlowPathDtos();
    YFlowRerouteResponse response = new YFlowRerouteResponse(sharedPath, subFlowPathDtos, !(sharedPath.equals(oldSharedPath) && subFlowPathDtos.equals(oldSubFlowPathDtos)));
    CommandContext commandContext = stateMachine.getCommandContext();
    return new InfoMessage(response, commandContext.getCreateTime(), commandContext.getCorrelationId());
}
Also used : YFlow(org.openkilda.model.YFlow) CommandContext(org.openkilda.wfm.CommandContext) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) ArrayList(java.util.ArrayList) SwitchId(org.openkilda.model.SwitchId) PathSegment(org.openkilda.model.PathSegment) YSubFlow(org.openkilda.model.YSubFlow) Flow(org.openkilda.model.Flow) YFlow(org.openkilda.model.YFlow) YSubFlow(org.openkilda.model.YSubFlow) PathInfoData(org.openkilda.messaging.info.event.PathInfoData) YFlowRerouteResponse(org.openkilda.messaging.command.yflow.YFlowRerouteResponse) InfoMessage(org.openkilda.messaging.info.InfoMessage) FlowPath(org.openkilda.model.FlowPath) SubFlowPathDto(org.openkilda.messaging.command.yflow.SubFlowPathDto)

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