use of org.openkilda.model.IslEndpoint in project open-kilda by telstra.
the class ValidateFlowAction method performWithResponse.
@TimedExecution("fsm.validate_flow")
@Override
protected Optional<Message> performWithResponse(State from, State to, Event event, FlowRerouteContext context, FlowRerouteFsm stateMachine) {
String flowId = stateMachine.getFlowId();
Set<IslEndpoint> affectedIsl = new HashSet<>(Optional.ofNullable(context.getAffectedIsl()).orElse(emptySet()));
dashboardLogger.onFlowPathReroute(flowId, affectedIsl, context.isForceReroute());
String rerouteReason = context.getRerouteReason();
stateMachine.saveNewEventToHistory("Started flow validation", FlowEventData.Event.REROUTE, rerouteReason == null ? FlowEventData.Initiator.NB : FlowEventData.Initiator.AUTO, rerouteReason == null ? null : "Reason: " + rerouteReason);
stateMachine.setRerouteReason(rerouteReason);
Flow flow = transactionManager.doInTransaction(() -> {
Flow foundFlow = getFlow(flowId);
if (foundFlow.getStatus() == FlowStatus.IN_PROGRESS) {
String message = format("Flow %s is in progress now", flowId);
stateMachine.setRerouteError(new RerouteError(message));
throw new FlowProcessingException(ErrorType.REQUEST_INVALID, message);
}
if (!foundFlow.getSrcSwitch().isActive()) {
String message = format("Flow's %s src switch is not active", flowId);
stateMachine.setRerouteError(new RerouteError(message));
throw new FlowProcessingException(ErrorType.UNPROCESSABLE_REQUEST, message);
}
if (!foundFlow.getDestSwitch().isActive()) {
String message = format("Flow's %s dest switch is not active", flowId);
stateMachine.setRerouteError(new RerouteError(message));
throw new FlowProcessingException(ErrorType.UNPROCESSABLE_REQUEST, message);
}
stateMachine.setOriginalFlowStatus(foundFlow.getStatus());
stateMachine.setOriginalFlowStatusInfo(foundFlow.getStatusInfo());
stateMachine.setOriginalEncapsulationType(foundFlow.getEncapsulationType());
stateMachine.setOriginalPathComputationStrategy(foundFlow.getPathComputationStrategy());
stateMachine.setRecreateIfSamePath(!foundFlow.isActive() || context.isForceReroute());
stateMachine.setOriginalFlow(RequestedFlowMapper.INSTANCE.toRequestedFlow(foundFlow));
stateMachine.setPeriodicPingsEnabled(foundFlow.isPeriodicPings());
if (foundFlow.getTargetPathComputationStrategy() != null) {
foundFlow.setPathComputationStrategy(foundFlow.getTargetPathComputationStrategy());
foundFlow.setTargetPathComputationStrategy(null);
}
foundFlow.setStatus(FlowStatus.IN_PROGRESS);
return foundFlow;
});
if (featureTogglesRepository.getOrDefault().getFlowsRerouteUsingDefaultEncapType()) {
stateMachine.setNewEncapsulationType(kildaConfigurationRepository.getOrDefault().getFlowEncapsulationType());
}
boolean reroutePrimary;
boolean rerouteProtected;
if (affectedIsl.isEmpty()) {
// no know affected ISLs
reroutePrimary = true;
rerouteProtected = true;
} else {
reroutePrimary = checkIsPathAffected(flow.getForwardPath(), affectedIsl) || checkIsPathAffected(flow.getReversePath(), affectedIsl);
rerouteProtected = checkIsPathAffected(flow.getProtectedForwardPath(), affectedIsl) || checkIsPathAffected(flow.getProtectedReversePath(), affectedIsl);
}
// check protected path presence
rerouteProtected &= flow.isAllocateProtectedPath();
if (!reroutePrimary && !rerouteProtected) {
throw new FlowProcessingException(ErrorType.NOT_FOUND, format("No paths of the flow %s are affected by failure on %s", flowId, affectedIsl.stream().map(IslEndpoint::toString).collect(Collectors.joining(","))));
}
if (reroutePrimary) {
log.info("Reroute for the flow {} will affect primary paths: {} / {}", flowId, flow.getForwardPathId(), flow.getReversePathId());
}
if (rerouteProtected) {
log.info("Reroute for the flow {} will affect protected paths: {} / {}", flowId, flow.getProtectedForwardPathId(), flow.getProtectedReversePathId());
}
stateMachine.setReroutePrimary(reroutePrimary);
stateMachine.setRerouteProtected(rerouteProtected);
stateMachine.setEffectivelyDown(context.isEffectivelyDown());
if (stateMachine.isRerouteProtected() && flow.isPinned()) {
throw new FlowProcessingException(ErrorType.REQUEST_INVALID, format("Flow %s is pinned, fail to reroute its protected paths", flowId));
}
stateMachine.setAffectedIsls(context.getAffectedIsl());
stateMachine.setForceReroute(context.isForceReroute());
stateMachine.setIgnoreBandwidth(context.isIgnoreBandwidth());
stateMachine.saveActionToHistory("Flow was validated successfully");
return Optional.empty();
}
use of org.openkilda.model.IslEndpoint in project open-kilda by telstra.
the class SwitchOperationsBolt method updateSwitchUnderMaintenanceFlag.
private List<GetSwitchResponse> updateSwitchUnderMaintenanceFlag(UpdateSwitchUnderMaintenanceRequest request, Tuple tuple) {
SwitchId switchId = request.getSwitchId();
boolean underMaintenance = request.isUnderMaintenance();
boolean evacuate = request.isEvacuate();
Switch sw;
try {
sw = switchOperationsService.updateSwitchUnderMaintenanceFlag(switchId, underMaintenance);
} catch (SwitchNotFoundException e) {
throw new MessageException(ErrorType.NOT_FOUND, e.getMessage(), "Switch was not found.");
}
if (underMaintenance && evacuate) {
Collection<FlowPath> paths = flowOperationsService.getFlowPathsForSwitch(switchId);
Set<IslEndpoint> affectedIslEndpoint = new HashSet<>(switchOperationsService.getSwitchIslEndpoints(switchId));
String reason = format("evacuated due to switch maintenance %s", switchId);
for (FlowRerouteRequest reroute : flowOperationsService.makeRerouteRequests(paths, affectedIslEndpoint, reason)) {
CommandContext forkedContext = getCommandContext().fork(reroute.getFlowId());
getOutput().emit(StreamType.REROUTE.toString(), tuple, new Values(reroute, forkedContext.getCorrelationId()));
}
}
return Collections.singletonList(new GetSwitchResponse(sw));
}
use of org.openkilda.model.IslEndpoint in project open-kilda by telstra.
the class LinkOperationsBolt method islBfdPropertiesChanged.
@Override
public void islBfdPropertiesChanged(Endpoint source, Endpoint destination) {
IslBfdPropertiesChangeNotification notification = new IslBfdPropertiesChangeNotification(new IslEndpoint(source.getDatapath(), source.getPortNumber()), new IslEndpoint(destination.getDatapath(), destination.getPortNumber()));
getOutput().emit(StreamType.DISCO.toString(), getCurrentTuple(), new Values(notification, getCorrelationId()));
}
use of org.openkilda.model.IslEndpoint in project open-kilda by telstra.
the class FlowOperationsBolt method processRerouteFlowsForLinkRequest.
@TimedExecution("reroute_flows_for_link")
private List<FlowsResponse> processRerouteFlowsForLinkRequest(RerouteFlowsForIslRequest message) {
SwitchId srcSwitch = message.getSource().getDatapath();
Integer srcPort = message.getSource().getPortNumber();
SwitchId dstSwitch = message.getDestination().getDatapath();
Integer dstPort = message.getDestination().getPortNumber();
Collection<FlowPath> paths;
try {
paths = flowOperationsService.getFlowPathsForLink(srcSwitch, srcPort, dstSwitch, dstPort);
} catch (IslNotFoundException e) {
throw new MessageException(ErrorType.NOT_FOUND, e.getMessage(), "ISL was not found.");
}
Set<IslEndpoint> affectedIslEndpoints = new HashSet<>();
affectedIslEndpoints.add(new IslEndpoint(srcSwitch, srcPort));
affectedIslEndpoints.add(new IslEndpoint(dstSwitch, dstPort));
sendRerouteRequest(paths, affectedIslEndpoints, format("initiated via Northbound, reroute all flows that go over the link %s_%d - %s_%d", srcSwitch, srcPort, dstSwitch, dstPort));
List<String> flowIds = paths.stream().map(FlowPath::getFlow).map(Flow::getFlowId).distinct().collect(Collectors.toList());
return Collections.singletonList(new FlowsResponse(flowIds));
}
use of org.openkilda.model.IslEndpoint in project open-kilda by telstra.
the class RerouteServiceTest method handlePathNoFoundExceptionForSubYFlow.
@Test
public void handlePathNoFoundExceptionForSubYFlow() {
PathNode islSide = new PathNode(SWITCH_A.getSwitchId(), 1, 0);
FlowPathRepository pathRepository = mock(FlowPathRepository.class);
when(pathRepository.findBySegmentEndpoint(eq(islSide.getSwitchId()), eq(islSide.getPortNo()))).thenReturn(asList(subFlow.getForwardPath(), subFlow.getReversePath()));
FlowRepository flowRepository = mock(FlowRepository.class);
YFlowRepository yFlowRepository = mock(YFlowRepository.class);
RepositoryFactory repositoryFactory = mock(RepositoryFactory.class);
when(repositoryFactory.createPathSegmentRepository()).thenReturn(mock(PathSegmentRepository.class));
when(repositoryFactory.createFlowPathRepository()).thenReturn(pathRepository);
when(repositoryFactory.createFlowRepository()).thenReturn(flowRepository);
when(repositoryFactory.createYFlowRepository()).thenReturn(yFlowRepository);
PersistenceManager persistenceManager = mock(PersistenceManager.class);
when(persistenceManager.getRepositoryFactory()).thenReturn(repositoryFactory);
when(persistenceManager.getTransactionManager()).thenReturn(transactionManager);
RerouteService rerouteService = new RerouteService(persistenceManager);
RerouteAffectedFlows request = new RerouteAffectedFlows(islSide, "dummy-reason - unittest");
rerouteService.rerouteAffectedFlows(carrier, CORRELATION_ID, request);
verify(flowRepository).updateStatusSafe(eq(subFlow), eq(FlowStatus.DOWN), any());
FlowThrottlingData expected = FlowThrottlingData.builder().correlationId(CORRELATION_ID).priority(regularYFlow.getPriority()).timeCreate(regularYFlow.getTimeCreate()).affectedIsl(Collections.singleton(new IslEndpoint(islSide.getSwitchId(), islSide.getPortNo()))).force(false).effectivelyDown(true).reason(request.getReason()).yFlow(true).build();
verify(carrier).emitRerouteCommand(eq(regularYFlow.getYFlowId()), eq(expected));
}
Aggregations