16 package org.openkilda.testing.model.topology;
18 import static java.util.Collections.emptyList;
19 import static java.util.Collections.unmodifiableList;
20 import static java.util.stream.Collectors.toList;
21 import static java.util.stream.Collectors.toSet;
25 import com.fasterxml.jackson.annotation.JsonCreator;
26 import com.fasterxml.jackson.annotation.JsonIdentityInfo;
27 import com.fasterxml.jackson.annotation.JsonProperty;
28 import com.fasterxml.jackson.annotation.ObjectIdGenerators;
29 import com.google.common.base.Preconditions;
30 import com.google.common.collect.ImmutableRangeSet;
31 import com.google.common.collect.Range;
32 import com.google.common.collect.RangeSet;
33 import lombok.NonNull;
35 import lombok.experimental.NonFinal;
37 import java.util.ArrayList;
38 import java.util.List;
40 import java.util.stream.Collectors;
41 import java.util.stream.IntStream;
53 private List<Switch> switches;
55 private List<Isl> isls;
57 private List<TraffGen> traffGens;
59 private TraffGenConfig traffGenConfig;
66 @JsonProperty(
"switches") List<Switch> switches,
67 @JsonProperty(
"isls") List<Isl> isls,
68 @JsonProperty(
"traffgens") List<TraffGen> traffGens,
69 @JsonProperty(
"traffgen_config") TraffGenConfig traffGenConfig) {
71 Preconditions.checkArgument(
72 switches.size() == switches.stream().map(Switch::getDpId).distinct().count(),
73 "Switches must have no duplicates");
74 Preconditions.checkArgument(
75 isls.size() == isls.stream().distinct().count(),
"Isls must have no duplicates");
76 Preconditions.checkArgument(
77 traffGens.size() == traffGens.stream().map(TraffGen::getName).distinct().count(),
78 "TraffGens must have no duplicates");
81 unmodifiableList(switches),
82 unmodifiableList(isls),
83 unmodifiableList(traffGens),
91 return switches.stream()
92 .filter(Switch::isActive)
100 return switches.stream()
102 .map(Switch::getDpId)
111 .filter(isl -> isl.getDstSwitch() != null
112 && isl.getSrcSwitch().isActive() && isl.getDstSwitch().isActive())
122 .filter(isl -> isl.getSrcSwitch() != null && isl.getSrcSwitch().isActive()
123 && isl.getDstSwitch() == null)
131 List<Integer> allPorts =
new ArrayList<>(sw.getAllPorts());
133 isl.getSrcSwitch().getDpId().equals(sw.getDpId())).map(Isl::getSrcPort).collect(Collectors.toList()));
135 isl.getDstSwitch().getDpId().equals(sw.getDpId())).map(Isl::getDstPort).collect(Collectors.toList()));
141 @JsonIdentityInfo(property =
"name",
generator = ObjectIdGenerators.PropertyGenerator.class)
142 public static class Switch {
144 private static int DEFAULT_MAX_PORT = 20;
150 private String ofVersion;
154 private List<OutPort> outPorts;
155 private Integer maxPort;
162 @JsonProperty(
"name") String
name,
163 @JsonProperty(
"dp_id")
SwitchId dpId,
164 @JsonProperty(
"of_version") String ofVersion,
165 @JsonProperty(
"status") Status
status,
166 @JsonProperty(
"out_ports") List<OutPort> outPorts,
167 @JsonProperty(
"max_port") Integer maxPort) {
168 if (outPorts == null) {
169 outPorts = emptyList();
171 if (maxPort == null) {
172 maxPort = DEFAULT_MAX_PORT;
175 return new Switch(
name, dpId, ofVersion,
status, outPorts, maxPort);
178 public boolean isActive() {
179 return status == Status.Active;
185 public List<Integer> getAllPorts() {
186 return IntStream.rangeClosed(1, maxPort).boxed().collect(toList());
192 public static class OutPort {
196 private RangeSet<Integer> vlanRange;
200 @JsonProperty(
"port")
int port,
201 @JsonProperty(
"vlan_range") String vlanRange) {
203 return new OutPort(
port, parseVlanRange(vlanRange));
206 private static RangeSet<Integer> parseVlanRange(String vlanRangeAsStr) {
207 String[] splitRanges = vlanRangeAsStr.split(
",");
208 if (splitRanges.length == 0) {
209 throw new IllegalArgumentException(
"Vlan range must be non-empty.");
212 ImmutableRangeSet.Builder<Integer> resultVlanRange = ImmutableRangeSet.builder();
213 for (String range : splitRanges) {
214 String[] boundaries = range.split(
"\\.\\.");
215 if (boundaries.length == 0 || boundaries.length > 2) {
216 throw new IllegalArgumentException(
"Range " + range +
" is not valid.");
219 int lowerBound = Integer.parseInt(boundaries[0].trim());
220 if (boundaries.length == 2) {
221 int upperBound = Integer.parseInt(boundaries[1].trim());
222 resultVlanRange.add(Range.closed(lowerBound, upperBound));
224 resultVlanRange.add(Range.closed(lowerBound, lowerBound));
228 return resultVlanRange.build();
234 public static class Isl {
237 private Switch srcSwitch;
239 private Switch dstSwitch;
241 private long maxBandwidth;
242 private ASwitch aswitch;
246 @JsonProperty(
"src_switch") Switch srcSwitch,
247 @JsonProperty(
"src_port")
int srcPort,
248 @JsonProperty(
"dst_switch") Switch dstSwitch,
249 @JsonProperty(
"dst_port")
int dstPort,
250 @JsonProperty(
"max_bandwidth")
long maxBandwidth,
251 @JsonProperty(
"a_switch") ASwitch aswitch) {
252 return new Isl(srcSwitch, srcPort, dstSwitch, dstPort, maxBandwidth, aswitch);
258 public static class ASwitch {
261 private Integer inPort;
262 private Integer outPort;
266 @JsonProperty(
"in_port") Integer inPort,
267 @JsonProperty(
"out_port") Integer outPort) {
268 return new ASwitch(inPort, outPort);
274 public static class TraffGen {
279 private String controlEndpoint;
281 private String ifaceName;
283 private Switch switchConnected;
284 private int switchPort;
289 public static TraffGen
factory(
290 @JsonProperty(
"name") String
name,
291 @JsonProperty(
"iface") String ifaceName,
292 @JsonProperty(
"control_endpoint") String controlEndpoint,
293 @JsonProperty(
"switch") Switch switchConnected,
294 @JsonProperty(
"switch_port")
int switchPort,
295 @JsonProperty(
"status") Status
status) {
296 return new TraffGen(
name, controlEndpoint, ifaceName, switchConnected, switchPort,
status);
299 public boolean isActive() {
300 return status == Status.Active;
308 return traffGens.stream()
309 .filter(TraffGen::isActive)
310 .filter(traffGen -> traffGen.getSwitchConnected().isActive())
311 .collect(Collectors.toList());
316 public static class TraffGenConfig {
319 private String addressPoolBase;
320 private int addressPoolPrefixLen;
323 public static TraffGenConfig
factory(
324 @JsonProperty(
"address_pool_base") String addressPoolBase,
325 @JsonProperty(
"address_pool_prefix_len")
int addressPoolPrefixLen) {
326 return new TraffGenConfig(addressPoolBase, addressPoolPrefixLen);
List< Switch > getActiveSwitches()
List< TraffGen > getActiveTraffGens()
List< Integer > getAllowedPortsForSwitch(Switch sw)
static TopologyDefinition factory( @JsonProperty("switches") List< Switch > switches, @JsonProperty("isls") List< Isl > isls, @JsonProperty("traffgens") List< TraffGen > traffGens, @JsonProperty("traffgen_config") TraffGenConfig traffGenConfig)
List< Isl > getIslsForActiveSwitches()
Set< SwitchId > getSkippedSwitchIds()
List< Isl > getNotConnectedIsls()