Search in sources :

Example 1 with PathSegment

use of org.openkilda.model.PathSegment in project open-kilda by telstra.

the class BaseResourceAllocationAction method createFlowPathPair.

protected FlowPathPair createFlowPathPair(String flowId, FlowResources flowResources, GetPathsResult pathPair, boolean forceToIgnoreBandwidth, String sharedBandwidthGroupId) {
    FlowSegmentCookieBuilder cookieBuilder = FlowSegmentCookie.builder().flowEffectiveId(flowResources.getUnmaskedCookie());
    return transactionManager.doInTransaction(() -> {
        Flow flow = getFlow(flowId);
        updateSwitchRelatedFlowProperties(flow);
        Path forward = pathPair.getForward();
        List<PathSegment> forwardSegments = pathSegmentRepository.findByPathId(flowResources.getForward().getPathId());
        FlowPath newForwardPath = flowPathBuilder.buildFlowPath(flow, flowResources.getForward(), forward.getLatency(), forward.getSrcSwitchId(), forward.getDestSwitchId(), forwardSegments, cookieBuilder.direction(FlowPathDirection.FORWARD).build(), forceToIgnoreBandwidth, sharedBandwidthGroupId);
        newForwardPath.setStatus(FlowPathStatus.IN_PROGRESS);
        Path reverse = pathPair.getReverse();
        List<PathSegment> reverseSegments = pathSegmentRepository.findByPathId(flowResources.getReverse().getPathId());
        FlowPath newReversePath = flowPathBuilder.buildFlowPath(flow, flowResources.getReverse(), reverse.getLatency(), reverse.getSrcSwitchId(), reverse.getDestSwitchId(), reverseSegments, cookieBuilder.direction(FlowPathDirection.REVERSE).build(), forceToIgnoreBandwidth, sharedBandwidthGroupId);
        newReversePath.setStatus(FlowPathStatus.IN_PROGRESS);
        log.debug("Persisting the paths {}/{}", newForwardPath, newReversePath);
        flowPathRepository.add(newForwardPath);
        flowPathRepository.add(newReversePath);
        flow.addPaths(newForwardPath, newReversePath);
        return FlowPathPair.builder().forward(newForwardPath).reverse(newReversePath).build();
    });
}
Also used : FlowPath(org.openkilda.model.FlowPath) Path(org.openkilda.pce.Path) FlowSegmentCookieBuilder(org.openkilda.model.cookie.FlowSegmentCookie.FlowSegmentCookieBuilder) PathSegment(org.openkilda.model.PathSegment) FlowPath(org.openkilda.model.FlowPath) Flow(org.openkilda.model.Flow)

Example 2 with PathSegment

use of org.openkilda.model.PathSegment 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 3 with PathSegment

use of org.openkilda.model.PathSegment in project open-kilda by telstra.

the class ResourcesDeallocationAction method perform.

@Override
protected void perform(State from, State to, Event event, FlowCreateContext context, FlowCreateFsm stateMachine) {
    try {
        transactionManager.doInTransaction(() -> {
            Flow flow = getFlow(stateMachine.getFlowId());
            flow.resetPaths();
        });
    } catch (FlowProcessingException e) {
        stateMachine.saveActionToHistory("Skip resources deallocation", format("Skip resources deallocation. Flow %s has already been deleted: %s", stateMachine.getFlowId(), e.getMessage()));
        return;
    }
    Collection<FlowResources> flowResources = stateMachine.getFlowResources();
    for (FlowResources resources : flowResources) {
        List<PathSegment> removedSegments = new ArrayList<>();
        Stream.of(resources.getForward().getPathId(), resources.getReverse().getPathId()).forEach(pathId -> flowPathRepository.remove(pathId).ifPresent(path -> removedSegments.addAll(path.getSegments())));
        updateIslsForSegments(removedSegments);
        transactionManager.doInTransaction(() -> resourcesManager.deallocatePathResources(resources));
    }
    if (!stateMachine.isPathsBeenAllocated()) {
        flowRepository.remove(stateMachine.getFlowId());
    }
    stateMachine.saveActionToHistory("The resources have been deallocated");
}
Also used : PathSegment(org.openkilda.model.PathSegment) FlowProcessingWithHistorySupportAction(org.openkilda.wfm.topology.flowhs.fsm.common.actions.FlowProcessingWithHistorySupportAction) Event(org.openkilda.wfm.topology.flowhs.fsm.create.FlowCreateFsm.Event) Collection(java.util.Collection) FlowCreateFsm(org.openkilda.wfm.topology.flowhs.fsm.create.FlowCreateFsm) FlowResources(org.openkilda.wfm.share.flow.resources.FlowResources) String.format(java.lang.String.format) ArrayList(java.util.ArrayList) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) Slf4j(lombok.extern.slf4j.Slf4j) List(java.util.List) Stream(java.util.stream.Stream) Flow(org.openkilda.model.Flow) State(org.openkilda.wfm.topology.flowhs.fsm.create.FlowCreateFsm.State) IslRepository(org.openkilda.persistence.repositories.IslRepository) FlowCreateContext(org.openkilda.wfm.topology.flowhs.fsm.create.FlowCreateContext) FlowResourcesManager(org.openkilda.wfm.share.flow.resources.FlowResourcesManager) PersistenceManager(org.openkilda.persistence.PersistenceManager) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) FlowResources(org.openkilda.wfm.share.flow.resources.FlowResources) ArrayList(java.util.ArrayList) PathSegment(org.openkilda.model.PathSegment) Flow(org.openkilda.model.Flow)

