use of org.openkilda.messaging.info.reroute.error.RerouteError in project open-kilda by telstra.
the class RerouteQueueService method processRerouteResult.
/**
* Process reroute result. Check fail reason, decide if retry is needed and schedule it if yes.
*
* @param rerouteResultInfoData reroute result
* @param correlationId correlation id
*/
public void processRerouteResult(RerouteResultInfoData rerouteResultInfoData, String correlationId) {
String flowId = rerouteResultInfoData.getFlowId();
RerouteQueue rerouteQueue = getRerouteQueue(flowId);
FlowThrottlingData inProgress = rerouteQueue.getInProgress();
if (inProgress == null || !Objects.equals(inProgress.getCorrelationId(), correlationId)) {
log.error("Skipped unexpected reroute result for flow {} with correlation id {}.", flowId, correlationId);
return;
}
carrier.cancelTimeout(correlationId);
if (rerouteResultInfoData.isSuccess()) {
FlowThrottlingData toSend = rerouteQueue.processPending();
sendRerouteRequest(flowId, toSend);
} else {
RerouteError rerouteError = rerouteResultInfoData.getRerouteError();
if (isRetryRequired(flowId, rerouteError, rerouteResultInfoData.isYFlow())) {
injectRetry(flowId, rerouteQueue, rerouteError instanceof NoPathFoundError);
} else {
FlowThrottlingData toSend = rerouteQueue.processPending();
sendRerouteRequest(flowId, toSend);
}
}
}
use of org.openkilda.messaging.info.reroute.error.RerouteError in project open-kilda by telstra.
the class YFlowRerouteServiceTest method shouldFailIfNoResourcesAvailable.
@Test
public void shouldFailIfNoResourcesAvailable() throws UnroutableFlowException, RecoverableException, ResourceAllocationException, DuplicateKeyException {
// given
YFlowRequest createYFlowRequest = createYFlow();
YFlowRerouteRequest request = new YFlowRerouteRequest(createYFlowRequest.getYFlowId(), "reason");
preparePathComputationForReroute("test_flow_1", buildFirstSubFlowPathPairWithNewTransit());
preparePathComputationForReroute("test_flow_2", buildSecondSubFlowPathPairWithNewTransit());
prepareYPointComputation(SWITCH_SHARED, SWITCH_FIRST_EP, SWITCH_SECOND_EP, SWITCH_NEW_TRANSIT);
doThrow(new ResourceAllocationException(injectedErrorMessage)).when(flowResourcesManager).allocateMeter(eq("test_successful_yflow"), eq(SWITCH_NEW_TRANSIT));
// when
processRerouteRequestAndSpeakerCommands(request);
verifyYFlowStatus(request.getYFlowId(), FlowStatus.UP);
verify(flowResourcesManager, times(METER_ALLOCATION_RETRIES_LIMIT + 1)).allocateMeter(eq("test_successful_yflow"), eq(SWITCH_NEW_TRANSIT));
verify(yFlowRerouteHubCarrier).sendYFlowRerouteResultStatus(eq(createYFlowRequest.getYFlowId()), eq(new RerouteError("Failed to allocate y-flow resources. Unit-test injected failure")), anyString());
}
use of org.openkilda.messaging.info.reroute.error.RerouteError 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.messaging.info.reroute.error.RerouteError in project open-kilda by telstra.
the class YFlowRerouteServiceTest method shouldFailIfNoPathAvailableForSecondSubFlow.
@Test
public void shouldFailIfNoPathAvailableForSecondSubFlow() throws UnroutableFlowException, RecoverableException, DuplicateKeyException {
// given
YFlowRequest createYFlowRequest = createYFlow();
YFlowRerouteRequest request = new YFlowRerouteRequest(createYFlowRequest.getYFlowId(), "reason");
preparePathComputationForReroute("test_flow_1", buildFirstSubFlowPathPairWithNewTransit());
when(pathComputer.getPath(buildFlowIdArgumentMatch("test_flow_2"), any())).thenThrow(new UnroutableFlowException(injectedErrorMessage));
prepareYPointComputation(SWITCH_SHARED, SWITCH_FIRST_EP, SWITCH_SECOND_EP, SWITCH_NEW_TRANSIT);
// when
processRerouteRequestAndSpeakerCommands(request, FlowStatus.IN_PROGRESS, FlowStatus.IN_PROGRESS, FlowStatus.UP);
verifyNorthboundErrorResponse(yFlowRerouteHubCarrier, ErrorType.NOT_FOUND);
verifyYFlowStatus(request.getYFlowId(), FlowStatus.DEGRADED, FlowStatus.UP, FlowStatus.DOWN);
verify(yFlowRerouteHubCarrier).sendYFlowRerouteResultStatus(eq(createYFlowRequest.getYFlowId()), eq(new RerouteError("Failed to reroute sub-flows [test_flow_2] of y-flow test_successful_yflow")), anyString());
}
use of org.openkilda.messaging.info.reroute.error.RerouteError in project open-kilda by telstra.
the class YFlowRerouteServiceTest method shouldFailOnTimeoutDuringMeterInstallation.
@Test
public void shouldFailOnTimeoutDuringMeterInstallation() throws UnroutableFlowException, RecoverableException, DuplicateKeyException, UnknownKeyException {
// given
YFlowRequest createYFlowRequest = createYFlow();
YFlowRerouteRequest request = new YFlowRerouteRequest(createYFlowRequest.getYFlowId(), "reason");
preparePathComputationForReroute("test_flow_1", buildFirstSubFlowPathPairWithNewTransit());
preparePathComputationForReroute("test_flow_2", buildSecondSubFlowPathPairWithNewTransit());
prepareYPointComputation(SWITCH_SHARED, SWITCH_FIRST_EP, SWITCH_SECOND_EP, SWITCH_NEW_TRANSIT);
YFlowRerouteService service = makeYFlowRerouteService(0);
// when
service.handleRequest(request.getYFlowId(), new CommandContext(), request);
verifyYFlowStatus(request.getYFlowId(), FlowStatus.IN_PROGRESS);
// and
handleSpeakerCommandsAndTimeoutInstall(service, request.getYFlowId());
// then
verifyNorthboundSuccessResponse(yFlowRerouteHubCarrier, YFlowRerouteResponse.class);
verifyYFlowStatus(request.getYFlowId(), FlowStatus.UP);
verifyAffinity(request.getYFlowId());
verify(yFlowRerouteHubCarrier).sendYFlowRerouteResultStatus(eq(createYFlowRequest.getYFlowId()), eq(new RerouteError("Timeout event has been received")), anyString());
}
Aggregations