Search in sources :

Example 1 with InvalidFlowException

use of org.openkilda.wfm.topology.flowhs.validation.InvalidFlowException in project open-kilda by telstra.

the class ValidateRequestAction method performWithResponse.

@Override
protected Optional<Message> performWithResponse(State from, State to, Event event, FlowMirrorPointCreateContext context, FlowMirrorPointCreateFsm stateMachine) {
    String flowId = stateMachine.getFlowId();
    RequestedFlowMirrorPoint mirrorPoint = context.getMirrorPoint();
    PathId mirrorPathId = new PathId(mirrorPoint.getMirrorPointId());
    stateMachine.setMirrorPathId(mirrorPathId);
    stateMachine.setMirrorSwitchId(mirrorPoint.getMirrorPointSwitchId());
    dashboardLogger.onFlowMirrorPointCreate(flowId, mirrorPoint.getMirrorPointSwitchId(), mirrorPoint.getMirrorPointDirection().toString(), mirrorPoint.getSinkEndpoint().getSwitchId(), mirrorPoint.getSinkEndpoint().getPortNumber(), mirrorPoint.getSinkEndpoint().getOuterVlanId());
    stateMachine.setRequestedFlowMirrorPoint(mirrorPoint);
    Flow flow = 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);
        return foundFlow;
    });
    if (!mirrorPoint.getMirrorPointSwitchId().equals(mirrorPoint.getSinkEndpoint().getSwitchId())) {
        throw new FlowProcessingException(ErrorType.REQUEST_INVALID, format("Invalid sink endpoint switch id: %s. In the current implementation, " + "the sink switch id cannot differ from the mirror point switch id.", mirrorPoint.getSinkEndpoint().getSwitchId()));
    }
    if (!mirrorPoint.getMirrorPointSwitchId().equals(flow.getSrcSwitchId()) && !mirrorPoint.getMirrorPointSwitchId().equals(flow.getDestSwitchId())) {
        throw new FlowProcessingException(ErrorType.REQUEST_INVALID, format("Invalid mirror point switch id: %s", mirrorPoint.getMirrorPointSwitchId()));
    }
    if (flowMirrorPathRepository.exists(mirrorPathId)) {
        throw new FlowProcessingException(ErrorType.ALREADY_EXISTS, format("Flow mirror point %s already exists", mirrorPathId));
    }
    Optional<PhysicalPort> physicalPort = physicalPortRepository.findBySwitchIdAndPortNumber(mirrorPoint.getSinkEndpoint().getSwitchId(), mirrorPoint.getSinkEndpoint().getPortNumber());
    if (physicalPort.isPresent()) {
        throw new FlowProcessingException(ErrorType.REQUEST_INVALID, format("Invalid sink port %d on switch %s. This port is part of LAG %d. Please delete LAG port " + "or choose another sink port.", mirrorPoint.getSinkEndpoint().getPortNumber(), mirrorPoint.getSinkEndpoint().getSwitchId(), physicalPort.get().getLagLogicalPort().getLogicalPortNumber()));
    }
    try {
        flowValidator.flowMirrorPointValidate(mirrorPoint);
    } catch (InvalidFlowException e) {
        throw new FlowProcessingException(e.getType(), e.getMessage(), e);
    } catch (UnavailableFlowEndpointException e) {
        throw new FlowProcessingException(ErrorType.DATA_INVALID, e.getMessage(), e);
    }
    stateMachine.saveNewEventToHistory("Flow was validated successfully", FlowEventData.Event.FLOW_MIRROR_POINT_CREATE);
    return Optional.empty();
}
Also used : PathId(org.openkilda.model.PathId) UnavailableFlowEndpointException(org.openkilda.wfm.topology.flowhs.validation.UnavailableFlowEndpointException) RequestedFlowMirrorPoint(org.openkilda.wfm.topology.flowhs.model.RequestedFlowMirrorPoint) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) PhysicalPort(org.openkilda.model.PhysicalPort) InvalidFlowException(org.openkilda.wfm.topology.flowhs.validation.InvalidFlowException) Flow(org.openkilda.model.Flow)

Example 2 with InvalidFlowException

use of org.openkilda.wfm.topology.flowhs.validation.InvalidFlowException 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 3 with InvalidFlowException

use of org.openkilda.wfm.topology.flowhs.validation.InvalidFlowException 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 4 with InvalidFlowException

use of org.openkilda.wfm.topology.flowhs.validation.InvalidFlowException in project open-kilda by telstra.

the class ValidateYFlowAction method performWithResponse.

