use of org.openkilda.model.YSubFlow in project open-kilda by telstra.
the class FlowFetcher method handleOnDemandYFlowRequest.
private void handleOnDemandYFlowRequest(Tuple input) throws PipelineException {
log.debug("Handle on demand ping request");
YFlowPingRequest request = pullOnDemandYFlowRequest(input);
Optional<YFlow> optionalYFlow = yFlowRepository.findById(request.getYFlowId());
if (!optionalYFlow.isPresent()) {
emitOnDemandYFlowResponse(input, request, format("YFlow %s does not exist", request.getYFlowId()));
return;
}
YFlow yFlow = optionalYFlow.get();
Set<YSubFlow> subFlows = yFlow.getSubFlows();
if (subFlows.isEmpty()) {
emitOnDemandYFlowResponse(input, request, format("YFlow %s has no sub flows", request.getYFlowId()));
return;
}
GroupId groupId = new GroupId(subFlows.size() * DIRECTION_COUNT_PER_FLOW);
List<PingContext> subFlowPingRequests = new ArrayList<>();
for (YSubFlow subFlow : subFlows) {
Flow flow = subFlow.getFlow();
// Load paths to use in PingProducer
flow.getPaths();
flowRepository.detach(flow);
Optional<FlowTransitEncapsulation> transitEncapsulation = getTransitEncapsulation(flow);
if (transitEncapsulation.isPresent()) {
subFlowPingRequests.add(PingContext.builder().group(groupId).kind(Kinds.ON_DEMAND_Y_FLOW).flow(flow).yFlowId(yFlow.getYFlowId()).transitEncapsulation(transitEncapsulation.get()).timeout(request.getTimeout()).build());
} else {
emitOnDemandYFlowResponse(input, request, format("Encapsulation resource not found for sub flow %s of YFlow %s", subFlow.getSubFlowId(), yFlow.getYFlowId()));
return;
}
}
CommandContext commandContext = pullContext(input);
for (PingContext pingContext : subFlowPingRequests) {
emit(input, pingContext, commandContext);
}
}
use of org.openkilda.model.YSubFlow in project open-kilda by telstra.
the class TestYFlowBuilder method build.
/**
* Build {@link YFlow} instance.
*/
public YFlow build() {
boolean allocateProtectedPath = false;
if (protectedPathYPoint != null || protectedPathMeterId != null) {
checkArgument(protectedPathYPoint != null && protectedPathMeterId != null, "Insufficient data provided to make YFlow with protected path");
allocateProtectedPath = true;
}
YFlow.YFlowBuilder yFlowBuilder = YFlow.builder().yFlowId(yFlowId).sharedEndpoint(sharedEndpoint).sharedEndpointMeterId(sharedEndpointMeterId).yPoint(yPoint).meterId(meterId).allocateProtectedPath(allocateProtectedPath).maximumBandwidth(maximumBandwidth).ignoreBandwidth(ignoreBandwidth).strictBandwidth(strictBandwidth).description(description).periodicPings(periodicPings).encapsulationType(encapsulationType).status(status).maxLatency(maxLatency).maxLatencyTier2(maxLatencyTier2).priority(priority).pinned(pinned).pathComputationStrategy(pathComputationStrategy);
if (allocateProtectedPath) {
yFlowBuilder = yFlowBuilder.protectedPathYPoint(protectedPathYPoint).protectedPathMeterId(protectedPathMeterId);
}
YFlow yFlow = yFlowBuilder.build();
Set<YSubFlow> subFlowsGoal = new HashSet<>();
for (TestYSubFlowBuilder subFlowBuilder : subFlows) {
subFlowsGoal.add(subFlowBuilder.yFlow(yFlow).build());
}
yFlow.setSubFlows(subFlowsGoal);
yFlow.setTimeCreate(timeCreate);
yFlow.setTimeModify(timeModify);
return yFlow;
}
use of org.openkilda.model.YSubFlow 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.YSubFlow 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.YSubFlow 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