Search in sources :

Example 6 with TimedExecution

use of org.openkilda.wfm.share.metrics.TimedExecution in project open-kilda by telstra.

the class LinkOperationsBolt method getAllLinks.

@TimedExecution("link_dump")
private List<IslInfoData> getAllLinks(GetLinksRequest request) {
    Integer srcPort = request.getSource().getPortNumber();
    SwitchId srcSwitch = request.getSource().getDatapath();
    Integer dstPort = request.getDestination().getPortNumber();
    SwitchId dstSwitch = request.getDestination().getDatapath();
    return linkOperationsService.getAllIsls(srcSwitch, srcPort, dstSwitch, dstPort).stream().map(IslMapper.INSTANCE::map).collect(Collectors.toList());
}
Also used : SwitchId(org.openkilda.model.SwitchId) IslMapper(org.openkilda.wfm.share.mappers.IslMapper) TimedExecution(org.openkilda.wfm.share.metrics.TimedExecution)

Example 7 with TimedExecution

use of org.openkilda.wfm.share.metrics.TimedExecution in project open-kilda by telstra.

the class FlowOperationsBolt method processGetFlowsForLinkRequest.

@TimedExecution("get_flows_for_link")
private List<FlowResponse> processGetFlowsForLinkRequest(GetFlowsForIslRequest request) {
    SwitchId srcSwitch = request.getSource().getDatapath();
    Integer srcPort = request.getSource().getPortNumber();
    SwitchId dstSwitch = request.getDestination().getDatapath();
    Integer dstPort = request.getDestination().getPortNumber();
    try {
        return flowOperationsService.getFlowPathsForLink(srcSwitch, srcPort, dstSwitch, dstPort).stream().filter(flowPath -> flowPath.getFlow().isActualPathId(flowPath.getPathId())).map(FlowPath::getFlow).distinct().map(flowOperationsService::buildFlowResponse).collect(Collectors.toList());
    } catch (IslNotFoundException e) {
        throw new MessageException(ErrorType.NOT_FOUND, e.getMessage(), "ISL was not found.");
    }
}
Also used : MessageException(org.openkilda.messaging.error.MessageException) SwitchId(org.openkilda.model.SwitchId) IslNotFoundException(org.openkilda.wfm.error.IslNotFoundException) TimedExecution(org.openkilda.wfm.share.metrics.TimedExecution)

Example 8 with TimedExecution

use of org.openkilda.wfm.share.metrics.TimedExecution in project open-kilda by telstra.

the class RerouteService method rerouteInactiveFlows.

/**
 * Handles reroute on ISL up events.
 *
 * @param sender transport sender
 * @param correlationId correlation id to pass through
 * @param command origin command
 */
