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();
}
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();
}
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();
}
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();
}
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();
}
Aggregations