Example 4 with PathSegment

use of org.openkilda.model.PathSegment in project open-kilda by telstra.

the class OnSubFlowAllocatedAction method buildRerouteResponseMessage.

private Message buildRerouteResponseMessage(YFlowRerouteFsm stateMachine) {
    String yFlowId = stateMachine.getYFlowId();
    List<Long> oldFlowPathCookies = stateMachine.getOldYFlowPathCookies();
    List<FlowPath> flowPaths = transactionManager.doInTransaction(() -> {
        YFlow yflow = yFlowRepository.findById(yFlowId).orElseThrow(() -> new FlowProcessingException(ErrorType.NOT_FOUND, format("Y-flow %s not found", yFlowId)));
        SwitchId sharedSwitchId = yflow.getSharedEndpoint().getSwitchId();
        List<FlowPath> paths = new ArrayList<>();
        for (YSubFlow subFlow : yflow.getSubFlows()) {
            Flow flow = subFlow.getFlow();
            FlowPath flowPath = flow.getPaths().stream().filter(path -> sharedSwitchId.equals(path.getSrcSwitchId()) && !path.isProtected() && !oldFlowPathCookies.contains(path.getCookie().getValue())).findFirst().orElse(sharedSwitchId.equals(flow.getForwardPath().getSrcSwitchId()) ? flow.getForwardPath() : flow.getReversePath());
            paths.add(flowPath);
        }
        return paths;
    });
    List<PathSegment> sharedPathSegments = IntersectionComputer.calculatePathIntersectionFromSource(flowPaths);
    PathInfoData sharedPath = FlowPathMapper.INSTANCE.map(sharedPathSegments);
    List<SubFlowPathDto> subFlowPathDtos = flowPaths.stream().map(flowPath -> new SubFlowPathDto(flowPath.getFlowId(), FlowPathMapper.INSTANCE.map(flowPath))).sorted(Comparator.comparing(SubFlowPathDto::getFlowId)).collect(Collectors.toList());
    PathInfoData oldSharedPath = stateMachine.getOldSharedPath();
    List<SubFlowPathDto> oldSubFlowPathDtos = stateMachine.getOldSubFlowPathDtos();
    YFlowRerouteResponse response = new YFlowRerouteResponse(sharedPath, subFlowPathDtos, !(sharedPath.equals(oldSharedPath) && subFlowPathDtos.equals(oldSubFlowPathDtos)));
    CommandContext commandContext = stateMachine.getCommandContext();
    return new InfoMessage(response, commandContext.getCreateTime(), commandContext.getCorrelationId());
}
Also used : YFlow(org.openkilda.model.YFlow) CommandContext(org.openkilda.wfm.CommandContext) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) ArrayList(java.util.ArrayList) SwitchId(org.openkilda.model.SwitchId) PathSegment(org.openkilda.model.PathSegment) YSubFlow(org.openkilda.model.YSubFlow) Flow(org.openkilda.model.Flow) YFlow(org.openkilda.model.YFlow) YSubFlow(org.openkilda.model.YSubFlow) PathInfoData(org.openkilda.messaging.info.event.PathInfoData) YFlowRerouteResponse(org.openkilda.messaging.command.yflow.YFlowRerouteResponse) InfoMessage(org.openkilda.messaging.info.InfoMessage) FlowPath(org.openkilda.model.FlowPath) SubFlowPathDto(org.openkilda.messaging.command.yflow.SubFlowPathDto)

Example 5 with PathSegment

use of org.openkilda.model.PathSegment in project open-kilda by telstra.

the class YFlowReadService method getYFlowPaths.

/**
 * Gets y-flow paths.
 */
