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());
}
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.");
}
}
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());
}
}
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);
}
}
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");
}
}
Aggregations