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