@TimedExecution("reroute_inactive_flows")
public void rerouteInactiveFlows(MessageSender sender, String correlationId, RerouteInactiveFlows command) {
    PathNode pathNode = command.getPathNode();
    int port = pathNode.getPortNo();
    SwitchId switchId = pathNode.getSwitchId();
    Map<String, FlowThrottlingData> flowsForReroute = transactionManager.doInTransaction(() -> {
        Map<String, FlowThrottlingData> forReroute = new HashMap<>();
        Map<Flow, Set<PathId>> flowsForRerouting = getInactiveFlowsForRerouting();
        for (Entry<Flow, Set<PathId>> entry : flowsForRerouting.entrySet()) {
            Flow flow = entry.getKey();
            Set<IslEndpoint> allAffectedIslEndpoints = new HashSet<>();
            for (FlowPath flowPath : flow.getPaths()) {
                Set<IslEndpoint> affectedIslEndpoints = new HashSet<>();
                PathSegment firstSegment = null;
                int failedSegmentsCount = 0;
                for (PathSegment pathSegment : flowPath.getSegments()) {
                    if (firstSegment == null) {
                        firstSegment = pathSegment;
                    }
                    if (pathSegment.isFailed()) {
                        affectedIslEndpoints.add(new IslEndpoint(pathSegment.getSrcSwitchId(), pathSegment.getSrcPort()));
                        affectedIslEndpoints.add(new IslEndpoint(pathSegment.getDestSwitchId(), pathSegment.getDestPort()));
                        if (pathSegment.containsNode(switchId, port)) {
                            pathSegment.setFailed(false);
                            pathSegmentRepository.updateFailedStatus(flowPath, pathSegment, false);
                        } else {
                            failedSegmentsCount++;
                        }
                    }
                }
                if (flowPath.getStatus().equals(FlowPathStatus.INACTIVE) && failedSegmentsCount == 0) {
                    updateFlowPathStatus(flowPath, FlowPathStatus.ACTIVE);
                    // force reroute of failed path only (required due to inaccurate path/segment state management)
                    if (affectedIslEndpoints.isEmpty() && firstSegment != null) {
                        affectedIslEndpoints.add(new IslEndpoint(firstSegment.getSrcSwitchId(), firstSegment.getSrcPort()));
                    }
                }
                allAffectedIslEndpoints.addAll(affectedIslEndpoints);
            }
            FlowStatus flowStatus = flow.computeFlowStatus();
            String flowStatusInfo = null;
            if (!FlowStatus.UP.equals(flowStatus)) {
                flowStatusInfo = command.getReason();
            }
            flowRepository.updateStatusSafe(flow, flowStatus, flowStatusInfo);
            if (flow.isPinned()) {
                log.info("Skipping reroute command for pinned flow {}", flow.getFlowId());
            } else if (flow.getYFlow() != null) {
                YFlow yFlow = flow.getYFlow();
                log.info("Create reroute command (attempt to restore inactive flows) request for {} " + "(affected ISL endpoints: {})", yFlow.getYFlowId(), allAffectedIslEndpoints);
                FlowThrottlingData flowThrottlingData = getFlowThrottlingDataBuilder(yFlow).correlationId(correlationId).affectedIsl(allAffectedIslEndpoints).force(false).effectivelyDown(true).reason(command.getReason()).build();
                sender.emitRerouteCommand(yFlow.getYFlowId(), flowThrottlingData);
            } else {
                log.info("Create reroute command (attempt to restore inactive flows) request for {} (affected ISL " + "endpoints: {})", flow.getFlowId(), allAffectedIslEndpoints);
                FlowThrottlingData flowThrottlingData = getFlowThrottlingDataBuilder(flow).correlationId(correlationId).affectedIsl(allAffectedIslEndpoints).force(false).effectivelyDown(true).reason(command.getReason()).build();
                forReroute.put(flow.getFlowId(), flowThrottlingData);
            }
        }
        return forReroute;
    });
    for (Entry<String, FlowThrottlingData> entry : flowsForReroute.entrySet()) {
        log.info("Produce reroute (attempt to restore inactive flows) request for {} (affected ISL endpoints: {})", entry.getKey(), entry.getValue().getAffectedIsl());
        sender.emitRerouteCommand(entry.getKey(), entry.getValue());
    }
}
Also used : YFlow(org.openkilda.model.YFlow) IslEndpoint(org.openkilda.model.IslEndpoint) HashSet(java.util.HashSet) Collectors.toSet(java.util.stream.Collectors.toSet) Set(java.util.Set) HashMap(java.util.HashMap) SwitchId(org.openkilda.model.SwitchId) PathSegment(org.openkilda.model.PathSegment) PathNode(org.openkilda.messaging.info.event.PathNode) IslEndpoint(org.openkilda.model.IslEndpoint) FlowStatus(org.openkilda.model.FlowStatus) Flow(org.openkilda.model.Flow) YFlow(org.openkilda.model.YFlow) FlowThrottlingData(org.openkilda.wfm.topology.reroute.model.FlowThrottlingData) FlowPath(org.openkilda.model.FlowPath) HashSet(java.util.HashSet) TimedExecution(org.openkilda.wfm.share.metrics.TimedExecution)

Example 9 with TimedExecution

use of org.openkilda.wfm.share.metrics.TimedExecution in project open-kilda by telstra.

the class RerouteService method rerouteAffectedFlows.

/**
 * Handles reroute on ISL down events.
 *
 * @param sender transport sender
 * @param correlationId correlation id to pass through
 * @param command origin command
 */
