use of org.openkilda.model.IslEndpoint 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.model.IslEndpoint in project open-kilda by telstra.
the class RerouteQueueServiceTest method shouldMergeAndSendRetryWithPendingRequestWhenReceivedFailedRuleInstallResponseOnTransitSwitchYFlow.
@Test
public void shouldMergeAndSendRetryWithPendingRequestWhenReceivedFailedRuleInstallResponseOnTransitSwitchYFlow() {
FlowThrottlingData inProgress = getFlowThrottlingData(yFlow, CORRELATION_ID).build();
FlowThrottlingData pending = FlowThrottlingData.builder().correlationId("pending").priority(7).timeCreate(yFlow.getTimeCreate()).affectedIsl(Collections.singleton(new IslEndpoint(SWITCH_ID_A, 1))).force(false).effectivelyDown(true).reason("another reason").yFlow(true).build();
RerouteQueue rerouteQueue = RerouteQueue.builder().inProgress(inProgress).pending(pending).build();
rerouteQueueService.getReroutes().put(YFLOW_ID, rerouteQueue);
RerouteResultInfoData rerouteResultInfoData = RerouteResultInfoData.builder().flowId(YFLOW_ID).success(false).rerouteError(new SpeakerRequestError("Failed to install rules", Collections.singleton(SWITCH_C.getSwitchId()))).yFlow(true).build();
rerouteQueueService.processRerouteResult(rerouteResultInfoData, CORRELATION_ID);
String retryCorrelationId = CORRELATION_ID + " : retry #1 ignore_bw false";
FlowThrottlingData expected = getFlowThrottlingData(yFlow, retryCorrelationId).build();
expected.setPriority(pending.getPriority());
expected.setReason(pending.getReason());
assertEquals(expected, rerouteQueue.getInProgress());
assertNull(rerouteQueue.getPending());
assertNull(rerouteQueue.getThrottling());
YFlowRerouteRequest expectedRequest = getYFlowRerouteRequest(YFLOW_ID, expected);
verify(carrier).sendRerouteRequest(eq(retryCorrelationId), eq(expectedRequest));
}
use of org.openkilda.model.IslEndpoint in project open-kilda by telstra.
the class RerouteQueueServiceTest method shouldMergeRequestsInThrottling.
@Test
public void shouldMergeRequestsInThrottling() {
FlowThrottlingData first = FlowThrottlingData.builder().correlationId("another").priority(1).timeCreate(Instant.now().plus(1, MINUTES)).affectedIsl(Collections.singleton(new IslEndpoint(SWITCH_ID_A, 1))).force(false).effectivelyDown(false).reason("another reason").build();
rerouteQueueService.getReroutes().put(FLOW_ID, RerouteQueue.builder().throttling(first).build());
FlowThrottlingData actual = getFlowThrottlingData(flow, CORRELATION_ID).build();
rerouteQueueService.processAutomaticRequest(FLOW_ID, actual);
assertEquals(1, rerouteQueueService.getReroutes().size());
assertNotNull(rerouteQueueService.getReroutes().get(FLOW_ID));
RerouteQueue rerouteQueue = rerouteQueueService.getReroutes().get(FLOW_ID);
assertNull(rerouteQueue.getInProgress());
assertNull(rerouteQueue.getPending());
actual.setReason(first.getReason());
assertEquals(actual, rerouteQueue.getThrottling());
verify(carrier).sendExtendTimeWindowEvent();
}
use of org.openkilda.model.IslEndpoint in project open-kilda by telstra.
the class RerouteQueueServiceTest method shouldMergeThrottledAndPendingRequestOnFlushWindowEvent.
@Test
public void shouldMergeThrottledAndPendingRequestOnFlushWindowEvent() {
FlowThrottlingData inProgress = FlowThrottlingData.builder().correlationId("in progress").priority(flow.getPriority()).timeCreate(flow.getTimeCreate()).affectedIsl(Collections.emptySet()).force(false).effectivelyDown(false).reason("first reason").build();
FlowThrottlingData pending = FlowThrottlingData.builder().correlationId("pending").priority(flow.getPriority()).timeCreate(flow.getTimeCreate()).affectedIsl(Collections.singleton(new IslEndpoint(SWITCH_ID_B, 1))).force(false).effectivelyDown(true).reason("second reason").build();
FlowThrottlingData throttling = FlowThrottlingData.builder().correlationId(CORRELATION_ID).priority(7).timeCreate(Instant.now().plus(1, MINUTES)).affectedIsl(Collections.singleton(new IslEndpoint(SWITCH_ID_A, 1))).force(true).effectivelyDown(false).reason("third reason").build();
RerouteQueue rerouteQueue = RerouteQueue.builder().inProgress(inProgress).pending(pending).throttling(throttling).build();
rerouteQueueService.getReroutes().put(FLOW_ID, rerouteQueue);
rerouteQueueService.flushThrottling();
assertNotNull(rerouteQueue.getInProgress());
FlowThrottlingData expected = FlowThrottlingData.builder().correlationId(rerouteQueue.getPending().getCorrelationId()).priority(throttling.getPriority()).timeCreate(throttling.getTimeCreate()).affectedIsl(Sets.newHashSet(new IslEndpoint(SWITCH_ID_A, 1), new IslEndpoint(SWITCH_ID_B, 1))).force(true).effectivelyDown(true).reason(pending.getReason()).build();
assertEquals(expected, rerouteQueue.getPending());
assertNull(rerouteQueue.getThrottling());
}
use of org.openkilda.model.IslEndpoint in project open-kilda by telstra.
the class SpeakerFlowSegmentRequestBuilder method makeTransitSegmentRequest.
private FlowSegmentRequestFactory makeTransitSegmentRequest(CommandContext context, FlowPath path, FlowTransitEncapsulation encapsulation, PathSegment ingress, PathSegment egress) {
final PathSegmentSide inboundSide = makePathSegmentDestSide(ingress);
final PathSegmentSide outboundSide = makePathSegmentSourceSide(egress);
final IslEndpoint ingressEndpoint = inboundSide.getEndpoint();
final IslEndpoint egressEndpoint = outboundSide.getEndpoint();
assert ingressEndpoint.getSwitchId().equals(egressEndpoint.getSwitchId()) : "Only neighbor segments can be used for for transit segment request creation";
UUID commandId = commandIdGenerator.generate();
MessageContext messageContext = new MessageContext(commandId.toString(), context.getCorrelationId());
return TransitFlowSegmentRequestFactory.builder().messageContext(messageContext).switchId(ingressEndpoint.getSwitchId()).metadata(makeMetadata(path, ensureEqualMultiTableFlag(inboundSide.isMultiTable(), outboundSide.isMultiTable(), String.format("Flow(id:%s, path:%s) have incompatible multi-table flags between segments %s " + "and %s", path.getFlow().getFlowId(), path.getPathId(), ingress, egress)))).ingressIslPort(ingressEndpoint.getPortNumber()).egressIslPort(egressEndpoint.getPortNumber()).encapsulation(encapsulation).build();
}
Aggregations