use of org.openkilda.pce.exception.UnroutableFlowException in project open-kilda by telstra.
the class ResourcesAllocationAction method performWithResponse.
@Override
protected Optional<Message> performWithResponse(State from, State to, Event event, FlowCreateContext context, FlowCreateFsm stateMachine) throws FlowProcessingException {
try {
String flowId = stateMachine.getFlowId();
log.debug("Allocation resources has been started");
stateMachine.setPathsBeenAllocated(false);
if (context != null && context.getTargetFlow() != null) {
createFlow(context.getTargetFlow());
} else if (!flowRepository.exists(flowId)) {
log.warn("Flow {} has been deleted while creation was in progress", flowId);
return Optional.empty();
}
createPaths(stateMachine);
log.debug("Resources allocated successfully for the flow {}", flowId);
stateMachine.setPathsBeenAllocated(true);
Flow resultFlow = getFlow(flowId);
createSpeakerRequestFactories(stateMachine, resultFlow);
saveHistory(stateMachine, resultFlow);
if (resultFlow.isOneSwitchFlow()) {
stateMachine.fire(Event.SKIP_NON_INGRESS_RULES_INSTALL);
} else {
stateMachine.fireNext(context);
}
// Notify about successful allocation.
stateMachine.notifyEventListeners(listener -> listener.onResourcesAllocated(flowId));
return Optional.of(buildResponseMessage(resultFlow, stateMachine.getCommandContext()));
} catch (UnroutableFlowException | RecoverableException e) {
throw new FlowProcessingException(ErrorType.NOT_FOUND, "Not enough bandwidth or no path found. " + e.getMessage(), e);
} catch (ResourceAllocationException e) {
throw new FlowProcessingException(ErrorType.INTERNAL_ERROR, "Failed to allocate flow resources. " + e.getMessage(), e);
} catch (FlowNotFoundException e) {
throw new FlowProcessingException(ErrorType.NOT_FOUND, "Couldn't find the diverse flow. " + e.getMessage(), e);
} catch (FlowAlreadyExistException e) {
if (!stateMachine.retryIfAllowed()) {
throw new FlowProcessingException(ErrorType.INTERNAL_ERROR, e.getMessage(), e);
} else {
// we have retried the operation, no need to respond.
log.debug(e.getMessage(), e);
return Optional.empty();
}
}
}
use of org.openkilda.pce.exception.UnroutableFlowException in project open-kilda by telstra.
the class FlowRerouteServiceTest method shouldFailRerouteOnErrorDuringCompletingFlowPathInstallation.
@Test
public void shouldFailRerouteOnErrorDuringCompletingFlowPathInstallation() throws RecoverableException, UnroutableFlowException, UnknownKeyException {
Flow origin = makeFlow();
preparePathComputation(origin.getFlowId(), make3SwitchesPathPair());
FlowPathRepository repository = setupFlowPathRepositorySpy();
Set<PathId> originalPaths = origin.getPaths().stream().map(FlowPath::getPathId).collect(toSet());
doThrow(new RuntimeException(injectedErrorMessage)).when(repository).updateStatus(ArgumentMatchers.argThat(argument -> !originalPaths.contains(argument)), eq(FlowPathStatus.ACTIVE));
FlowRerouteService service = makeService();
FlowRerouteRequest request = new FlowRerouteRequest(origin.getFlowId(), false, false, false, Collections.emptySet(), null, false);
service.handleRequest(currentRequestKey, request, commandContext);
verifyFlowStatus(origin.getFlowId(), FlowStatus.IN_PROGRESS);
verifyNorthboundSuccessResponse(carrier);
FlowSegmentRequest speakerRequest;
while ((speakerRequest = requests.poll()) != null) {
if (speakerRequest.isVerifyRequest()) {
service.handleAsyncResponse(currentRequestKey, buildResponseOnVerifyRequest(speakerRequest));
} else {
produceAsyncResponse(service, speakerRequest);
}
}
Flow result = verifyFlowStatus(origin.getFlowId(), FlowStatus.UP);
verifyNoPathReplace(origin, result);
}
use of org.openkilda.pce.exception.UnroutableFlowException in project open-kilda by telstra.
the class FlowUpdateServiceTest method shouldFailUpdateOnErrorDuringCompletingFlowPathInstallation.
@Test
public void shouldFailUpdateOnErrorDuringCompletingFlowPathInstallation() throws RecoverableException, UnroutableFlowException, DuplicateKeyException, UnknownKeyException {
Flow origin = makeFlow();
preparePathComputation(origin.getFlowId(), make3SwitchesPathPair());
FlowRequest request = makeRequest().flowId(origin.getFlowId()).build();
FlowPathRepository repository = setupFlowPathRepositorySpy();
Set<PathId> originalPaths = origin.getPaths().stream().map(FlowPath::getPathId).collect(Collectors.toSet());
doThrow(new RuntimeException(injectedErrorMessage)).when(repository).updateStatus(ArgumentMatchers.argThat(argument -> !originalPaths.contains(argument)), eq(FlowPathStatus.ACTIVE));
FlowUpdateService service = makeService();
service.handleUpdateRequest(dummyRequestKey, commandContext, request);
verifyFlowStatus(origin.getFlowId(), FlowStatus.IN_PROGRESS);
verifyNorthboundSuccessResponse(carrier);
FlowSegmentRequest speakerRequest;
while ((speakerRequest = requests.poll()) != null) {
if (speakerRequest.isVerifyRequest()) {
service.handleAsyncResponse(dummyRequestKey, buildResponseOnVerifyRequest(speakerRequest));
} else {
service.handleAsyncResponse(dummyRequestKey, SpeakerFlowSegmentResponse.builder().messageContext(speakerRequest.getMessageContext()).commandId(speakerRequest.getCommandId()).metadata(speakerRequest.getMetadata()).switchId(speakerRequest.getSwitchId()).success(true).build());
}
}
Flow result = verifyFlowStatus(origin.getFlowId(), FlowStatus.UP);
verifyNoPathReplace(origin, result);
}
use of org.openkilda.pce.exception.UnroutableFlowException in project open-kilda by telstra.
the class AllocateProtectedResourcesAction method allocate.
@TimedExecution("fsm.resource_allocation_protected")
@Override
protected void allocate(FlowRerouteFsm stateMachine) throws RecoverableException, UnroutableFlowException, ResourceAllocationException {
String flowId = stateMachine.getFlowId();
Flow tmpFlowCopy = getFlow(flowId);
// Detach the entity to avoid propagation to the database.
flowRepository.detach(tmpFlowCopy);
if (stateMachine.getNewEncapsulationType() != null) {
// This is for PCE to use proper (updated) encapsulation type.
tmpFlowCopy.setEncapsulationType(stateMachine.getNewEncapsulationType());
}
FlowPathPair oldPaths = new FlowPathPair(tmpFlowCopy.getProtectedForwardPath(), tmpFlowCopy.getProtectedReversePath());
FlowPath primaryForward = tmpFlowCopy.getPath(stateMachine.getNewPrimaryForwardPath()).orElse(tmpFlowCopy.getForwardPath());
FlowPath primaryReverse = tmpFlowCopy.getPath(stateMachine.getNewPrimaryReversePath()).orElse(tmpFlowCopy.getReversePath());
Predicate<GetPathsResult> testNonOverlappingPath = path -> (primaryForward == null || !flowPathBuilder.arePathsOverlapped(path.getForward(), primaryForward)) && (primaryReverse == null || !flowPathBuilder.arePathsOverlapped(path.getReverse(), primaryReverse));
PathId newForwardPathId = resourcesManager.generatePathId(flowId);
PathId newReversePathId = resourcesManager.generatePathId(flowId);
List<PathId> pathsToReuse = Lists.newArrayList(tmpFlowCopy.getProtectedForwardPathId(), tmpFlowCopy.getProtectedReversePathId());
pathsToReuse.addAll(stateMachine.getRejectedPaths());
log.debug("Finding a new protected path for flow {}", flowId);
GetPathsResult allocatedPaths = allocatePathPair(tmpFlowCopy, newForwardPathId, newReversePathId, stateMachine.isIgnoreBandwidth(), pathsToReuse, oldPaths, stateMachine.isRecreateIfSamePath(), stateMachine.getSharedBandwidthGroupId(), testNonOverlappingPath);
if (allocatedPaths != null) {
stateMachine.setBackUpProtectedPathComputationWayUsed(allocatedPaths.isBackUpPathComputationWayUsed());
if (!testNonOverlappingPath.test(allocatedPaths)) {
stateMachine.saveActionToHistory("Couldn't find non overlapping protected path. Skipped creating it");
stateMachine.fireNoPathFound("Couldn't find non overlapping protected path");
} else {
log.debug("New protected paths have been allocated: {}", allocatedPaths);
stateMachine.setNewProtectedForwardPath(newForwardPathId);
stateMachine.setNewProtectedReversePath(newReversePathId);
log.debug("Allocating resources for a new protected path of flow {}", flowId);
FlowResources flowResources = allocateFlowResources(tmpFlowCopy, newForwardPathId, newReversePathId);
stateMachine.setNewProtectedResources(flowResources);
FlowPathPair createdPaths = createFlowPathPair(flowId, flowResources, allocatedPaths, stateMachine.isIgnoreBandwidth(), stateMachine.getSharedBandwidthGroupId());
log.debug("New protected paths have been created: {}", createdPaths);
saveAllocationActionWithDumpsToHistory(stateMachine, tmpFlowCopy, "protected", createdPaths);
}
} else {
stateMachine.saveActionToHistory("Found the same protected path. Skipped creating of it");
}
}
use of org.openkilda.pce.exception.UnroutableFlowException 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());
}
Aggregations