Search in sources :

Example 11 with YSubFlow

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

the class FlowFetcher method handleOnDemandYFlowRequest.

private void handleOnDemandYFlowRequest(Tuple input) throws PipelineException {
    log.debug("Handle on demand ping request");
    YFlowPingRequest request = pullOnDemandYFlowRequest(input);
    Optional<YFlow> optionalYFlow = yFlowRepository.findById(request.getYFlowId());
    if (!optionalYFlow.isPresent()) {
        emitOnDemandYFlowResponse(input, request, format("YFlow %s does not exist", request.getYFlowId()));
        return;
    }
    YFlow yFlow = optionalYFlow.get();
    Set<YSubFlow> subFlows = yFlow.getSubFlows();
    if (subFlows.isEmpty()) {
        emitOnDemandYFlowResponse(input, request, format("YFlow %s has no sub flows", request.getYFlowId()));
        return;
    }
    GroupId groupId = new GroupId(subFlows.size() * DIRECTION_COUNT_PER_FLOW);
    List<PingContext> subFlowPingRequests = new ArrayList<>();
    for (YSubFlow subFlow : subFlows) {
        Flow flow = subFlow.getFlow();
        // Load paths to use in PingProducer
        flow.getPaths();
        flowRepository.detach(flow);
        Optional<FlowTransitEncapsulation> transitEncapsulation = getTransitEncapsulation(flow);
        if (transitEncapsulation.isPresent()) {
            subFlowPingRequests.add(PingContext.builder().group(groupId).kind(Kinds.ON_DEMAND_Y_FLOW).flow(flow).yFlowId(yFlow.getYFlowId()).transitEncapsulation(transitEncapsulation.get()).timeout(request.getTimeout()).build());
        } else {
            emitOnDemandYFlowResponse(input, request, format("Encapsulation resource not found for sub flow %s of YFlow %s", subFlow.getSubFlowId(), yFlow.getYFlowId()));
            return;
        }
    }
    CommandContext commandContext = pullContext(input);
    for (PingContext pingContext : subFlowPingRequests) {
        emit(input, pingContext, commandContext);
    }
}
Also used : YFlow(org.openkilda.model.YFlow) CommandContext(org.openkilda.wfm.CommandContext) ArrayList(java.util.ArrayList) FlowTransitEncapsulation(org.openkilda.model.FlowTransitEncapsulation) YSubFlow(org.openkilda.model.YSubFlow) GroupId(org.openkilda.wfm.topology.ping.model.GroupId) Flow(org.openkilda.model.Flow) YFlow(org.openkilda.model.YFlow) YSubFlow(org.openkilda.model.YSubFlow) PingContext(org.openkilda.wfm.topology.ping.model.PingContext) YFlowPingRequest(org.openkilda.messaging.command.flow.YFlowPingRequest)

Example 12 with YSubFlow

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

the class TestYFlowBuilder method build.

/**
 * Build {@link YFlow} instance.
 */
public YFlow build() {
    boolean allocateProtectedPath = false;
    if (protectedPathYPoint != null || protectedPathMeterId != null) {
        checkArgument(protectedPathYPoint != null && protectedPathMeterId != null, "Insufficient data provided to make YFlow with protected path");
        allocateProtectedPath = true;
    }
    YFlow.YFlowBuilder yFlowBuilder = YFlow.builder().yFlowId(yFlowId).sharedEndpoint(sharedEndpoint).sharedEndpointMeterId(sharedEndpointMeterId).yPoint(yPoint).meterId(meterId).allocateProtectedPath(allocateProtectedPath).maximumBandwidth(maximumBandwidth).ignoreBandwidth(ignoreBandwidth).strictBandwidth(strictBandwidth).description(description).periodicPings(periodicPings).encapsulationType(encapsulationType).status(status).maxLatency(maxLatency).maxLatencyTier2(maxLatencyTier2).priority(priority).pinned(pinned).pathComputationStrategy(pathComputationStrategy);
    if (allocateProtectedPath) {
        yFlowBuilder = yFlowBuilder.protectedPathYPoint(protectedPathYPoint).protectedPathMeterId(protectedPathMeterId);
    }
    YFlow yFlow = yFlowBuilder.build();
    Set<YSubFlow> subFlowsGoal = new HashSet<>();
    for (TestYSubFlowBuilder subFlowBuilder : subFlows) {
        subFlowsGoal.add(subFlowBuilder.yFlow(yFlow).build());
    }
    yFlow.setSubFlows(subFlowsGoal);
    yFlow.setTimeCreate(timeCreate);
    yFlow.setTimeModify(timeModify);
    return yFlow;
}
Also used : YFlow(org.openkilda.model.YFlow) YSubFlow(org.openkilda.model.YSubFlow) HashSet(java.util.HashSet)

