use of org.openkilda.model.YFlow 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();
}
use of org.openkilda.model.YFlow in project open-kilda by telstra.
the class RemoveMetersAction method perform.
@Override
protected void perform(State from, State to, Event event, YFlowUpdateContext context, YFlowUpdateFsm stateMachine) {
log.debug("Abandoning all pending commands: {}", stateMachine.getPendingCommands());
stateMachine.clearPendingAndRetriedAndFailedCommands();
String yFlowId = stateMachine.getYFlowId();
YFlow yFlow = getYFlow(yFlowId);
Collection<DeleteSpeakerCommandsRequest> commands = buildYFlowDeleteCommands(yFlow, stateMachine.getCommandContext());
commands.addAll(stateMachine.getDeleteOldYFlowCommands());
if (commands.isEmpty()) {
stateMachine.saveActionToHistory("No need to remove y-flow meters");
stateMachine.fire(Event.YPOINT_METERS_REMOVED);
} else {
// emitting
commands.forEach(command -> {
stateMachine.getCarrier().sendSpeakerRequest(command);
stateMachine.addDeleteSpeakerCommand(command.getCommandId(), command);
stateMachine.addPendingCommand(command.getCommandId(), command.getSwitchId());
});
stateMachine.saveActionToHistory("Commands for removing y-flow rules have been sent");
}
}
use of org.openkilda.model.YFlow 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();
}
use of org.openkilda.model.YFlow in project open-kilda by telstra.
the class DumpYFlowResourcesAction method perform.
@Override
protected void perform(State from, State to, Event event, YFlowValidationContext context, YFlowValidationFsm stateMachine) {
String yFlowId = stateMachine.getYFlowId();
YFlow yFlow = yFlowRepository.findById(yFlowId).orElseThrow(() -> new FlowProcessingException(ErrorType.NOT_FOUND, format("Y-flow %s not found", yFlowId)));
log.debug("Start validating y-flow {} resources", yFlowId);
List<SwitchId> switchIds = Stream.of(yFlow.getSharedEndpoint().getSwitchId(), yFlow.getYPoint(), yFlow.getProtectedPathYPoint()).filter(Objects::nonNull).collect(Collectors.toList());
int switchCount = switchIds.size();
stateMachine.setAwaitingRules(switchCount);
stateMachine.setAwaitingMeters(switchCount);
log.debug("Send commands to get rules & meters on {} switches", switchCount);
YFlowValidationHubCarrier carrier = stateMachine.getCarrier();
switchIds.forEach(switchId -> {
carrier.sendSpeakerRequest(yFlowId, new DumpRulesForFlowHsRequest(switchId));
carrier.sendSpeakerRequest(yFlowId, new DumpMetersForFlowHsRequest(switchId));
});
}
use of org.openkilda.model.YFlow 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);
}
Aggregations