use of org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException in project open-kilda by telstra.
the class ValidateFlowAction method performWithResponse.
@TimedExecution("fsm.validate_flow")
@Override
protected Optional<Message> performWithResponse(State from, State to, Event event, FlowRerouteContext context, FlowRerouteFsm stateMachine) {
String flowId = stateMachine.getFlowId();
Set<IslEndpoint> affectedIsl = new HashSet<>(Optional.ofNullable(context.getAffectedIsl()).orElse(emptySet()));
dashboardLogger.onFlowPathReroute(flowId, affectedIsl, context.isForceReroute());
String rerouteReason = context.getRerouteReason();
stateMachine.saveNewEventToHistory("Started flow validation", FlowEventData.Event.REROUTE, rerouteReason == null ? FlowEventData.Initiator.NB : FlowEventData.Initiator.AUTO, rerouteReason == null ? null : "Reason: " + rerouteReason);
stateMachine.setRerouteReason(rerouteReason);
Flow flow = transactionManager.doInTransaction(() -> {
Flow foundFlow = getFlow(flowId);
if (foundFlow.getStatus() == FlowStatus.IN_PROGRESS) {
String message = format("Flow %s is in progress now", flowId);
stateMachine.setRerouteError(new RerouteError(message));
throw new FlowProcessingException(ErrorType.REQUEST_INVALID, message);
}
if (!foundFlow.getSrcSwitch().isActive()) {
String message = format("Flow's %s src switch is not active", flowId);
stateMachine.setRerouteError(new RerouteError(message));
throw new FlowProcessingException(ErrorType.UNPROCESSABLE_REQUEST, message);
}
if (!foundFlow.getDestSwitch().isActive()) {
String message = format("Flow's %s dest switch is not active", flowId);
stateMachine.setRerouteError(new RerouteError(message));
throw new FlowProcessingException(ErrorType.UNPROCESSABLE_REQUEST, message);
}
stateMachine.setOriginalFlowStatus(foundFlow.getStatus());
stateMachine.setOriginalFlowStatusInfo(foundFlow.getStatusInfo());
stateMachine.setOriginalEncapsulationType(foundFlow.getEncapsulationType());
stateMachine.setOriginalPathComputationStrategy(foundFlow.getPathComputationStrategy());
stateMachine.setRecreateIfSamePath(!foundFlow.isActive() || context.isForceReroute());
stateMachine.setOriginalFlow(RequestedFlowMapper.INSTANCE.toRequestedFlow(foundFlow));
stateMachine.setPeriodicPingsEnabled(foundFlow.isPeriodicPings());
if (foundFlow.getTargetPathComputationStrategy() != null) {
foundFlow.setPathComputationStrategy(foundFlow.getTargetPathComputationStrategy());
foundFlow.setTargetPathComputationStrategy(null);
}
foundFlow.setStatus(FlowStatus.IN_PROGRESS);
return foundFlow;
});
if (featureTogglesRepository.getOrDefault().getFlowsRerouteUsingDefaultEncapType()) {
stateMachine.setNewEncapsulationType(kildaConfigurationRepository.getOrDefault().getFlowEncapsulationType());
}
boolean reroutePrimary;
boolean rerouteProtected;
if (affectedIsl.isEmpty()) {
// no know affected ISLs
reroutePrimary = true;
rerouteProtected = true;
} else {
reroutePrimary = checkIsPathAffected(flow.getForwardPath(), affectedIsl) || checkIsPathAffected(flow.getReversePath(), affectedIsl);
rerouteProtected = checkIsPathAffected(flow.getProtectedForwardPath(), affectedIsl) || checkIsPathAffected(flow.getProtectedReversePath(), affectedIsl);
}
// check protected path presence
rerouteProtected &= flow.isAllocateProtectedPath();
if (!reroutePrimary && !rerouteProtected) {
throw new FlowProcessingException(ErrorType.NOT_FOUND, format("No paths of the flow %s are affected by failure on %s", flowId, affectedIsl.stream().map(IslEndpoint::toString).collect(Collectors.joining(","))));
}
if (reroutePrimary) {
log.info("Reroute for the flow {} will affect primary paths: {} / {}", flowId, flow.getForwardPathId(), flow.getReversePathId());
}
if (rerouteProtected) {
log.info("Reroute for the flow {} will affect protected paths: {} / {}", flowId, flow.getProtectedForwardPathId(), flow.getProtectedReversePathId());
}
stateMachine.setReroutePrimary(reroutePrimary);
stateMachine.setRerouteProtected(rerouteProtected);
stateMachine.setEffectivelyDown(context.isEffectivelyDown());
if (stateMachine.isRerouteProtected() && flow.isPinned()) {
throw new FlowProcessingException(ErrorType.REQUEST_INVALID, format("Flow %s is pinned, fail to reroute its protected paths", flowId));
}
stateMachine.setAffectedIsls(context.getAffectedIsl());
stateMachine.setForceReroute(context.isForceReroute());
stateMachine.setIgnoreBandwidth(context.isIgnoreBandwidth());
stateMachine.saveActionToHistory("Flow was validated successfully");
return Optional.empty();
}
use of org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException in project open-kilda by telstra.
the class OnSubFlowAllocatedAction method performWithResponse.
@Override
protected Optional<Message> performWithResponse(State from, State to, Event event, YFlowCreateContext context, YFlowCreateFsm stateMachine) {
String subFlowId = context.getSubFlowId();
if (!stateMachine.isCreatingSubFlow(subFlowId)) {
throw new IllegalStateException("Received an event for non-pending sub-flow " + subFlowId);
}
String yFlowId = stateMachine.getYFlowId();
stateMachine.saveActionToHistory("Creating a sub-flow", format("Allocated resources for sub-flow %s of y-flow %s", subFlowId, yFlowId));
stateMachine.addAllocatedSubFlow(subFlowId);
SubFlowDto subFlowDto = stateMachine.getTargetFlow().getSubFlows().stream().filter(f -> f.getFlowId().equals(subFlowId)).findAny().orElseThrow(() -> new FlowProcessingException(ErrorType.INTERNAL_ERROR, format("Can't find definition of created sub-flow %s", subFlowId)));
SubFlowSharedEndpointEncapsulation sharedEndpoint = subFlowDto.getSharedEndpoint();
FlowEndpoint endpoint = subFlowDto.getEndpoint();
log.debug("Start creating sub-flow references from {} to y-flow {}", subFlowId, stateMachine.getYFlowId());
YFlow result = transactionManager.doInTransaction(() -> {
YFlow yFlow = yFlowRepository.findById(yFlowId).orElseThrow(() -> new FlowProcessingException(ErrorType.INTERNAL_ERROR, format("Y-flow %s not found", yFlowId)));
Flow flow = flowRepository.findById(subFlowId).orElseThrow(() -> new FlowProcessingException(ErrorType.INTERNAL_ERROR, format("Flow %s not found", subFlowId)));
YSubFlow subFlow = YSubFlow.builder().yFlow(yFlow).flow(flow).sharedEndpointVlan(sharedEndpoint.getVlanId()).sharedEndpointInnerVlan(sharedEndpoint.getInnerVlanId()).endpointSwitchId(endpoint.getSwitchId()).endpointPort(endpoint.getPortNumber()).endpointVlan(endpoint.getOuterVlanId()).endpointInnerVlan(endpoint.getInnerVlanId()).build();
yFlow.addSubFlow(subFlow);
return yFlow;
});
if (subFlowId.equals(stateMachine.getMainAffinityFlowId())) {
stateMachine.getRequestedFlows().forEach(requestedFlow -> {
String requestedFlowId = requestedFlow.getFlowId();
if (!requestedFlowId.equals(subFlowId)) {
stateMachine.addSubFlow(requestedFlowId);
stateMachine.addCreatingSubFlow(requestedFlowId);
stateMachine.notifyEventListeners(listener -> listener.onSubFlowProcessingStart(yFlowId, requestedFlowId));
CommandContext flowContext = stateMachine.getCommandContext().fork(requestedFlowId);
requestedFlow.setAffinityFlowId(stateMachine.getMainAffinityFlowId());
flowCreateService.startFlowCreation(flowContext, requestedFlow, yFlowId);
}
});
}
if (stateMachine.getAllocatedSubFlows().size() == stateMachine.getSubFlows().size()) {
return Optional.of(buildResponseMessage(result, stateMachine.getCommandContext()));
} else {
return Optional.empty();
}
}
use of org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException in project open-kilda by telstra.
the class OnSubFlowAllocatedAction method convertToYFlowDto.
private YFlowDto convertToYFlowDto(YFlow yFlow) {
Flow mainAffinityFlow = yFlow.getSubFlows().stream().map(YSubFlow::getFlow).filter(flow -> flow.getFlowId().equals(flow.getAffinityGroupId())).findFirst().orElseThrow(() -> new FlowProcessingException(ErrorType.INTERNAL_ERROR, "Main affinity flow not found"));
Collection<Flow> diverseWithFlow = getDiverseWithFlow(mainAffinityFlow);
Set<String> diverseFlows = diverseWithFlow.stream().filter(flow -> flow.getYFlowId() == null).map(Flow::getFlowId).collect(Collectors.toSet());
Set<String> diverseYFlows = diverseWithFlow.stream().map(Flow::getYFlowId).filter(Objects::nonNull).collect(Collectors.toSet());
return YFlowMapper.INSTANCE.toYFlowDto(yFlow, diverseFlows, diverseYFlows);
}
use of org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException in project open-kilda by telstra.
the class RevertFlowAction method revertFlow.
private void revertFlow(Flow flow, FlowUpdateFsm stateMachine) {
flow.setDiverseGroupId(stateMachine.getOriginalDiverseFlowGroup());
flow.setAffinityGroupId(stateMachine.getOriginalAffinityFlowGroup());
RequestedFlow originalFlow = stateMachine.getOriginalFlow();
Switch srcSwitch = switchRepository.findById(originalFlow.getSrcSwitch()).orElseThrow(() -> new FlowProcessingException(ErrorType.NOT_FOUND, format("Switch %s not found", originalFlow.getSrcSwitch())));
flow.setSrcSwitch(srcSwitch);
flow.setSrcPort(originalFlow.getSrcPort());
flow.setSrcVlan(originalFlow.getSrcVlan());
Switch destSwitch = switchRepository.findById(originalFlow.getDestSwitch()).orElseThrow(() -> new FlowProcessingException(ErrorType.NOT_FOUND, format("Switch %s not found", originalFlow.getDestSwitch())));
flow.setDestSwitch(destSwitch);
flow.setDestPort(originalFlow.getDestPort());
flow.setDestVlan(originalFlow.getDestVlan());
flow.setPriority(originalFlow.getPriority());
flow.setPinned(originalFlow.isPinned());
flow.setAllocateProtectedPath(originalFlow.isAllocateProtectedPath());
flow.setDescription(originalFlow.getDescription());
flow.setBandwidth(originalFlow.getBandwidth());
flow.setIgnoreBandwidth(originalFlow.isIgnoreBandwidth());
flow.setMaxLatency(originalFlow.getMaxLatency());
flow.setPeriodicPings(originalFlow.isPeriodicPings());
flow.setEncapsulationType(originalFlow.getFlowEncapsulationType());
flow.setPathComputationStrategy(originalFlow.getPathComputationStrategy());
flow.setTargetPathComputationStrategy(stateMachine.getOldTargetPathComputationStrategy());
}
use of org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException in project open-kilda by telstra.
the class ValidateYFlowAction method performWithResponse.
@Override
protected Optional<Message> performWithResponse(State from, State to, Event event, YFlowDeleteContext context, YFlowDeleteFsm stateMachine) {
String yFlowId = stateMachine.getYFlowId();
dashboardLogger.onYFlowDelete(yFlowId);
boolean isOperationAllowed = featureTogglesRepository.getOrDefault().getModifyYFlowEnabled();
if (!isOperationAllowed) {
throw new FlowProcessingException(ErrorType.NOT_PERMITTED, "Y-flow delete feature is disabled");
}
YFlow result = transactionManager.doInTransaction(() -> {
YFlow yFlow = yFlowRepository.findById(yFlowId).orElseThrow(() -> new FlowProcessingException(ErrorType.NOT_FOUND, format("Y-flow %s not found", yFlowId)));
if (yFlow.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(yFlow.getStatus());
yFlow.setStatus(FlowStatus.IN_PROGRESS);
return yFlow;
});
stateMachine.saveNewEventToHistory("Y-flow was validated successfully", FlowEventData.Event.DELETE);
return Optional.of(buildResponseMessage(result, stateMachine.getCommandContext()));
}
Aggregations