Open Kilda Java Documentation
FlowCrudBasicRunTest.java
Go to the documentation of this file.
1 /* Copyright 2017 Telstra Open Source
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 package org.openkilda.atdd;
17 
18 import static java.lang.String.format;
19 import static org.hamcrest.MatcherAssert.assertThat;
20 import static org.hamcrest.Matchers.empty;
21 import static org.hamcrest.Matchers.hasItems;
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertFalse;
24 import static org.junit.Assert.assertNotEquals;
25 import static org.junit.Assert.assertNotNull;
26 import static org.junit.Assert.assertNull;
27 import static org.junit.Assert.assertTrue;
32 
44 
45 import com.fasterxml.jackson.databind.ObjectMapper;
46 import cucumber.api.java.en.Given;
47 import cucumber.api.java.en.Then;
48 import cucumber.api.java.en.When;
49 import org.glassfish.jersey.client.ClientConfig;
50 import org.hamcrest.Matcher;
51 import org.hamcrest.Matchers;
52 
53 import java.io.File;
54 import java.nio.file.Files;
55 import java.util.Arrays;
56 import java.util.List;
57 import java.util.concurrent.TimeUnit;
58 import java.util.stream.Collectors;
59 import javax.ws.rs.client.Client;
60 import javax.ws.rs.client.ClientBuilder;
61 import javax.ws.rs.core.Response;
62 
63 public class FlowCrudBasicRunTest {
64  private FlowPayload flowPayload;
65  private static final String fileName = "topologies/nonrandom-topology.json";
66 
67  @Given("^a nonrandom linear topology of 7 switches$")
68  public void multiPathTopology() throws Throwable {
69  ClassLoader classLoader = getClass().getClassLoader();
70  File file = new File(classLoader.getResource(fileName).getFile());
71  String json = new String(Files.readAllBytes(file.toPath()));
72  assertTrue(TopologyHelp.CreateMininetTopology(json));
73  // Should also wait for some of this to come up
74 
75  }
76 
77  @When("^flow (.*) creation request with (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) is successful$")
78  public void successfulFlowCreation(final String flowId, final String sourceSwitch, final int sourcePort,
79  final int sourceVlan, final String destinationSwitch, final int destinationPort,
80  final int destinationVlan, final int bandwidth) throws Exception {
81  flowPayload = new FlowPayload(FlowUtils.getFlowName(flowId),
82  new FlowEndpointPayload(new SwitchId(sourceSwitch), sourcePort, sourceVlan),
83  new FlowEndpointPayload(new SwitchId(destinationSwitch), destinationPort, destinationVlan),
84  bandwidth, false, flowId, null, FlowState.UP.getState());
85 
86  FlowPayload response = FlowUtils.putFlow(flowPayload);
87  assertNotNull(response);
88  response.setLastUpdated(null);
89 
90  assertEquals(flowPayload, response);
91  }
92 
93  @When("^flow (.*) creation request with (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) is failed$")
94  public void failedFlowCreation(final String flowId, final String sourceSwitch, final int sourcePort,
95  final int sourceVlan, final String destinationSwitch, final int destinationPort,
96  final int destinationVlan, final int bandwidth) throws Exception {
97  flowPayload = new FlowPayload(FlowUtils.getFlowName(flowId),
98  new FlowEndpointPayload(new SwitchId(sourceSwitch), sourcePort, sourceVlan),
99  new FlowEndpointPayload(new SwitchId(destinationSwitch), destinationPort, destinationVlan),
100  bandwidth, false, flowId, null, FlowState.DOWN.getState());
101 
102  FlowPayload response = FlowUtils.putFlow(flowPayload);
103 
104  assertNull(response);
105  }
106 
107  @Then("^flow (.*) with (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) could be created$")
108  public void checkFlowCreation(final String flowId, final String sourceSwitch, final int sourcePort,
109  final int sourceVlan, final String destinationSwitch, final int destinationPort,
110  final int destinationVlan, final int bandwidth) throws Exception {
111  Flow expectedFlow =
112  new Flow(FlowUtils.getFlowName(flowId), bandwidth, false, 0, flowId, null,
113  new SwitchId(sourceSwitch), new SwitchId(destinationSwitch), sourcePort, destinationPort,
114  sourceVlan, destinationVlan, 0, 0, null, null);
115 
116  List<Flow> flows = validateFlowStored(expectedFlow);
117 
118  assertFalse(flows.isEmpty());
119  assertTrue(flows.contains(expectedFlow));
120  }
121 
122  @Then("^flow (.*) with (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) could be read$")
123  public void checkFlowRead(final String flowId, final String sourceSwitch, final int sourcePort,
124  final int sourceVlan, final String destinationSwitch, final int destinationPort,
125  final int destinationVlan, final int bandwidth) throws Exception {
127  assertNotNull(flow);
128 
129  System.out.println(format("===> Flow was created at %s\n", flow.getLastUpdated()));
130 
131  assertEquals(FlowUtils.getFlowName(flowId), flow.getId());
132  assertEquals(new SwitchId(sourceSwitch), flow.getSource().getSwitchDpId());
133  assertEquals(sourcePort, flow.getSource().getPortId().longValue());
134  assertEquals(sourceVlan, flow.getSource().getVlanId().longValue());
135  assertEquals(new SwitchId(destinationSwitch), flow.getDestination().getSwitchDpId());
136  assertEquals(destinationPort, flow.getDestination().getPortId().longValue());
137  assertEquals(destinationVlan, flow.getDestination().getVlanId().longValue());
138  assertEquals(bandwidth, flow.getMaximumBandwidth());
139  assertNotNull(flow.getLastUpdated());
140  }
141 
142  @Then("^flow (.*) with (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) could be updated with (\\d+)$")
143  public void checkFlowUpdate(final String flowId, final String sourceSwitch, final int sourcePort,
144  final int sourceVlan, final String destinationSwitch, final int destinationPort,
145  final int destinationVlan, final int band, final int newBand) throws Exception {
146  flowPayload.setMaximumBandwidth(newBand);
147 
148  FlowPayload response = FlowUtils.updateFlow(FlowUtils.getFlowName(flowId), flowPayload);
149  assertNotNull(response);
150  response.setLastUpdated(null);
151 
152  assertEquals(flowPayload, response);
153 
154  checkFlowCreation(flowId, sourceSwitch, sourcePort, sourceVlan, destinationSwitch,
155  destinationPort, destinationVlan, newBand);
156  }
157 
158  @Then("^flow (.*) with (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) could be deleted$")
159  public void checkFlowDeletion(final String flowId, final String sourceSwitch, final int sourcePort,
160  final int sourceVlan, final String destinationSwitch, final int destinationPort,
161  final int destinationVlan, final int bandwidth) throws Exception {
162  int unknownFlowCount = -1; // use -1 to communicate "I don't know what it should be")
163  int expectedFlowCount = getFlowCount(unknownFlowCount) - 2;
164 
166  assertNotNull(response);
167  response.setLastUpdated(null);
168 
169  assertEquals(flowPayload, response);
170 
172  if (flow != null) {
173  TimeUnit.SECONDS.sleep(2);
174  flow = FlowUtils.getFlow(FlowUtils.getFlowName(flowId));
175  }
176 
177  assertNull(flow);
178 
179  int actualFlowCount = getFlowCount(expectedFlowCount);
180  assertEquals(expectedFlowCount, actualFlowCount);
181  }
182 
183  @Then("^validation of flow (.*) is successful with no discrepancies$")
184  public void checkRulesInstalled(final String flowName) {
185  String flowId = FlowUtils.getFlowName(flowName);
186  List<FlowValidationDto> flowValidationResult = FlowUtils.validateFlow(flowId);
187 
188  List<String> discrepancies = flowValidationResult.stream()
189  .peek(flowValidation -> {
190  assertEquals(flowId, flowValidation.getFlowId());
191  })
192  .flatMap(item -> item.getDiscrepancies().stream())
193  //TODO: We have to skip discrepancies in meters because don't install them in Mininet.
194  .filter(item -> !item.getField().equals("meterId"))
195  .map(PathDiscrepancyDto::toString)
196  .collect(Collectors.toList());
197 
198  assertThat("The flow has discrepancies.", discrepancies, empty());
199 
200  //flowValidationResult.forEach(flowValidation ->
201  // assertTrue(format("The flow %s didn't pass validation.", flowId), flowValidation.getAsExpected())
202  //);
203  }
204 
205  @Then("^validation of flow (.*) has completed with (\\d+) discrepancies on ([\\w:,]+) switches found$")
206  public void checkRulesHaveDiscrepancies(final String flowName, int discrepancyCount, String switches) {
207  String flowId = FlowUtils.getFlowName(flowName);
208  List<FlowValidationDto> flowValidationResults = FlowUtils.validateFlow(flowId);
209 
210  List<String> discrepancies = flowValidationResults.stream()
211  .flatMap(item -> item.getDiscrepancies().stream())
212  .map(PathDiscrepancyDto::getRule)
213  .collect(Collectors.toList());
214 
215  assertEquals(discrepancyCount, discrepancies.size());
216 
217  @SuppressWarnings("unchecked")
218  Matcher<String>[] expectedSwitches = Arrays.stream(switches.split(","))
219  .map(Matchers::containsString)
220  .toArray(Matcher[]::new);
221  assertThat("The discrepancies doesn't contain expected switches.", discrepancies, hasItems(expectedSwitches));
222  }
223 
224  @Then("^rules with (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) are installed$")
225  public void checkRulesInstall(final String sourceSwitch, final int sourcePort, final int sourceVlan,
226  final String destinationSwitch, final int destinationPort, final int destinationVlan,
227  final int bandwidth) throws Throwable {
228  // TODO: implement
229  }
230 
231  @Then("^rules with (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) are updated with (\\d+)$")
232  public void checkRulesUpdate(final String sourceSwitch, final int sourcePort, final int sourceVlan,
233  final String destinationSwitch, final int destinationPort, final int destinationVlan,
234  final int bandwidth, final int newBandwidth) throws Throwable {
235  // TODO: implement
236  }
237 
238  @Then("^rules with (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) are deleted$")
239  public void checkRulesDeletion(final String sourceSwitch, final int sourcePort, final int sourceVlan,
240  final String destinationSwitch, final int destinationPort, final int destinationVlan,
241  final int bandwidth) throws Throwable {
242  // TODO: implement
243  }
244 
245  private int checkTraffic(String sourceSwitch, String destSwitch,
246  int sourceVlan, int destinationVlan, int expectedStatus) {
247  if (isTrafficTestsEnabled()) {
248  System.out.print("=====> Send traffic");
249 
250  long current = System.currentTimeMillis();
251  Client client = ClientBuilder.newClient(new ClientConfig());
252 
253  // NOTE: current implementation requires two auxiliary switches in
254  // topology, one for generating traffic, another for receiving it.
255  // Originaly smallest meaningful topology was supposed to consist
256  // of three switches, thus switches 1 and 5 were used as auxiliary.
257  // Now some scenarios require even smaller topologies and at the same
258  // time they reuse small linear topology. This leads to shutting off of
259  // switches 1 and 5 from flows and to test failures. Since topology
260  // reuse speeds testing up the code below determines which switch:port
261  // pairs should be used as source and drains for traffic while keepig
262  // small linear topology in use.
263  int fromNum = Integer.parseInt(sourceSwitch.substring(sourceSwitch.length() - 1));
264  int toNum = Integer.parseInt(destSwitch.substring(destSwitch.length() - 1));
265  String from = "0000000" + (fromNum - 1);
266  String to = "0000000" + (toNum + 1);
267  int fromPort = from.equals("00000001") ? 1 : 2;
268  int toPort = 1;
269  System.out.println(format("from:%s:%d::%d via %s, To:%s:%d::%d via %s",
270  from, fromPort, sourceVlan, sourceSwitch,
271  to, toPort, destinationVlan, destSwitch));
272 
273 
274  Response result = client
275  .target(trafficEndpoint)
276  .path("/checkflowtraffic")
277  .queryParam("srcswitch", from)
278  .queryParam("dstswitch", to)
279  .queryParam("srcport", fromPort)
280  .queryParam("dstport", toPort)
281  .queryParam("srcvlan", sourceVlan)
282  .queryParam("dstvlan", destinationVlan)
283  .request()
284  .get();
285 
286  System.out.println(format("======> Response = %s", result.toString()));
287  System.out.println(format("======> Send traffic Time: %,.3f", getTimeDuration(current)));
288 
289  return result.getStatus();
290  } else {
291  return expectedStatus;
292  }
293  }
294 
295 
296  private int checkPingTraffic(String sourceSwitch, String destSwitch,
297  int sourceVlan, int destinationVlan, int expectedStatus) {
298  if (isTrafficTestsEnabled()) {
299  System.out.print("=====> Send PING traffic");
300 
301  long current = System.currentTimeMillis();
302  Client client = ClientBuilder.newClient(new ClientConfig());
303 
304  // NOTE: current implementation requires two auxiliary switches in
305  // topology, one for generating traffic, another for receiving it.
306  // Originaly smallest meaningful topology was supposed to consist
307  // of three switches, thus switches 1 and 5 were used as auxiliary.
308  // Now some scenarios require even smaller topologies and at the same
309  // time they reuse small linear topology. This leads to shutting off of
310  // switches 1 and 5 from flows and to test failures. Since topology
311  // reuse speeds testing up the code below determines which switch:port
312  // pairs should be used as source and drains for traffic while keepig
313  // small linear topology in use.
314  int fromNum = Integer.parseInt(sourceSwitch.substring(sourceSwitch.length() - 1));
315  int toNum = Integer.parseInt(destSwitch.substring(destSwitch.length() - 1));
316  String from = "0000000" + (fromNum - 1);
317  String to = "0000000" + (toNum + 1);
318  int fromPort = from.equals("00000001") ? 1 : 2;
319  int toPort = 1;
320  System.out.println(format("from:%s:%d::%d via %s, To:%s:%d::%d via %s",
321  from, fromPort, sourceVlan, sourceSwitch,
322  to, toPort, destinationVlan, destSwitch));
323 
324 
325  Response result = client
326  .target(mininetEndpoint)
327  .path("/checkpingtraffic")
328  .queryParam("srcswitch", from)
329  .queryParam("dstswitch", to)
330  .queryParam("srcport", fromPort)
331  .queryParam("dstport", toPort)
332  .queryParam("srcvlan", sourceVlan)
333  .queryParam("dstvlan", destinationVlan)
334  .request()
335  .get();
336 
337  int status = result.getStatus();
338  String body = result.readEntity(String.class);
339  System.out.println(format("======> Response = %s, BODY = %s", result.toString(), body));
340  System.out.println(format("======> Send traffic Time: %,.3f", getTimeDuration(current)));
341 
342  if (body.equals("NOOP")) {
343  return expectedStatus;
344  } else {
345  return status;
346  }
347  } else {
348  return expectedStatus;
349  }
350  }
351 
352 
353  /*
354  * NB: This test uses SCAPY on mininet_rest .. and has been deprecated in favor of pingable.
355  * One of the reasons it was deprecated was due to unresolved issues in testing
356  * single switch scenarios.
357  */
358  @Then("^traffic through (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) is forwarded$")
359  public void checkTrafficIsForwarded(final String sourceSwitch, final int sourcePort, final int sourceVlan,
360  final String destinationSwitch, final int destinationPort,
361  final int destinationVlan, final int bandwidth) throws Throwable {
362  TimeUnit.SECONDS.sleep(2);
363  int status = checkTraffic(sourceSwitch, destinationSwitch, sourceVlan, destinationVlan, 200);
364  assertEquals(200, status);
365  }
366 
367  @Then("^traffic through (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) is not forwarded$")
368  public void checkTrafficIsNotForwarded(final String sourceSwitch, final int sourcePort, final int sourceVlan,
369  final String destinationSwitch, final int destinationPort,
370  final int destinationVlan, final int bandwidth) throws Throwable {
371  TimeUnit.SECONDS.sleep(2);
372  int status = checkTraffic(sourceSwitch, destinationSwitch, sourceVlan, destinationVlan, 503);
373  assertNotEquals(200, status);
374  }
375 
376  /*
377  * NB: Pingable uses the native Mininet mechanisms to ping between hosts attached to switches
378  */
379  @Then("^traffic through (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) is pingable$")
380  public void checkTrafficIsPingable(final String sourceSwitch, final int sourcePort, final int sourceVlan,
381  final String destinationSwitch, final int destinationPort,
382  final int destinationVlan, final int bandwidth) throws Throwable {
383  TimeUnit.SECONDS.sleep(2);
384  int status = checkPingTraffic(sourceSwitch, destinationSwitch, sourceVlan, destinationVlan, 200);
385  assertEquals(200, status);
386  }
387 
388  @Then("^traffic through (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) is not pingable$")
389  public void checkTrafficIsNotPingable(final String sourceSwitch, final int sourcePort, final int sourceVlan,
390  final String destinationSwitch, final int destinationPort,
391  final int destinationVlan, final int bandwidth) throws Throwable {
392  TimeUnit.SECONDS.sleep(2);
393  int status = checkPingTraffic(sourceSwitch, destinationSwitch, sourceVlan, destinationVlan, 503);
394  assertNotEquals(200, status);
395  }
396 
397  @Then("^flows count is (\\d+)$")
398  public void checkFlowCount(int expectedFlowsCount) throws Exception {
399  int actualFlowCount = getFlowCount(expectedFlowsCount * 2);
400  assertEquals(expectedFlowsCount * 2, actualFlowCount);
401  }
402 
403  @When("^flow (.*) push request for (.*) is successful$")
404  public void successfulPushFlowFromResource(String flowId, String flowResource) throws Exception {
405  FlowInfoData flowInfoData = new ObjectMapper()
406  .readValue(getClass().getResourceAsStream(flowResource), FlowInfoData.class);
407 
408  // Overwrite the flow ID.
409  String flowName = FlowUtils.getFlowName(flowId);
410  flowInfoData.setFlowId(flowName);
411  flowInfoData.getPayload().getLeft().setFlowId(flowName);
412  flowInfoData.getPayload().getRight().setFlowId(flowName);
413 
414  BatchResults result = FlowUtils.pushFlow(flowInfoData, true);
415  assertNotNull(result);
416  assertEquals(0, result.getFailures());
417  assertEquals(2, result.getSuccesses()); // 2 separate requests into TE and Flow Topology
418  }
419 
427  private List<Flow> validateFlowStored(Flow expectedFlow) throws Exception {
428  List<Flow> flows = FlowUtils.dumpFlows();
429  flows.forEach(this::resetImmaterialFields);
430 
431  if (!flows.contains(expectedFlow) || flows.size() % 2 != 0) {
432  TimeUnit.SECONDS.sleep(2);
433  flows = FlowUtils.dumpFlows();
434  flows.forEach(this::resetImmaterialFields);
435  }
436 
437  return flows;
438  }
439 
446  private int getFlowCount(int expectedFlowsCount) throws Exception {
447  List<Flow> flows = FlowUtils.dumpFlows();
448 
449  // pass in -1 if the count is unknown
450  if (expectedFlowsCount >= 0) {
451  int arbitraryCount = 3;
452  for (int i = 0; i < arbitraryCount; i++) {
453  System.out.println(format("\n=====> Flow Count is %d, expecting %d",
454  flows.size(), expectedFlowsCount));
455  if (expectedFlowsCount == flows.size()) {
456  break;
457  }
458  TimeUnit.SECONDS.sleep(2);
459  flows = FlowUtils.dumpFlows();
460  }
461  if (expectedFlowsCount != flows.size()) {
462  System.out.println(format("\n=====> FLOW COUNT doesn't match, flows: %s",
463  flows.toString()));
464  }
465  }
466  return flows.size();
467  }
468 
469  private void resetImmaterialFields(Flow flow) {
470  flow.setTransitVlan(0);
471  flow.setMeterId(0);
472  flow.setCookie(0);
473  flow.setLastUpdated(null);
474  flow.setFlowPath(null);
475  flow.setState(null);
476  }
477 }
void successfulPushFlowFromResource(String flowId, String flowResource)
static FlowPayload updateFlow(final String flowId, final FlowPayload payload)
Definition: FlowUtils.java:200
void setMaximumBandwidth(long maximumBandwidth)
void checkFlowRead(final String flowId, final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
void checkTrafficIsForwarded(final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
void checkFlowCreation(final String flowId, final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
static boolean isTrafficTestsEnabled()
Definition: FlowUtils.java:612
static FlowPayload deleteFlow(final String flowId)
Definition: FlowUtils.java:238
void checkTrafficIsNotForwarded(final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
static List< Flow > dumpFlows()
Definition: FlowUtils.java:444
void checkFlowDeletion(final String flowId, final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
def status()
Definition: rest.py:593
void checkFlowUpdate(final String flowId, final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int band, final int newBand)
void checkRulesInstall(final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
ImmutablePair< Flow, Flow > getPayload()
void checkRulesHaveDiscrepancies(final String flowName, int discrepancyCount, String switches)
void checkTrafficIsPingable(final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
static boolean CreateMininetTopology(String json)
list result
Definition: plan-d.py:72
void successfulFlowCreation(final String flowId, final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
static FlowPayload getFlow(final String flowId)
Definition: FlowUtils.java:126
static List< FlowValidationDto > validateFlow(final String flowId)
Definition: FlowUtils.java:750
void checkTrafficIsNotPingable(final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
static FlowPayload putFlow(final FlowPayload payload)
Definition: FlowUtils.java:163
void failedFlowCreation(final String flowId, final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
void checkRulesDeletion(final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
static BatchResults pushFlow(FlowInfoData flowInfo, boolean propagate)
Definition: FlowUtils.java:786
void checkRulesInstalled(final String flowName)
static String getFlowName(final String flowId)
Definition: FlowUtils.java:595
void checkRulesUpdate(final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth, final int newBandwidth)
static double getTimeDuration(final long current)
Definition: FlowUtils.java:605