use of org.openkilda.model.YFlow in project open-kilda by telstra.
the class RerouteQueueService method isRetryRequired.
private boolean isRetryRequired(String flowId, RerouteError rerouteError, boolean isYFlow) {
if (rerouteError instanceof NoPathFoundError) {
log.info("Received no path found error for flow {}", flowId);
return true;
} else if (rerouteError instanceof RerouteInProgressError) {
log.info("Received reroute in progress error for flow {}", flowId);
return true;
} else if (rerouteError instanceof SpeakerRequestError) {
if (isYFlow) {
log.info("Received speaker request error for y-flow {}", flowId);
YFlow yFlow = yFlowRepository.findById(flowId).orElse(null);
if (yFlow == null) {
log.error("Y-flow {} not found", flowId);
return false;
}
Set<SwitchId> yFlowSwitchIds = yFlow.getSubFlows().stream().map(YSubFlow::getEndpointSwitchId).collect(Collectors.toSet());
yFlowSwitchIds.add(yFlow.getSharedEndpoint().getSwitchId());
boolean isRetryRequired = true;
SpeakerRequestError ruleFailedError = (SpeakerRequestError) rerouteError;
for (SwitchId switchId : yFlowSwitchIds) {
isRetryRequired &= !ruleFailedError.getSwitches().contains(switchId);
}
return isRetryRequired;
} else {
log.info("Received speaker request error for flow {}", flowId);
Flow flow = flowRepository.findById(flowId).orElse(null);
if (flow == null) {
log.error("Flow {} not found", flowId);
return false;
}
SpeakerRequestError ruleFailedError = (SpeakerRequestError) rerouteError;
return !ruleFailedError.getSwitches().contains(flow.getSrcSwitchId()) && !ruleFailedError.getSwitches().contains(flow.getDestSwitchId());
}
}
return false;
}
use of org.openkilda.model.YFlow in project open-kilda by telstra.
the class RerouteQueueService method processManualRequest.
/**
* Process manual reroute request.
*
* @param flowId flow id
* @param throttlingData reroute request params
*/
public void processManualRequest(String flowId, FlowThrottlingData throttlingData) {
if (throttlingData.isYFlow()) {
Optional<YFlow> yFlow = yFlowRepository.findById(flowId);
if (!yFlow.isPresent()) {
String description = format("Y-flow %s not found", flowId);
ErrorData errorData = new ErrorData(ErrorType.NOT_FOUND, "Could not reroute y-flow", description);
carrier.emitFlowRerouteError(errorData);
return;
} else if (yFlow.get().isPinned()) {
String description = "Can't reroute pinned y-flow";
ErrorData errorData = new ErrorData(ErrorType.UNPROCESSABLE_REQUEST, "Could not reroute y-flow", description);
carrier.emitFlowRerouteError(errorData);
return;
}
} else {
Optional<Flow> flow = flowRepository.findById(flowId);
if (!flow.isPresent()) {
String description = format("Flow %s not found", flowId);
ErrorData errorData = new ErrorData(ErrorType.NOT_FOUND, "Could not reroute flow", description);
carrier.emitFlowRerouteError(errorData);
return;
} else if (flow.get().isPinned()) {
String description = "Can't reroute pinned flow";
ErrorData errorData = new ErrorData(ErrorType.UNPROCESSABLE_REQUEST, "Could not reroute flow", description);
carrier.emitFlowRerouteError(errorData);
return;
}
}
RerouteQueue rerouteQueue = getRerouteQueue(flowId);
if (rerouteQueue.hasInProgress()) {
String description = format("Flow %s is in reroute process", flowId);
ErrorData errorData = new ErrorData(ErrorType.UNPROCESSABLE_REQUEST, "Could not reroute flow", description);
carrier.emitFlowRerouteError(errorData);
} else {
rerouteQueue.putToInProgress(throttlingData);
sendRerouteRequest(flowId, throttlingData);
}
}
use of org.openkilda.model.YFlow in project open-kilda by telstra.
the class AllocateYFlowResourcesAction method perform.
@Override
public void perform(S from, S to, E event, C context, T stateMachine) {
try {
String yFlowId = stateMachine.getYFlowId();
YFlowResources newResources;
// This could be a retry.
if (stateMachine.getNewResources() != null) {
newResources = stateMachine.getNewResources();
} else {
newResources = new YFlowResources();
stateMachine.setNewResources(newResources);
}
YFlow yFlow = getYFlow(yFlowId);
SwitchId sharedEndpoint = yFlow.getSharedEndpoint().getSwitchId();
if (newResources.getSharedEndpointResources() == null) {
EndpointResources sharedEndpointResources = allocateMeterAsEndpointResources(yFlowId, sharedEndpoint, yFlow.getMaximumBandwidth());
newResources.setSharedEndpointResources(sharedEndpointResources);
stateMachine.saveActionToHistory("A new meter was allocated for the y-flow shared endpoint", format("A new meter %s / %s was allocated", sharedEndpointResources.getMeterId(), sharedEndpointResources.getEndpoint()));
}
if (newResources.getMainPathYPointResources() == null) {
List<FlowPath> subFlowsReversePaths = new ArrayList<>();
yFlow.getSubFlows().forEach(subFlow -> {
Flow flow = subFlow.getFlow();
FlowPath path = flow.getReversePath();
if (path == null) {
throw new FlowProcessingException(ErrorType.INTERNAL_ERROR, format("Missing a reverse path for %s sub-flow", flow.getFlowId()));
} else {
subFlowsReversePaths.add(path);
}
});
EndpointResources yPointResources = allocateYPointResources(yFlowId, sharedEndpoint, yFlow.getMaximumBandwidth(), subFlowsReversePaths.toArray(new FlowPath[0]));
newResources.setMainPathYPointResources(yPointResources);
stateMachine.saveActionToHistory("A new meter was allocated for the y-flow y-point", format("A new meter %s / %s was allocated", yPointResources.getMeterId(), yPointResources.getEndpoint()));
}
if (yFlow.isAllocateProtectedPath() && newResources.getProtectedPathYPointResources() == null) {
List<FlowPath> subFlowsReversePaths = new ArrayList<>();
yFlow.getSubFlows().forEach(subFlow -> {
Flow flow = subFlow.getFlow();
FlowPath path = flow.getProtectedReversePath();
if (path == null) {
if (flow.getStatus() == FlowStatus.UP) {
throw new FlowProcessingException(ErrorType.INTERNAL_ERROR, format("Missing a protected path for %s sub-flow", flow.getFlowId()));
} else {
log.warn("Sub-flow {} has no expected protected path and status {}", flow.getFlowId(), flow.getStatus());
}
} else {
subFlowsReversePaths.add(path);
}
});
if (subFlowsReversePaths.size() > 1) {
EndpointResources yPointResources = allocateYPointResources(yFlowId, sharedEndpoint, yFlow.getMaximumBandwidth(), subFlowsReversePaths.toArray(new FlowPath[0]));
newResources.setProtectedPathYPointResources(yPointResources);
stateMachine.saveActionToHistory("A new meter was allocated for the y-flow protected path y-point", format("A new meter %s / %s was allocated", yPointResources.getMeterId(), yPointResources.getEndpoint()));
} else {
stateMachine.saveActionToHistory("Skip meter allocation for the y-flow protected path y-point", "Y-flow protected path y-point can't be found - sub-flow(s) lacks a protected path");
}
}
transactionManager.doInTransaction(() -> {
YFlow yFlowToUpdate = getYFlow(yFlowId);
yFlowToUpdate.setYPoint(newResources.getMainPathYPointResources().getEndpoint());
yFlowToUpdate.setMeterId(newResources.getMainPathYPointResources().getMeterId());
if (newResources.getProtectedPathYPointResources() != null) {
yFlowToUpdate.setProtectedPathYPoint(newResources.getProtectedPathYPointResources().getEndpoint());
yFlowToUpdate.setProtectedPathMeterId(newResources.getProtectedPathYPointResources().getMeterId());
} else {
yFlowToUpdate.setProtectedPathYPoint(null);
yFlowToUpdate.setProtectedPathMeterId(null);
}
yFlowToUpdate.setSharedEndpointMeterId(newResources.getSharedEndpointResources().getMeterId());
});
notifyStats(stateMachine, newResources);
} catch (ResourceAllocationException ex) {
String errorMessage = format("Failed to allocate y-flow resources. %s", ex.getMessage());
stateMachine.saveErrorToHistory(errorMessage, ex);
stateMachine.fireError(errorMessage);
}
}
use of org.openkilda.model.YFlow in project open-kilda by telstra.
the class AbstractFlowTest method createTestYFlowForSubFlow.
protected void createTestYFlowForSubFlow(Flow subFlow) {
YFlow yFlow = YFlow.builder().yFlowId("test_y_flow").sharedEndpoint(new SharedEndpoint(subFlow.getSrcSwitchId(), subFlow.getSrcPort())).status(FlowStatus.UP).build();
yFlow.setSubFlows(singleton(YSubFlow.builder().sharedEndpointVlan(subFlow.getSrcVlan()).sharedEndpointInnerVlan(subFlow.getSrcInnerVlan()).endpointSwitchId(subFlow.getDestSwitchId()).endpointPort(subFlow.getDestPort()).endpointVlan(subFlow.getDestVlan()).endpointInnerVlan(subFlow.getDestInnerVlan()).flow(subFlow).yFlow(yFlow).build()));
YFlowRepository yFlowRepository = persistenceManager.getRepositoryFactory().createYFlowRepository();
yFlowRepository.add(yFlow);
}
use of org.openkilda.model.YFlow in project open-kilda by telstra.
the class YFlowUpdateService method handlePartialUpdateRequest.
/**
* Handles request for y-flow patch updating.
*
* @param key command identifier.
* @param request request data.
*/
public void handlePartialUpdateRequest(@NonNull String key, @NonNull CommandContext commandContext, @NonNull YFlowPartialUpdateRequest request) throws DuplicateKeyException {
YFlowRequest target;
if (request.getYFlowId() != null) {
YFlow yFlow = yFlowRepository.findById(request.getYFlowId()).orElse(null);
target = YFlowRequestMapper.INSTANCE.toYFlowRequest(yFlow);
} else {
throw new FlowProcessingException(ErrorType.REQUEST_INVALID, "Need to specify the y-flow id");
}
if (target == null) {
throw new FlowProcessingException(ErrorType.NOT_FOUND, format("Y-flow was not found by the specified y-flow id: %s", request.getYFlowId()));
}
if (request.getSharedEndpoint() != null) {
if (target.getSharedEndpoint() == null) {
target.setSharedEndpoint(new FlowEndpoint(request.getSharedEndpoint().getSwitchId(), request.getSharedEndpoint().getPortNumber()));
} else {
SwitchId switchId = Optional.ofNullable(request.getSharedEndpoint().getSwitchId()).orElse(target.getSharedEndpoint().getSwitchId());
int portNumber = Optional.ofNullable(request.getSharedEndpoint().getPortNumber()).orElse(target.getSharedEndpoint().getPortNumber());
target.setSharedEndpoint(new FlowEndpoint(switchId, portNumber));
}
}
Optional.ofNullable(request.getMaximumBandwidth()).ifPresent(target::setMaximumBandwidth);
Optional.ofNullable(request.getPathComputationStrategy()).ifPresent(target::setPathComputationStrategy);
Optional.ofNullable(request.getEncapsulationType()).ifPresent(target::setEncapsulationType);
Optional.ofNullable(request.getMaxLatency()).ifPresent(target::setMaxLatency);
Optional.ofNullable(request.getMaxLatencyTier2()).ifPresent(target::setMaxLatencyTier2);
Optional.ofNullable(request.getIgnoreBandwidth()).ifPresent(target::setIgnoreBandwidth);
Optional.ofNullable(request.getPeriodicPings()).ifPresent(target::setPeriodicPings);
Optional.ofNullable(request.getPinned()).ifPresent(target::setPinned);
Optional.ofNullable(request.getPriority()).ifPresent(target::setPriority);
Optional.ofNullable(request.getStrictBandwidth()).ifPresent(target::setStrictBandwidth);
Optional.ofNullable(request.getDescription()).ifPresent(target::setDescription);
Optional.ofNullable(request.getAllocateProtectedPath()).ifPresent(target::setAllocateProtectedPath);
Optional.ofNullable(request.getDiverseFlowId()).ifPresent(target::setDiverseFlowId);
if (request.getSubFlows() != null && !request.getSubFlows().isEmpty()) {
Map<String, SubFlowDto> stringSubFlowDtoMap;
if (target.getSubFlows() != null) {
stringSubFlowDtoMap = target.getSubFlows().stream().collect(Collectors.toMap(SubFlowDto::getFlowId, Function.identity()));
} else {
throw new FlowProcessingException(ErrorType.INTERNAL_ERROR, format("Sub-flows for y-flow %s not found", target.getYFlowId()));
}
List<SubFlowDto> subFlows = new ArrayList<>();
for (SubFlowPartialUpdateDto subFlowPartialUpdate : request.getSubFlows()) {
SubFlowDto subFlow = stringSubFlowDtoMap.get(subFlowPartialUpdate.getFlowId());
if (subFlow != null) {
if (subFlowPartialUpdate.getEndpoint() != null) {
if (subFlow.getEndpoint() == null) {
subFlow.setEndpoint(new FlowEndpoint(subFlowPartialUpdate.getEndpoint().getSwitchId(), subFlowPartialUpdate.getEndpoint().getPortNumber(), subFlowPartialUpdate.getEndpoint().getVlanId(), subFlowPartialUpdate.getEndpoint().getInnerVlanId()));
} else {
SwitchId switchId = Optional.ofNullable(subFlowPartialUpdate.getEndpoint().getSwitchId()).orElse(subFlow.getEndpoint().getSwitchId());
int portNumber = Optional.ofNullable(subFlowPartialUpdate.getEndpoint().getPortNumber()).orElse(subFlow.getEndpoint().getPortNumber());
int vlanId = Optional.ofNullable(subFlowPartialUpdate.getEndpoint().getVlanId()).orElse(subFlow.getEndpoint().getOuterVlanId());
int innerVlanId = Optional.ofNullable(subFlowPartialUpdate.getEndpoint().getInnerVlanId()).orElse(subFlow.getEndpoint().getInnerVlanId());
subFlow.setEndpoint(new FlowEndpoint(switchId, portNumber, vlanId, innerVlanId));
}
}
if (subFlowPartialUpdate.getSharedEndpoint() != null) {
if (subFlow.getSharedEndpoint() == null) {
subFlow.setSharedEndpoint(new SubFlowSharedEndpointEncapsulation(subFlowPartialUpdate.getSharedEndpoint().getVlanId(), subFlowPartialUpdate.getSharedEndpoint().getInnerVlanId()));
} else {
int vlanId = Optional.ofNullable(subFlowPartialUpdate.getSharedEndpoint().getVlanId()).orElse(subFlow.getSharedEndpoint().getVlanId());
int innerVlanId = Optional.ofNullable(subFlowPartialUpdate.getSharedEndpoint().getInnerVlanId()).orElse(subFlow.getSharedEndpoint().getInnerVlanId());
subFlow.setSharedEndpoint(new SubFlowSharedEndpointEncapsulation(vlanId, innerVlanId));
}
}
Optional.ofNullable(subFlowPartialUpdate.getDescription()).ifPresent(subFlow::setDescription);
subFlows.add(subFlow);
} else {
throw new FlowProcessingException(ErrorType.REQUEST_INVALID, format("There is no sub-flows with sub-flow id: %s", subFlowPartialUpdate.getFlowId()));
}
}
target.setSubFlows(subFlows);
}
target.setType(Type.UPDATE);
handleRequest(key, commandContext, target);
}
Aggregations