@TimedExecution("reroute_affected_flows")
public void rerouteAffectedFlows(MessageSender sender, String correlationId, RerouteAffectedFlows command) {
    // TODO(surabujin): need better/more detailed representation of failed ISL
    PathNode pathNode = command.getPathNode();
    int port = pathNode.getPortNo();
    SwitchId switchId = pathNode.getSwitchId();
    final IslEndpoint affectedIsl = new IslEndpoint(switchId, port);
    RerouteResult rerouteResult = transactionManager.doInTransaction(() -> {
        RerouteResult result = new RerouteResult();
        Collection<FlowPath> affectedFlowPaths = getAffectedFlowPaths(pathNode.getSwitchId(), pathNode.getPortNo());
        // swapping affected primary paths with available protected
        List<FlowPath> pathsForSwapping = getPathsForSwapping(affectedFlowPaths);
        for (FlowPath path : pathsForSwapping) {
            result.flowIdsForSwapPaths.add(path.getFlowId());
        }
        for (FlowWithAffectedPaths entry : groupPathsForRerouting(affectedFlowPaths)) {
            Flow flow = entry.getFlow();
            boolean rerouteRequired = updateFlowPathsStateForFlow(switchId, port, entry.getAffectedPaths());
            FlowStatus flowStatus = flow.computeFlowStatus();
            String flowStatusInfo = null;
            if (!FlowStatus.UP.equals(flowStatus)) {
                flowStatusInfo = command.getReason();
            }
            flowRepository.updateStatusSafe(flow, flowStatus, flowStatusInfo);
            if (rerouteRequired) {
                if (flow.getYFlow() != null) {
                    result.yFlowsForReroute.add(flow.getYFlow());
                } else {
                    result.flowsForReroute.add(flow);
                }
            }
        }
        Set<Flow> affectedPinnedFlows = groupAffectedPinnedFlows(affectedFlowPaths);
        for (Flow flow : affectedPinnedFlows) {
            List<FlowPath> flowPaths = new ArrayList<>(flow.getPaths());
            updateFlowPathsStateForFlow(switchId, port, flowPaths);
            if (flow.getStatus() != FlowStatus.DOWN) {
                flowDashboardLogger.onFlowStatusUpdate(flow.getFlowId(), FlowStatus.DOWN);
                flowRepository.updateStatusSafe(flow, FlowStatus.DOWN, command.getReason());
            }
        }
        return result;
    });
    for (String flowId : rerouteResult.flowIdsForSwapPaths) {
        sender.emitPathSwapCommand(correlationId, flowId, command.getReason());
    }
    for (Flow flow : rerouteResult.flowsForReroute) {
        FlowThrottlingData flowThrottlingData = getFlowThrottlingDataBuilder(flow).correlationId(correlationId).affectedIsl(Collections.singleton(affectedIsl)).force(false).effectivelyDown(true).reason(command.getReason()).build();
        sender.emitRerouteCommand(flow.getFlowId(), flowThrottlingData);
    }
    for (YFlow yFlow : rerouteResult.yFlowsForReroute) {
        FlowThrottlingData flowThrottlingData = getFlowThrottlingDataBuilder(yFlow).correlationId(correlationId).affectedIsl(Collections.singleton(affectedIsl)).force(false).effectivelyDown(true).reason(command.getReason()).build();
        sender.emitRerouteCommand(yFlow.getYFlowId(), flowThrottlingData);
    }
}
Also used : YFlow(org.openkilda.model.YFlow) IslEndpoint(org.openkilda.model.IslEndpoint) ArrayList(java.util.ArrayList) SwitchId(org.openkilda.model.SwitchId) PathNode(org.openkilda.messaging.info.event.PathNode) IslEndpoint(org.openkilda.model.IslEndpoint) FlowStatus(org.openkilda.model.FlowStatus) Flow(org.openkilda.model.Flow) YFlow(org.openkilda.model.YFlow) FlowThrottlingData(org.openkilda.wfm.topology.reroute.model.FlowThrottlingData) FlowPath(org.openkilda.model.FlowPath) TimedExecution(org.openkilda.wfm.share.metrics.TimedExecution)

Example 10 with TimedExecution

use of org.openkilda.wfm.share.metrics.TimedExecution in project open-kilda by telstra.

the class RemoveOldRulesAction method perform.