public YFlowPathsResponse getYFlowPaths(@NonNull String yFlowId) throws FlowNotFoundException {
    return transactionManager.doInTransaction(getReadOperationRetryPolicy(), () -> {
        Set<YSubFlow> subFlows = yFlowRepository.findById(yFlowId).orElseThrow(() -> new FlowNotFoundException(yFlowId)).getSubFlows();
        Set<FlowPath> mainPaths = new HashSet<>();
        Set<FlowPath> protectedPaths = new HashSet<>();
        for (YSubFlow subFlow : subFlows) {
            Flow flow = subFlow.getFlow();
            mainPaths.add(flow.getForwardPath());
            if (flow.isAllocateProtectedPath() && flow.getProtectedForwardPath() != null) {
                protectedPaths.add(flow.getProtectedForwardPath());
            }
        }
        List<PathSegment> sharedPathSegments = IntersectionComputer.calculatePathIntersectionFromSource(mainPaths);
        PathInfoData sharedPath = FlowPathMapper.INSTANCE.map(sharedPathSegments);
        PathInfoData sharedProtectedPath;
        // At least 2 paths required to calculate Y-point.
        if (protectedPaths.size() < 2) {
            sharedProtectedPath = new PathInfoData();
        } else {
            List<PathSegment> pathSegments = IntersectionComputer.calculatePathIntersectionFromSource(protectedPaths);
            sharedProtectedPath = FlowPathMapper.INSTANCE.map(pathSegments);
        }
        List<SubFlowPathDto> subFlowPathDtos = mainPaths.stream().map(flowPath -> new SubFlowPathDto(flowPath.getFlowId(), FlowPathMapper.INSTANCE.map(flowPath))).collect(Collectors.toList());
        List<SubFlowPathDto> subFlowProtectedPathDtos = protectedPaths.stream().map(flowPath -> new SubFlowPathDto(flowPath.getFlowId(), FlowPathMapper.INSTANCE.map(flowPath))).collect(Collectors.toList());
        return new YFlowPathsResponse(sharedPath, subFlowPathDtos, sharedProtectedPath, subFlowProtectedPathDtos);
    });
}
Also used : TransactionManager(org.openkilda.persistence.tx.TransactionManager) PathSegment(org.openkilda.model.PathSegment) FlowPath(org.openkilda.model.FlowPath) SubFlowDto(org.openkilda.messaging.command.yflow.SubFlowDto) YFlowResponse(org.openkilda.messaging.command.yflow.YFlowResponse) FlowPathMapper(org.openkilda.wfm.share.mappers.FlowPathMapper) YFlowDto(org.openkilda.messaging.command.yflow.YFlowDto) PathInfoData(org.openkilda.messaging.info.event.PathInfoData) HashSet(java.util.HashSet) Flow(org.openkilda.model.Flow) IntersectionComputer(org.openkilda.wfm.share.service.IntersectionComputer) Duration(java.time.Duration) SubFlowsResponse(org.openkilda.messaging.command.yflow.SubFlowsResponse) YFlow(org.openkilda.model.YFlow) FlowRepository(org.openkilda.persistence.repositories.FlowRepository) PersistenceManager(org.openkilda.persistence.PersistenceManager) YFlowPathsResponse(org.openkilda.messaging.command.yflow.YFlowPathsResponse) FlowNotFoundException(org.openkilda.wfm.error.FlowNotFoundException) YSubFlow(org.openkilda.model.YSubFlow) ErrorType(org.openkilda.messaging.error.ErrorType) NonNull(lombok.NonNull) Collection(java.util.Collection) Set(java.util.Set) RetryPolicy(net.jodah.failsafe.RetryPolicy) PersistenceException(org.openkilda.persistence.exceptions.PersistenceException) Collectors(java.util.stream.Collectors) YFlowRepository(org.openkilda.persistence.repositories.YFlowRepository) YFlowMapper(org.openkilda.wfm.topology.flowhs.mapper.YFlowMapper) Objects(java.util.Objects) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) Slf4j(lombok.extern.slf4j.Slf4j) List(java.util.List) SubFlowPathDto(org.openkilda.messaging.command.yflow.SubFlowPathDto) Collections(java.util.Collections) FlowNotFoundException(org.openkilda.wfm.error.FlowNotFoundException) PathSegment(org.openkilda.model.PathSegment) YSubFlow(org.openkilda.model.YSubFlow) Flow(org.openkilda.model.Flow) YFlow(org.openkilda.model.YFlow) YSubFlow(org.openkilda.model.YSubFlow) PathInfoData(org.openkilda.messaging.info.event.PathInfoData) FlowPath(org.openkilda.model.FlowPath) HashSet(java.util.HashSet) SubFlowPathDto(org.openkilda.messaging.command.yflow.SubFlowPathDto) YFlowPathsResponse(org.openkilda.messaging.command.yflow.YFlowPathsResponse)

Aggregations

PathSegment (org.openkilda.model.PathSegment)73 FlowPath (org.openkilda.model.FlowPath)40 ArrayList (java.util.ArrayList)28 Flow (org.openkilda.model.Flow)26 PathId (org.openkilda.model.PathId)24 SwitchId (org.openkilda.model.SwitchId)18 FlowSegmentCookie (org.openkilda.model.cookie.FlowSegmentCookie)17 FlowEndpoint (org.openkilda.model.FlowEndpoint)12 Test (org.junit.Test)11 List (java.util.List)9 MeterId (org.openkilda.model.MeterId)9 Switch (org.openkilda.model.Switch)9 YFlow (org.openkilda.model.YFlow)8 PersistenceManager (org.openkilda.persistence.PersistenceManager)7 Optional (java.util.Optional)6 Slf4j (lombok.extern.slf4j.Slf4j)6 VisibleForTesting (com.google.common.annotations.VisibleForTesting)5 Set (java.util.Set)5 Collectors (java.util.stream.Collectors)5 PathInfoData (org.openkilda.messaging.info.event.PathInfoData)5