use of org.openkilda.pce.exception.UnroutableFlowException in project open-kilda by telstra.
the class BaseResourceAllocationAction method allocatePathPair.
@SneakyThrows
protected GetPathsResult allocatePathPair(Flow flow, PathId newForwardPathId, PathId newReversePathId, boolean forceToIgnoreBandwidth, List<PathId> pathsToReuseBandwidth, FlowPathPair oldPaths, boolean allowOldPaths, String sharedBandwidthGroupId, Predicate<GetPathsResult> whetherCreatePathSegments) throws RecoverableException, UnroutableFlowException, ResourceAllocationException {
// Lazy initialisable map with reused bandwidth...
Supplier<Map<IslEndpoints, Long>> reuseBandwidthPerIsl = Suppliers.memoize(() -> {
Map<IslEndpoints, Long> result = new HashMap<>();
if (pathsToReuseBandwidth != null && !pathsToReuseBandwidth.isEmpty()) {
pathsToReuseBandwidth.stream().map(pathId -> flow.getPath(pathId).orElse(flowPathRepository.findById(pathId).orElse(null))).filter(Objects::nonNull).flatMap(path -> path.getSegments().stream()).forEach(segment -> {
IslEndpoints isl = new IslEndpoints(segment.getSrcSwitchId().toString(), segment.getSrcPort(), segment.getDestSwitchId().toString(), segment.getDestPort());
result.put(isl, result.getOrDefault(isl, 0L) + segment.getBandwidth());
});
}
return result;
});
RetryPolicy<GetPathsResult> pathAllocationRetryPolicy = new RetryPolicy<GetPathsResult>().handle(RecoverableException.class).handle(ResourceAllocationException.class).handle(UnroutableFlowException.class).handle(PersistenceException.class).onRetry(e -> log.warn("Failure in path allocation. Retrying #{}...", e.getAttemptCount(), e.getLastFailure())).onRetriesExceeded(e -> log.warn("Failure in path allocation. No more retries", e.getFailure())).withMaxRetries(pathAllocationRetriesLimit);
if (pathAllocationRetryDelay > 0) {
pathAllocationRetryPolicy.withDelay(Duration.ofMillis(pathAllocationRetryDelay));
}
try {
return Failsafe.with(pathAllocationRetryPolicy).get(() -> {
GetPathsResult potentialPath;
if (forceToIgnoreBandwidth) {
boolean originalIgnoreBandwidth = flow.isIgnoreBandwidth();
flow.setIgnoreBandwidth(true);
potentialPath = pathComputer.getPath(flow);
flow.setIgnoreBandwidth(originalIgnoreBandwidth);
} else {
potentialPath = pathComputer.getPath(flow, pathsToReuseBandwidth);
}
boolean newPathFound = isNotSamePath(potentialPath, oldPaths);
if (allowOldPaths || newPathFound) {
if (!newPathFound) {
log.debug("Found the same path for flow {}. Proceed with recreating it", flow.getFlowId());
}
if (whetherCreatePathSegments.test(potentialPath)) {
boolean ignoreBandwidth = forceToIgnoreBandwidth || flow.isIgnoreBandwidth();
List<PathSegment> forwardSegments = flowPathBuilder.buildPathSegments(newForwardPathId, potentialPath.getForward(), flow.getBandwidth(), ignoreBandwidth, sharedBandwidthGroupId);
List<PathSegment> reverseSegments = flowPathBuilder.buildPathSegments(newReversePathId, potentialPath.getReverse(), flow.getBandwidth(), ignoreBandwidth, sharedBandwidthGroupId);
transactionManager.doInTransaction(() -> {
createPathSegments(forwardSegments, reuseBandwidthPerIsl);
createPathSegments(reverseSegments, reuseBandwidthPerIsl);
});
}
return potentialPath;
}
return null;
});
} catch (FailsafeException ex) {
throw ex.getCause();
}
}
use of org.openkilda.pce.exception.UnroutableFlowException in project open-kilda by telstra.
the class PathsService method getPaths.
/**
* Get paths.
*/
public List<PathsInfoData> getPaths(SwitchId srcSwitchId, SwitchId dstSwitchId, FlowEncapsulationType requestEncapsulationType, PathComputationStrategy requestPathComputationStrategy, Duration maxLatency, Duration maxLatencyTier2) throws RecoverableException, SwitchNotFoundException, UnroutableFlowException {
if (Objects.equals(srcSwitchId, dstSwitchId)) {
throw new IllegalArgumentException(String.format("Source and destination switch IDs are equal: '%s'", srcSwitchId));
}
if (!switchRepository.exists(srcSwitchId)) {
throw new SwitchNotFoundException(srcSwitchId);
}
if (!switchRepository.exists(dstSwitchId)) {
throw new SwitchNotFoundException(dstSwitchId);
}
KildaConfiguration kildaConfiguration = kildaConfigurationRepository.getOrDefault();
FlowEncapsulationType flowEncapsulationType = Optional.ofNullable(requestEncapsulationType).orElse(kildaConfiguration.getFlowEncapsulationType());
SwitchProperties srcProperties = switchPropertiesRepository.findBySwitchId(srcSwitchId).orElseThrow(() -> new SwitchPropertiesNotFoundException(srcSwitchId));
if (!srcProperties.getSupportedTransitEncapsulation().contains(flowEncapsulationType)) {
throw new IllegalArgumentException(String.format("Switch %s doesn't support %s encapslation type. Choose " + "one of the supported encapsulation types %s or update switch properties and add needed " + "encapsulation type.", srcSwitchId, flowEncapsulationType, srcProperties.getSupportedTransitEncapsulation()));
}
SwitchProperties dstProperties = switchPropertiesRepository.findBySwitchId(dstSwitchId).orElseThrow(() -> new SwitchPropertiesNotFoundException(dstSwitchId));
if (!dstProperties.getSupportedTransitEncapsulation().contains(flowEncapsulationType)) {
throw new IllegalArgumentException(String.format("Switch %s doesn't support %s encapslation type. Choose " + "one of the supported encapsulation types %s or update switch properties and add needed " + "encapsulation type.", dstSwitchId, requestEncapsulationType, dstProperties.getSupportedTransitEncapsulation()));
}
PathComputationStrategy pathComputationStrategy = Optional.ofNullable(requestPathComputationStrategy).orElse(kildaConfiguration.getPathComputationStrategy());
List<Path> flowPaths = pathComputer.getNPaths(srcSwitchId, dstSwitchId, MAX_PATH_COUNT, flowEncapsulationType, pathComputationStrategy, maxLatency, maxLatencyTier2);
return flowPaths.stream().map(PathMapper.INSTANCE::map).map(path -> PathsInfoData.builder().path(path).build()).collect(Collectors.toList());
}
Aggregations