use of org.openkilda.wfm.share.flow.resources.ResourceAllocationException in project open-kilda by telstra.
the class BaseResourceAllocationAction method createPathSegments.
@VisibleForTesting
void createPathSegments(List<PathSegment> segments, Supplier<Map<IslEndpoints, Long>> reuseBandwidth) throws ResourceAllocationException {
for (PathSegment segment : segments) {
log.debug("Persisting the segment {}", segment);
long updatedAvailableBandwidth = pathSegmentRepository.addSegmentAndUpdateIslAvailableBandwidth(segment).orElse(0L);
if (!segment.isIgnoreBandwidth() && updatedAvailableBandwidth < 0) {
IslEndpoints isl = new IslEndpoints(segment.getSrcSwitchId().toString(), segment.getSrcPort(), segment.getDestSwitchId().toString(), segment.getDestPort());
log.debug("ISL {} is being over-provisioned, check if it's allowed", isl);
long allowedOverprovisionedBandwidth = reuseBandwidth.get().getOrDefault(isl, 0L);
if ((updatedAvailableBandwidth + allowedOverprovisionedBandwidth) < 0) {
throw new ResourceAllocationException(format("ISL %s_%d-%s_%d was overprovisioned", isl.getSrcSwitch(), isl.getSrcPort(), isl.getDestSwitch(), isl.getDestPort()));
}
}
}
}
use of org.openkilda.wfm.share.flow.resources.ResourceAllocationException 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.wfm.share.flow.resources.ResourceAllocationException in project open-kilda by telstra.
the class AllocateProtectedResourcesAction method allocate.
@Override
protected void allocate(FlowUpdateFsm stateMachine) throws RecoverableException, UnroutableFlowException, ResourceAllocationException {
String flowId = stateMachine.getFlowId();
Set<String> flowIds = Sets.newHashSet(flowId);
if (stateMachine.getBulkUpdateFlowIds() != null) {
flowIds.addAll(stateMachine.getBulkUpdateFlowIds());
}
log.debug("Finding protected path ids for flows {}", flowIds);
List<PathId> pathIdsToReuse = new ArrayList<>(flowPathRepository.findActualPathIdsByFlowIds(flowIds));
pathIdsToReuse.addAll(stateMachine.getRejectedPaths());
Flow tmpFlow = getFlow(flowId);
FlowPathPair oldPaths = new FlowPathPair(tmpFlow.getProtectedForwardPath(), tmpFlow.getProtectedReversePath());
FlowPath primaryForward = getFlowPath(tmpFlow, stateMachine.getNewPrimaryForwardPath());
FlowPath primaryReverse = getFlowPath(tmpFlow, stateMachine.getNewPrimaryReversePath());
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);
log.debug("Finding a new protected path for flow {}", flowId);
GetPathsResult allocatedPaths = allocatePathPair(tmpFlow, newForwardPathId, newReversePathId, false, pathIdsToReuse, oldPaths, true, stateMachine.getSharedBandwidthGroupId(), testNonOverlappingPath);
if (allocatedPaths == null) {
throw new ResourceAllocationException("Unable to allocate a path");
}
if (!testNonOverlappingPath.test(allocatedPaths)) {
stateMachine.saveActionToHistory("Couldn't find non overlapping protected path");
} else {
log.debug("New protected paths have been allocated: {}", allocatedPaths);
stateMachine.setNewProtectedForwardPath(newForwardPathId);
stateMachine.setNewProtectedReversePath(newReversePathId);
stateMachine.setBackUpProtectedPathComputationWayUsed(allocatedPaths.isBackUpPathComputationWayUsed());
log.debug("Allocating resources for a new protected path of flow {}", flowId);
FlowResources flowResources = allocateFlowResources(tmpFlow, newForwardPathId, newReversePathId);
stateMachine.setNewProtectedResources(flowResources);
FlowPathPair createdPaths = createFlowPathPair(flowId, flowResources, allocatedPaths, false, stateMachine.getSharedBandwidthGroupId());
log.debug("New protected path has been created: {}", createdPaths);
saveAllocationActionWithDumpsToHistory(stateMachine, tmpFlow, "protected", createdPaths);
}
}
use of org.openkilda.wfm.share.flow.resources.ResourceAllocationException in project open-kilda by telstra.
the class FlowUpdateServiceTest method shouldFailUpdateFlowIfNoResourcesAvailable.
@Test
public void shouldFailUpdateFlowIfNoResourcesAvailable() throws RecoverableException, UnroutableFlowException, ResourceAllocationException, DuplicateKeyException {
Flow origin = makeFlow();
preparePathComputation(origin.getFlowId(), make3SwitchesPathPair());
doThrow(new ResourceAllocationException(injectedErrorMessage)).when(flowResourcesManager).allocateFlowResources(makeFlowArgumentMatch(origin.getFlowId()), any(), any());
FlowRequest request = makeRequest().flowId(origin.getFlowId()).build();
testExpectedFailure(request, origin, ErrorType.INTERNAL_ERROR);
verify(flowResourcesManager, times(PATH_ALLOCATION_RETRIES_LIMIT + 1)).allocateFlowResources(makeFlowArgumentMatch(origin.getFlowId()), any(), any());
}
use of org.openkilda.wfm.share.flow.resources.ResourceAllocationException 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());
}
Aggregations