Example 13 with YSubFlow

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

the class ValidateYFlowAction method performWithResponse.

@Override
protected Optional<Message> performWithResponse(State from, State to, Event event, YFlowUpdateContext context, YFlowUpdateFsm stateMachine) {
    YFlowRequest targetFlow = context.getTargetFlow();
    boolean isOperationAllowed = featureTogglesRepository.getOrDefault().getModifyYFlowEnabled();
    if (!isOperationAllowed) {
        throw new FlowProcessingException(ErrorType.NOT_PERMITTED, "Y-flow create feature is disabled");
    }
    try {
        yFlowValidator.validate(targetFlow);
    } catch (InvalidFlowException e) {
        throw new FlowProcessingException(e.getType(), e.getMessage(), e);
    } catch (UnavailableFlowEndpointException e) {
        throw new FlowProcessingException(ErrorType.DATA_INVALID, e.getMessage(), e);
    }
    String yFlowId = targetFlow.getYFlowId();
    YFlow yFlow = transactionManager.doInTransaction(() -> {
        YFlow result = yFlowRepository.findById(yFlowId).orElseThrow(() -> new FlowProcessingException(ErrorType.NOT_FOUND, format("Y-flow %s not found", yFlowId)));
        if (result.getStatus() == FlowStatus.IN_PROGRESS) {
            throw new FlowProcessingException(ErrorType.REQUEST_INVALID, format("Y-flow %s is in progress now", yFlowId));
        }
        // Keep it, just in case we have to revert it.
        stateMachine.setOriginalYFlowStatus(result.getStatus());
        result.setStatus(FlowStatus.IN_PROGRESS);
        return result;
    });
    Set<String> requestedSubFlowIds = targetFlow.getSubFlows().stream().map(SubFlowDto::getFlowId).collect(Collectors.toSet());
    Set<String> originalSubFlowIds = yFlow.getSubFlows().stream().map(YSubFlow::getSubFlowId).collect(Collectors.toSet());
    if (!requestedSubFlowIds.equals(originalSubFlowIds)) {
        throw new FlowProcessingException(ErrorType.PARAMETERS_INVALID, format("Unable to map provided sub-flows set onto existing y-flow %s", yFlowId));
    }
    YSubFlow subFlow = yFlow.getSubFlows().stream().findAny().orElseThrow(() -> new FlowProcessingException(ErrorType.DATA_INVALID, format("No sub-flows of the y-flow %s were found", yFlowId)));
    stateMachine.setMainAffinityFlowId(subFlow.getFlow().getAffinityGroupId());
    List<FlowEndpoint> subFlowEndpoints = targetFlow.getSubFlows().stream().map(SubFlowDto::getEndpoint).collect(Collectors.toList());
    dashboardLogger.onYFlowUpdate(yFlowId, targetFlow.getSharedEndpoint(), subFlowEndpoints, targetFlow.getMaximumBandwidth());
    stateMachine.setTargetFlow(targetFlow);
    stateMachine.saveNewEventToHistory("Y-flow was validated successfully", FlowEventData.Event.UPDATE);
    return Optional.empty();
}
Also used : UnavailableFlowEndpointException(org.openkilda.wfm.topology.flowhs.validation.UnavailableFlowEndpointException) YFlow(org.openkilda.model.YFlow) FlowEndpoint(org.openkilda.model.FlowEndpoint) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) InvalidFlowException(org.openkilda.wfm.topology.flowhs.validation.InvalidFlowException) YFlowRequest(org.openkilda.messaging.command.yflow.YFlowRequest) YSubFlow(org.openkilda.model.YSubFlow)

Example 14 with YSubFlow

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

the class YFlowValidationService method validateYFlowResources.

/**
 * Validate y-flow.
 */
