use of org.openkilda.atdd.staging.model.topology.TopologyDefinition.Switch in project open-kilda by telstra.
the class FlowCrudSteps method buildFlow.
private FlowPayload buildFlow(String flowId, Switch srcSwitch, Switch destSwitch) {
// Take the switch vlan ranges as the base
RangeSet<Integer> srcRangeSet = TreeRangeSet.create();
srcSwitch.getOutPorts().forEach(port -> srcRangeSet.addAll(port.getVlanRange()));
RangeSet<Integer> destRangeSet = TreeRangeSet.create();
destSwitch.getOutPorts().forEach(port -> destRangeSet.addAll(port.getVlanRange()));
// Exclude already allocated vlans
srcRangeSet.removeAll(allocatedVlans);
destRangeSet.removeAll(allocatedVlans);
if (srcRangeSet.isEmpty() || destRangeSet.isEmpty()) {
LOGGER.warn("Unable to define a flow between {} and {} as no vlan available.", srcSwitch, destSwitch);
return null;
}
// Calculate intersection of the ranges
RangeSet<Integer> interRangeSet = TreeRangeSet.create(srcRangeSet);
interRangeSet.removeAll(destRangeSet.complement());
// Same vlan for source and destination
final Optional<Integer> sameVlan = interRangeSet.asRanges().stream().flatMap(range -> ContiguousSet.create(range, DiscreteDomain.integers()).stream()).findFirst();
int srcVlan;
int destVlan;
if (sameVlan.isPresent()) {
srcVlan = sameVlan.get();
destVlan = sameVlan.get();
} else {
// Cross vlan flow
Optional<Integer> srcVlanOpt = srcRangeSet.asRanges().stream().flatMap(range -> ContiguousSet.create(range, DiscreteDomain.integers()).stream()).findFirst();
if (!srcVlanOpt.isPresent()) {
LOGGER.warn("Unable to allocate a vlan for the switch {}.", srcSwitch);
return null;
}
srcVlan = srcVlanOpt.get();
Optional<Integer> destVlanOpt = destRangeSet.asRanges().stream().flatMap(range -> ContiguousSet.create(range, DiscreteDomain.integers()).stream()).findFirst();
if (!destVlanOpt.isPresent()) {
LOGGER.warn("Unable to allocate a vlan for the switch {}.", destSwitch);
return null;
}
destVlan = destVlanOpt.get();
}
boolean sameSwitchFlow = srcSwitch.getDpId().equals(destSwitch.getDpId());
Optional<OutPort> srcPort = srcSwitch.getOutPorts().stream().filter(p -> p.getVlanRange().contains(srcVlan)).findFirst();
int srcPortId = srcPort.orElseThrow(() -> new IllegalStateException("Unable to allocate a port in found vlan.")).getPort();
Optional<OutPort> destPort = destSwitch.getOutPorts().stream().filter(p -> p.getVlanRange().contains(destVlan)).filter(p -> !sameSwitchFlow || p.getPort() != srcPortId).findFirst();
if (!destPort.isPresent()) {
if (sameSwitchFlow) {
LOGGER.warn("Unable to define a same switch flow for {} as no ports available.", srcSwitch);
return null;
} else {
throw new IllegalStateException("Unable to allocate a port in found vlan.");
}
}
// Record used vlan to archive uniqueness
allocatedVlans.add(Range.singleton(srcVlan));
allocatedVlans.add(Range.singleton(destVlan));
FlowEndpointPayload srcEndpoint = new FlowEndpointPayload(srcSwitch.getDpId(), srcPortId, srcVlan);
FlowEndpointPayload destEndpoint = new FlowEndpointPayload(destSwitch.getDpId(), destPort.get().getPort(), destVlan);
return new FlowPayload(flowId, srcEndpoint, destEndpoint, 1, false, flowId, null);
}
Aggregations