@TimedExecution("fsm.remove_old_rules")
@Override
protected void perform(State from, State to, Event event, FlowRerouteContext context, FlowRerouteFsm stateMachine) {
    FlowEncapsulationType encapsulationType = stateMachine.getOriginalEncapsulationType();
    FlowCommandBuilder commandBuilder = commandBuilderFactory.getBuilder(encapsulationType);
    Collection<FlowSegmentRequestFactory> factories = new ArrayList<>();
    Flow originalFlow = getOriginalFlowWithPaths(stateMachine, stateMachine.getOriginalFlow());
    SpeakerRequestBuildContext speakerContext = SpeakerRequestBuildContext.getEmpty();
    MirrorContext mirrorContext = MirrorContext.builder().removeFlowOperation(true).build();
    if (stateMachine.getOldPrimaryForwardPath() != null) {
        FlowPath oldForward = getFlowPath(stateMachine.getOldPrimaryForwardPath());
        speakerContext.setForward(buildPathContextForRemovalIngressOnly(oldForward.getSrcSwitchId()));
        if (stateMachine.getOldPrimaryReversePath() != null) {
            FlowPath oldReverse = getFlowPath(stateMachine.getOldPrimaryReversePath());
            speakerContext.setReverse(buildPathContextForRemovalIngressOnly(oldReverse.getSrcSwitchId()));
            factories.addAll(commandBuilder.buildAll(stateMachine.getCommandContext(), originalFlow, oldForward, oldReverse, speakerContext, mirrorContext));
        } else {
            factories.addAll(commandBuilder.buildAll(stateMachine.getCommandContext(), originalFlow, oldForward, speakerContext, mirrorContext));
        }
    } else if (stateMachine.getOldPrimaryReversePath() != null) {
        FlowPath oldReverse = getFlowPath(stateMachine.getOldPrimaryReversePath());
        speakerContext.setForward(buildPathContextForRemovalIngressOnly(oldReverse.getSrcSwitchId()));
        factories.addAll(commandBuilder.buildAll(stateMachine.getCommandContext(), originalFlow, oldReverse, speakerContext, mirrorContext));
    }
    if (stateMachine.getOldProtectedForwardPath() != null) {
        FlowPath oldForward = getFlowPath(stateMachine.getOldProtectedForwardPath());
        if (stateMachine.getOldProtectedReversePath() != null) {
            FlowPath oldReverse = getFlowPath(stateMachine.getOldProtectedReversePath());
            factories.addAll(commandBuilder.buildAllExceptIngress(stateMachine.getCommandContext(), originalFlow, oldForward, oldReverse, mirrorContext));
        } else {
            factories.addAll(commandBuilder.buildAllExceptIngress(stateMachine.getCommandContext(), originalFlow, oldForward, mirrorContext));
        }
    } else if (stateMachine.getOldProtectedReversePath() != null) {
        FlowPath oldReverse = getFlowPath(stateMachine.getOldProtectedReversePath());
        factories.addAll(commandBuilder.buildAllExceptIngress(stateMachine.getCommandContext(), originalFlow, oldReverse, mirrorContext));
    }
    stateMachine.clearPendingAndRetriedAndFailedCommands();
    if (factories.isEmpty()) {
        stateMachine.saveActionToHistory("No need to remove old rules");
        stateMachine.fire(Event.RULES_REMOVED);
    } else {
        Map<UUID, FlowSegmentRequestFactory> requestsStorage = stateMachine.getRemoveCommands();
        for (FlowSegmentRequestFactory factory : factories) {
            FlowSegmentRequest request = factory.makeRemoveRequest(commandIdGenerator.generate());
            // TODO ensure no conflicts
            requestsStorage.put(request.getCommandId(), factory);
            stateMachine.getCarrier().sendSpeakerRequest(request);
        }
        requestsStorage.forEach((key, value) -> stateMachine.addPendingCommand(key, value.getSwitchId()));
        stateMachine.saveActionToHistory("Remove commands for old rules have been sent");
    }
}
Also used : FlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.FlowSegmentRequestFactory) MirrorContext(org.openkilda.wfm.share.model.MirrorContext) FlowSegmentRequest(org.openkilda.floodlight.api.request.FlowSegmentRequest) ArrayList(java.util.ArrayList) FlowCommandBuilder(org.openkilda.wfm.topology.flowhs.service.FlowCommandBuilder) FlowEncapsulationType(org.openkilda.model.FlowEncapsulationType) SpeakerRequestBuildContext(org.openkilda.wfm.share.model.SpeakerRequestBuildContext) FlowPath(org.openkilda.model.FlowPath) UUID(java.util.UUID) Flow(org.openkilda.model.Flow) TimedExecution(org.openkilda.wfm.share.metrics.TimedExecution)

Aggregations

TimedExecution (org.openkilda.wfm.share.metrics.TimedExecution)16 Flow (org.openkilda.model.Flow)11 SwitchId (org.openkilda.model.SwitchId)6 FlowPath (org.openkilda.model.FlowPath)5 MessageException (org.openkilda.messaging.error.MessageException)4 IslEndpoint (org.openkilda.model.IslEndpoint)4 HashSet (java.util.HashSet)3 FlowStatus (org.openkilda.model.FlowStatus)3 PathId (org.openkilda.model.PathId)3 IslNotFoundException (org.openkilda.wfm.error.IslNotFoundException)3 ArrayList (java.util.ArrayList)2 List (java.util.List)2 PathNode (org.openkilda.messaging.info.event.PathNode)2 YFlow (org.openkilda.model.YFlow)2 GetPathsResult (org.openkilda.pce.GetPathsResult)2 PersistenceManager (org.openkilda.persistence.PersistenceManager)2 SwitchNotFoundException (org.openkilda.wfm.error.SwitchNotFoundException)2 FlowResources (org.openkilda.wfm.share.flow.resources.FlowResources)2 FlowPathPair (org.openkilda.wfm.topology.flow.model.FlowPathPair)2 FlowThrottlingData (org.openkilda.wfm.topology.reroute.model.FlowThrottlingData)2