public YFlowDiscrepancyDto validateYFlowResources(String yFlowId, List<SwitchFlowEntries> actualSwitchFlowEntries, List<SwitchMeterEntries> actualSwitchMeterEntries) throws FlowNotFoundException, SwitchNotFoundException {
    Map<SwitchId, List<SimpleSwitchRule>> actualRules = new HashMap<>();
    for (SwitchFlowEntries switchRulesEntries : actualSwitchFlowEntries) {
        SwitchMeterEntries switchMeters = actualSwitchMeterEntries.stream().filter(meterEntries -> switchRulesEntries.getSwitchId().equals(meterEntries.getSwitchId())).findFirst().orElse(null);
        List<SimpleSwitchRule> simpleSwitchRules = simpleSwitchRuleConverter.convertSwitchFlowEntriesToSimpleSwitchRules(switchRulesEntries, switchMeters, null);
        actualRules.put(switchRulesEntries.getSwitchId(), simpleSwitchRules);
    }
    YFlow yFlow = yFlowRepository.findById(yFlowId).orElseThrow(() -> new FlowNotFoundException(yFlowId));
    List<SimpleSwitchRule> expectedRules = new ArrayList<>();
    for (YSubFlow subFlow : yFlow.getSubFlows()) {
        Flow flow = subFlow.getFlow();
        expectedRules.addAll(buildSimpleSwitchRules(flow, yFlow.getSharedEndpoint().getSwitchId(), yFlow.getSharedEndpointMeterId(), flow.getForwardPathId(), flow.getReversePathId(), yFlow.getYPoint(), yFlow.getMeterId()));
        if (flow.isAllocateProtectedPath()) {
            if (flow.getProtectedForwardPathId() != null && flow.getProtectedReversePathId() != null) {
                expectedRules.addAll(buildSimpleSwitchRules(flow, yFlow.getSharedEndpoint().getSwitchId(), yFlow.getSharedEndpointMeterId(), flow.getProtectedForwardPathId(), flow.getProtectedReversePathId(), yFlow.getProtectedPathYPoint(), yFlow.getProtectedPathMeterId()));
            } else {
                log.warn("Sub-flow {} of y-flow {} has no expected protected paths", flow.getFlowId(), yFlowId);
            }
        }
    }
    List<PathDiscrepancyEntity> discrepancies = new ArrayList<>();
    for (SimpleSwitchRule simpleRule : expectedRules) {
        discrepancies.addAll(simpleSwitchRuleComparator.findDiscrepancy(simpleRule, actualRules.get(simpleRule.getSwitchId())));
    }
    return YFlowDiscrepancyDto.builder().discrepancies(discrepancies).asExpected(discrepancies.isEmpty()).build();
}
Also used : YFlow(org.openkilda.model.YFlow) FlowNotFoundException(org.openkilda.wfm.error.FlowNotFoundException) SwitchFlowEntries(org.openkilda.messaging.info.rule.SwitchFlowEntries) HashMap(java.util.HashMap) SwitchMeterEntries(org.openkilda.messaging.info.meter.SwitchMeterEntries) ArrayList(java.util.ArrayList) PathDiscrepancyEntity(org.openkilda.messaging.info.flow.PathDiscrepancyEntity) SwitchId(org.openkilda.model.SwitchId) YSubFlow(org.openkilda.model.YSubFlow) Flow(org.openkilda.model.Flow) YFlow(org.openkilda.model.YFlow) YSubFlow(org.openkilda.model.YSubFlow) SimpleSwitchRule(org.openkilda.wfm.share.utils.rule.validation.SimpleSwitchRule) ArrayList(java.util.ArrayList) List(java.util.List)

Example 15 with YSubFlow

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

the class StartReroutingYFlowAction method perform.

