Search in sources :

Example 1 with ResourceAllocationException

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()));
            }
        }
    }
}
Also used : IslEndpoints(org.openkilda.persistence.repositories.IslRepository.IslEndpoints) PathSegment(org.openkilda.model.PathSegment) ResourceAllocationException(org.openkilda.wfm.share.flow.resources.ResourceAllocationException) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 2 with ResourceAllocationException

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();
        }
    }
}
Also used : FlowNotFoundException(org.openkilda.wfm.error.FlowNotFoundException) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) FlowAlreadyExistException(org.openkilda.wfm.error.FlowAlreadyExistException) UnroutableFlowException(org.openkilda.pce.exception.UnroutableFlowException) ResourceAllocationException(org.openkilda.wfm.share.flow.resources.ResourceAllocationException) RecoverableException(org.openkilda.pce.exception.RecoverableException) Flow(org.openkilda.model.Flow) YSubFlow(org.openkilda.model.YSubFlow) RequestedFlow(org.openkilda.wfm.topology.flowhs.model.RequestedFlow) YFlow(org.openkilda.model.YFlow)

Example 3 with ResourceAllocationException

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);
    }
}
Also used : BaseResourceAllocationAction(org.openkilda.wfm.topology.flowhs.fsm.common.actions.BaseResourceAllocationAction) FlowPath(org.openkilda.model.FlowPath) ResourceAllocationException(org.openkilda.wfm.share.flow.resources.ResourceAllocationException) RecoverableException(org.openkilda.pce.exception.RecoverableException) ArrayList(java.util.ArrayList) UnroutableFlowException(org.openkilda.pce.exception.UnroutableFlowException) Flow(org.openkilda.model.Flow) FlowPathPair(org.openkilda.wfm.topology.flow.model.FlowPathPair) PersistenceManager(org.openkilda.persistence.PersistenceManager) PathId(org.openkilda.model.PathId) FlowOperationsDashboardLogger(org.openkilda.wfm.share.logger.FlowOperationsDashboardLogger) ErrorType(org.openkilda.messaging.error.ErrorType) Predicate(java.util.function.Predicate) FlowUpdateFsm(org.openkilda.wfm.topology.flowhs.fsm.update.FlowUpdateFsm) Set(java.util.Set) State(org.openkilda.wfm.topology.flowhs.fsm.update.FlowUpdateFsm.State) FlowResources(org.openkilda.wfm.share.flow.resources.FlowResources) Sets(com.google.common.collect.Sets) Event(org.openkilda.wfm.topology.flowhs.fsm.update.FlowUpdateFsm.Event) Slf4j(lombok.extern.slf4j.Slf4j) List(java.util.List) FlowUpdateContext(org.openkilda.wfm.topology.flowhs.fsm.update.FlowUpdateContext) PathComputer(org.openkilda.pce.PathComputer) FlowResourcesManager(org.openkilda.wfm.share.flow.resources.FlowResourcesManager) GetPathsResult(org.openkilda.pce.GetPathsResult) FlowResources(org.openkilda.wfm.share.flow.resources.FlowResources) ArrayList(java.util.ArrayList) Flow(org.openkilda.model.Flow) FlowPathPair(org.openkilda.wfm.topology.flow.model.FlowPathPair) GetPathsResult(org.openkilda.pce.GetPathsResult) PathId(org.openkilda.model.PathId) FlowPath(org.openkilda.model.FlowPath) ResourceAllocationException(org.openkilda.wfm.share.flow.resources.ResourceAllocationException)

Example 4 with ResourceAllocationException

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());
}
Also used : FlowRequest(org.openkilda.messaging.command.flow.FlowRequest) ResourceAllocationException(org.openkilda.wfm.share.flow.resources.ResourceAllocationException) Flow(org.openkilda.model.Flow) Test(org.junit.Test)

Example 5 with ResourceAllocationException

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());
}
Also used : YFlowRerouteRequest(org.openkilda.messaging.command.yflow.YFlowRerouteRequest) RerouteError(org.openkilda.messaging.info.reroute.error.RerouteError) ResourceAllocationException(org.openkilda.wfm.share.flow.resources.ResourceAllocationException) YFlowRequest(org.openkilda.messaging.command.yflow.YFlowRequest) Test(org.junit.Test) AbstractYFlowTest(org.openkilda.wfm.topology.flowhs.service.AbstractYFlowTest)

Aggregations

ResourceAllocationException (org.openkilda.wfm.share.flow.resources.ResourceAllocationException)13 Flow (org.openkilda.model.Flow)9 ArrayList (java.util.ArrayList)5 Test (org.junit.Test)5 FlowPath (org.openkilda.model.FlowPath)5 PathId (org.openkilda.model.PathId)5 GetPathsResult (org.openkilda.pce.GetPathsResult)5 RecoverableException (org.openkilda.pce.exception.RecoverableException)5 UnroutableFlowException (org.openkilda.pce.exception.UnroutableFlowException)5 FlowResources (org.openkilda.wfm.share.flow.resources.FlowResources)5 FlowPathPair (org.openkilda.wfm.topology.flow.model.FlowPathPair)5 List (java.util.List)4 Predicate (java.util.function.Predicate)4 Slf4j (lombok.extern.slf4j.Slf4j)4 ErrorType (org.openkilda.messaging.error.ErrorType)4 SwitchId (org.openkilda.model.SwitchId)4 PathComputer (org.openkilda.pce.PathComputer)4 PersistenceManager (org.openkilda.persistence.PersistenceManager)4 FlowResourcesManager (org.openkilda.wfm.share.flow.resources.FlowResourcesManager)4 FlowOperationsDashboardLogger (org.openkilda.wfm.share.logger.FlowOperationsDashboardLogger)4