@Override
protected Optional<Message> performWithResponse(State from, State to, Event event, YFlowCreateContext context, YFlowCreateFsm stateMachine) {
    YFlowRequest targetFlow = context.getTargetFlow();
    String yFlowId = targetFlow.getYFlowId();
    boolean isOperationAllowed = featureTogglesRepository.getOrDefault().getModifyYFlowEnabled();
    if (!isOperationAllowed) {
        throw new FlowProcessingException(ErrorType.NOT_PERMITTED, "Y-flow create feature is disabled");
    }
    if (flowRepository.exists(yFlowId)) {
        throw new FlowProcessingException(ErrorType.ALREADY_EXISTS, format("Flow %s already exists", yFlowId));
    }
    if (yFlowRepository.exists(yFlowId)) {
        throw new FlowProcessingException(ErrorType.ALREADY_EXISTS, format("Y-flow %s already exists", yFlowId));
    }
    try {
        yFlowValidator.validate(targetFlow);
    } catch (InvalidFlowException e) {
        throw new FlowProcessingException(e.getType(), e.getMessage(), e);
    } catch (UnavailableFlowEndpointException e) {
        throw new FlowProcessingException(ErrorType.DATA_INVALID, e.getMessage(), e);
    }
    stateMachine.setTargetFlow(targetFlow);
    List<FlowEndpoint> subFlowEndpoints = targetFlow.getSubFlows().stream().map(SubFlowDto::getEndpoint).collect(Collectors.toList());
    dashboardLogger.onYFlowCreate(yFlowId, targetFlow.getSharedEndpoint(), subFlowEndpoints, targetFlow.getMaximumBandwidth());
    stateMachine.saveNewEventToHistory("Y-flow was validated successfully", FlowEventData.Event.CREATE);
    return Optional.empty();
}
Also used : UnavailableFlowEndpointException(org.openkilda.wfm.topology.flowhs.validation.UnavailableFlowEndpointException) FlowEndpoint(org.openkilda.model.FlowEndpoint) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) InvalidFlowException(org.openkilda.wfm.topology.flowhs.validation.InvalidFlowException) YFlowRequest(org.openkilda.messaging.command.yflow.YFlowRequest)

Example 5 with InvalidFlowException

use of org.openkilda.wfm.topology.flowhs.validation.InvalidFlowException in project open-kilda by telstra.

the class ValidateYFlowAction method performWithResponse.

@Override
protected Optional<Message> performWithResponse(State from, State to, Event event, YFlowUpdateContext context, YFlowUpdateFsm stateMachine) {
    YFlowRequest targetFlow = context.getTargetFlow();
    boolean isOperationAllowed = featureTogglesRepository.getOrDefault().getModifyYFlowEnabled();
    if (!isOperationAllowed) {
        throw new FlowProcessingException(ErrorType.NOT_PERMITTED, "Y-flow create feature is disabled");
    }
    try {
        yFlowValidator.validate(targetFlow);
    } catch (InvalidFlowException e) {
        throw new FlowProcessingException(e.getType(), e.getMessage(), e);
    } catch (UnavailableFlowEndpointException e) {
        throw new FlowProcessingException(ErrorType.DATA_INVALID, e.getMessage(), e);
    }
    String yFlowId = targetFlow.getYFlowId();
    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;
    });
    Set<String> requestedSubFlowIds = targetFlow.getSubFlows().stream().map(SubFlowDto::getFlowId).collect(Collectors.toSet());
    Set<String> originalSubFlowIds = yFlow.getSubFlows().stream().map(YSubFlow::getSubFlowId).collect(Collectors.toSet());
    if (!requestedSubFlowIds.equals(originalSubFlowIds)) {
        throw new FlowProcessingException(ErrorType.PARAMETERS_INVALID, format("Unable to map provided sub-flows set onto existing y-flow %s", yFlowId));
    }
    YSubFlow subFlow = yFlow.getSubFlows().stream().findAny().orElseThrow(() -> new FlowProcessingException(ErrorType.DATA_INVALID, format("No sub-flows of the y-flow %s were found", yFlowId)));
    stateMachine.setMainAffinityFlowId(subFlow.getFlow().getAffinityGroupId());
    List<FlowEndpoint> subFlowEndpoints = targetFlow.getSubFlows().stream().map(SubFlowDto::getEndpoint).collect(Collectors.toList());
    dashboardLogger.onYFlowUpdate(yFlowId, targetFlow.getSharedEndpoint(), subFlowEndpoints, targetFlow.getMaximumBandwidth());
    stateMachine.setTargetFlow(targetFlow);
    stateMachine.saveNewEventToHistory("Y-flow was validated successfully", FlowEventData.Event.UPDATE);
    return Optional.empty();
}
Also used : UnavailableFlowEndpointException(org.openkilda.wfm.topology.flowhs.validation.UnavailableFlowEndpointException) YFlow(org.openkilda.model.YFlow) FlowEndpoint(org.openkilda.model.FlowEndpoint) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) InvalidFlowException(org.openkilda.wfm.topology.flowhs.validation.InvalidFlowException) YFlowRequest(org.openkilda.messaging.command.yflow.YFlowRequest) YSubFlow(org.openkilda.model.YSubFlow)

Aggregations

FlowProcessingException (org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException)6 InvalidFlowException (org.openkilda.wfm.topology.flowhs.validation.InvalidFlowException)6 UnavailableFlowEndpointException (org.openkilda.wfm.topology.flowhs.validation.UnavailableFlowEndpointException)6 Flow (org.openkilda.model.Flow)3 RequestedFlow (org.openkilda.wfm.topology.flowhs.model.RequestedFlow)3 YFlowRequest (org.openkilda.messaging.command.yflow.YFlowRequest)2 FlowEndpoint (org.openkilda.model.FlowEndpoint)2 ErrorData (org.openkilda.messaging.error.ErrorData)1 PathId (org.openkilda.model.PathId)1 PhysicalPort (org.openkilda.model.PhysicalPort)1 YFlow (org.openkilda.model.YFlow)1 YSubFlow (org.openkilda.model.YSubFlow)1 RequestedFlowMirrorPoint (org.openkilda.wfm.topology.flowhs.model.RequestedFlowMirrorPoint)1