@Override
protected void perform(State from, State to, Event event, YFlowRerouteContext context, YFlowRerouteFsm stateMachine) {
    String yFlowId = stateMachine.getYFlowId();
    List<FlowPath> flowPaths = transactionManager.doInTransaction(() -> {
        YFlow yFlow = getYFlow(yFlowId);
        saveOldResources(stateMachine, yFlow);
        stateMachine.setDeleteOldYFlowCommands(buildYFlowDeleteCommands(yFlow, stateMachine.getCommandContext()));
        SwitchId sharedSwitchId = yFlow.getSharedEndpoint().getSwitchId();
        return yFlow.getSubFlows().stream().map(YSubFlow::getFlow).flatMap(flow -> Stream.of(flow.getForwardPath(), flow.getReversePath())).filter(path -> sharedSwitchId.equals(path.getSrcSwitchId())).collect(Collectors.toList());
    });
    stateMachine.setOldYFlowPathCookies(flowPaths.stream().map(FlowPath::getCookie).map(FlowSegmentCookie::getValue).collect(Collectors.toList()));
    List<PathSegment> sharedPathSegments = IntersectionComputer.calculatePathIntersectionFromSource(flowPaths);
    PathInfoData sharedPath = FlowPathMapper.INSTANCE.map(sharedPathSegments);
    stateMachine.setOldSharedPath(sharedPath);
    List<SubFlowPathDto> subFlowPathDtos = flowPaths.stream().map(flowPath -> new SubFlowPathDto(flowPath.getFlowId(), FlowPathMapper.INSTANCE.map(flowPath))).sorted(Comparator.comparing(SubFlowPathDto::getFlowId)).collect(Collectors.toList());
    stateMachine.setOldSubFlowPathDtos(subFlowPathDtos);
}
Also used : YFlow(org.openkilda.model.YFlow) EndpointResources(org.openkilda.wfm.topology.flowhs.model.yflow.YFlowResources.EndpointResources) PathSegment(org.openkilda.model.PathSegment) YSubFlow(org.openkilda.model.YSubFlow) FlowPath(org.openkilda.model.FlowPath) State(org.openkilda.wfm.topology.flowhs.fsm.yflow.reroute.YFlowRerouteFsm.State) YFlowResources(org.openkilda.wfm.topology.flowhs.model.yflow.YFlowResources) FlowPathMapper(org.openkilda.wfm.share.mappers.FlowPathMapper) YFlowRuleManagerProcessingAction(org.openkilda.wfm.topology.flowhs.fsm.common.actions.YFlowRuleManagerProcessingAction) Collectors(java.util.stream.Collectors) PathInfoData(org.openkilda.messaging.info.event.PathInfoData) RuleManager(org.openkilda.rulemanager.RuleManager) YFlowRerouteContext(org.openkilda.wfm.topology.flowhs.fsm.yflow.reroute.YFlowRerouteContext) Slf4j(lombok.extern.slf4j.Slf4j) List(java.util.List) Stream(java.util.stream.Stream) SwitchId(org.openkilda.model.SwitchId) IntersectionComputer(org.openkilda.wfm.share.service.IntersectionComputer) SubFlowPathDto(org.openkilda.messaging.command.yflow.SubFlowPathDto) YFlow(org.openkilda.model.YFlow) Event(org.openkilda.wfm.topology.flowhs.fsm.yflow.reroute.YFlowRerouteFsm.Event) FlowSegmentCookie(org.openkilda.model.cookie.FlowSegmentCookie) PersistenceManager(org.openkilda.persistence.PersistenceManager) Comparator(java.util.Comparator) YFlowRerouteFsm(org.openkilda.wfm.topology.flowhs.fsm.yflow.reroute.YFlowRerouteFsm) PathInfoData(org.openkilda.messaging.info.event.PathInfoData) FlowSegmentCookie(org.openkilda.model.cookie.FlowSegmentCookie) SwitchId(org.openkilda.model.SwitchId) PathSegment(org.openkilda.model.PathSegment) FlowPath(org.openkilda.model.FlowPath) SubFlowPathDto(org.openkilda.messaging.command.yflow.SubFlowPathDto)

Aggregations

YSubFlow (org.openkilda.model.YSubFlow)26 YFlow (org.openkilda.model.YFlow)24 Flow (org.openkilda.model.Flow)18 FlowProcessingException (org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException)11 SwitchId (org.openkilda.model.SwitchId)7 ArrayList (java.util.ArrayList)6 FlowEndpoint (org.openkilda.model.FlowEndpoint)6 FlowPath (org.openkilda.model.FlowPath)5 Collection (java.util.Collection)4 HashSet (java.util.HashSet)4 List (java.util.List)4 ErrorType (org.openkilda.messaging.error.ErrorType)4 PathSegment (org.openkilda.model.PathSegment)4 PersistenceManager (org.openkilda.persistence.PersistenceManager)4 CommandContext (org.openkilda.wfm.CommandContext)4 Collectors (java.util.stream.Collectors)3 Slf4j (lombok.extern.slf4j.Slf4j)3 SubFlowDto (org.openkilda.messaging.command.yflow.SubFlowDto)3 SubFlowSharedEndpointEncapsulation (org.openkilda.messaging.command.yflow.SubFlowSharedEndpointEncapsulation)3 String.format (java.lang.String.format)2