16 package org.openkilda.flow;
18 import static java.lang.String.format;
19 import static java.util.Base64.getEncoder;
20 import static java.util.Collections.singletonList;
21 import static org.junit.Assert.assertEquals;
52 import com.fasterxml.jackson.core.JsonProcessingException;
53 import com.fasterxml.jackson.core.type.TypeReference;
54 import com.fasterxml.jackson.databind.ObjectMapper;
55 import org.glassfish.jersey.client.ClientConfig;
56 import org.glassfish.jersey.client.HttpUrlConnectorProvider;
57 import org.glassfish.jersey.jackson.JacksonFeature;
59 import java.io.IOException;
60 import java.util.ArrayList;
61 import java.util.Collections;
62 import java.util.HashSet;
63 import java.util.List;
65 import java.util.concurrent.TimeUnit;
66 import javax.ws.rs.client.Client;
67 import javax.ws.rs.client.ClientBuilder;
68 import javax.ws.rs.client.Entity;
69 import javax.ws.rs.core.GenericType;
70 import javax.ws.rs.core.HttpHeaders;
71 import javax.ws.rs.core.MediaType;
72 import javax.ws.rs.core.Response;
76 private static final String auth = topologyUsername +
":" + topologyPassword;
77 private static final String authHeaderValue =
"Basic " + getEncoder().encodeToString(auth.getBytes());
78 private static final String FEATURE_TIME = String.valueOf(System.currentTimeMillis());
79 private static final int WAIT_ATTEMPTS = 10;
80 private static final int WAIT_DELAY = 2;
85 return ClientBuilder.newClient(
new ClientConfig()).register(JacksonFeature.class);
92 System.out.println(
"\n==> Northbound Health-Check");
94 long current = System.currentTimeMillis();
97 Response response = client
98 .target(northboundEndpoint)
99 .path(
"/api/v1/health-check")
100 .request(MediaType.APPLICATION_JSON)
101 .header(HttpHeaders.AUTHORIZATION, authHeaderValue)
105 System.out.println(
format(
"===> Response = %s", response.toString()));
108 int responseCode = response.getStatus();
109 if (responseCode == 200) {
110 System.out.println(
format(
"====> Health-Check = %s",
113 System.out.println(
format(
"====> Error: Health-Check = %s",
127 System.out.println(
"\n==> Northbound Get Flow");
129 long current = System.currentTimeMillis();
132 Response response = client
133 .target(northboundEndpoint)
134 .path(
"/api/v1/flows")
136 .resolveTemplate(
"flowid", flowId)
137 .request(MediaType.APPLICATION_JSON)
138 .header(HttpHeaders.AUTHORIZATION, authHeaderValue)
142 System.out.println(
format(
"===> Response = %s", response.toString()));
145 int responseCode = response.getStatus();
146 if (responseCode == 200) {
148 System.out.println(
format(
"====> Northbound Get Flow = %s", flow));
151 System.out.println(
format(
"====> Error: Northbound Get Flow = %s",
164 System.out.println(
"\n==> Northbound Create Flow");
166 long current = System.currentTimeMillis();
169 Response response = client
170 .target(northboundEndpoint)
171 .path(
"/api/v1/flows")
172 .request(MediaType.APPLICATION_JSON)
173 .header(HttpHeaders.AUTHORIZATION, authHeaderValue)
175 .put(Entity.json(payload));
177 System.out.println(
format(
"===> Request Payload = %s", Entity.json(payload).getEntity()));
178 System.out.println(
format(
"===> Response = %s", response.toString()));
181 int responseCode = response.getStatus();
182 if (responseCode == 200) {
184 System.out.println(
format(
"====> Northbound Create Flow = %s", flow));
187 System.out.println(
format(
"====> Error: Northbound Create Flow = %s",
201 System.out.println(
"\n==> Northbound Update Flow");
203 long current = System.currentTimeMillis();
206 Response response = client
207 .target(northboundEndpoint)
208 .path(
"/api/v1/flows")
210 .resolveTemplate(
"flowid", flowId)
211 .request(MediaType.APPLICATION_JSON)
212 .header(HttpHeaders.AUTHORIZATION, authHeaderValue)
214 .put(Entity.json(payload));
216 System.out.println(
format(
"===> Request Payload = %s", Entity.json(payload).getEntity()));
217 System.out.println(
format(
"===> Response = %s", response.toString()));
220 int responseCode = response.getStatus();
221 if (responseCode == 200) {
223 System.out.println(
format(
"====> Northbound Update Flow = %s", flow));
226 System.out.println(
format(
"====> Error: Northbound Update Flow = %s",
239 System.out.println(
"\n==> Northbound Delete Flow");
241 long current = System.currentTimeMillis();
244 Response response = client
245 .target(northboundEndpoint)
246 .path(
"/api/v1/flows")
248 .resolveTemplate(
"flowid", flowId)
249 .request(MediaType.APPLICATION_JSON)
250 .header(HttpHeaders.AUTHORIZATION, authHeaderValue)
254 System.out.println(
format(
"===> Response = %s", response.toString()));
257 int responseCode = response.getStatus();
258 if (responseCode == 200) {
260 System.out.println(
format(
"====> Northbound Delete Flow = %s", flow));
263 System.out.println(
format(
"====> Error: Northbound Delete Flow = %s",
276 System.out.println(
"\n==> Northbound Get Flow Path");
278 long current = System.currentTimeMillis();
281 Response response = client
282 .target(northboundEndpoint)
283 .path(
"/api/v1/flows/{flowid}/path")
284 .resolveTemplate(
"flowid", flowId)
285 .request(MediaType.APPLICATION_JSON)
286 .header(HttpHeaders.AUTHORIZATION, authHeaderValue)
290 System.out.println(
format(
"===> Response = %s", response.toString()));
293 int responseCode = response.getStatus();
294 if (responseCode == 200) {
296 System.out.println(
format(
"====> Northbound Get Flow Path = %s", flowPath));
299 System.out.println(
format(
"====> Error: Northbound Get Flow Path = %s",
327 for (
int i = 0;
i < WAIT_ATTEMPTS;
i++) {
329 if (current != null && expected.equals(current.getStatus())) {
332 TimeUnit.SECONDS.sleep(WAIT_DELAY);
342 for (
int attempt = 0; attempt < WAIT_ATTEMPTS; attempt += 1) {
343 Response response = doGetFlowStatusRequest(flowId);
344 int status = response.getStatus();
347 TimeUnit.SECONDS.sleep(WAIT_DELAY);
354 format(
"Flow status request for flow %s ens with %d", flowId,
status));
368 Response response = doGetFlowStatusRequest(flowId);
370 int responseCode = response.getStatus();
371 if (responseCode != 200) {
372 System.out.println(
format(
"====> Error: Northbound Get Flow Status = %s",
379 private static Response doGetFlowStatusRequest(
final String flowId) {
380 System.out.println(
"\n==> Northbound Get Flow Status");
382 long current = System.currentTimeMillis();
385 Response response = client
386 .target(northboundEndpoint)
387 .path(
"/api/v1/flows/status")
389 .resolveTemplate(
"flowid", flowId)
390 .request(MediaType.APPLICATION_JSON)
391 .header(HttpHeaders.AUTHORIZATION, authHeaderValue)
395 System.out.println(
format(
"===> Response = %s", response.toString()));
398 int status = response.getStatus();
399 System.out.println(
format(
"====> Northbound Get Flow Status = %s",
status));
410 System.out.println(
"\n==> Northbound Get Flow Dump");
412 long current = System.currentTimeMillis();
415 Response response = client
416 .target(northboundEndpoint)
417 .path(
"/api/v1/flows")
418 .request(MediaType.APPLICATION_JSON)
419 .header(HttpHeaders.AUTHORIZATION, authHeaderValue)
423 System.out.println(
format(
"===> Response = %s", response.toString()));
426 int responseCode = response.getStatus();
427 if (responseCode == 200) {
428 List<FlowPayload> flows = response.readEntity(
new GenericType<List<FlowPayload>>() {
430 System.out.println(
format(
"====> Northbound Get Flow Dump = %d", flows.size()));
433 System.out.println(
format(
"====> Error: Northbound Get Flow Dump = %s",
435 return Collections.emptyList();
445 System.out.println(
"\n==> Topology-Engine Dump Flows");
447 long current = System.currentTimeMillis();
450 Response response = client
451 .target(topologyEndpoint)
452 .path(
"/api/v1/topology/flows")
454 .header(HttpHeaders.AUTHORIZATION, authHeaderValue)
457 System.out.println(
format(
"===> Response = %s", response.toString()));
461 List<Flow> flows =
new ObjectMapper().readValue(response.readEntity(String.class),
462 new TypeReference<List<Flow>>() {
464 System.out.println(
format(
"====> Topology-Engine Dump Flows = %d", flows.size()));
468 }
catch (IOException ex) {
479 System.out.println(
"\n==> Topology-Engine Link Bandwidth");
481 long current = System.currentTimeMillis();
484 Response response = client
485 .target(topologyEndpoint)
486 .path(
"/api/v1/topology/links/bandwidth/")
487 .path(
"{src_switch}")
489 .resolveTemplate(
"src_switch", srcSwitch)
490 .resolveTemplate(
"src_port", srcPort)
492 .header(HttpHeaders.AUTHORIZATION, authHeaderValue)
495 System.out.println(
format(
"===> Response = %s", response.toString()));
496 System.out.println(
format(
"===> Topology-Engine Link Bandwidth Time: %,.3f",
getTimeDuration(current)));
499 Integer bandwidth =
new ObjectMapper().readValue(response.readEntity(String.class), Integer.class);
500 System.out.println(
format(
"====> Link switch=%s port=%s bandwidth=%d", srcSwitch, srcPort, bandwidth));
503 }
catch (IOException ex) {
512 System.out.println(
"\n==> Topology-Engine Restore Flows");
514 long current = System.currentTimeMillis();
517 Response response = client
518 .target(topologyEndpoint)
519 .path(
"/api/v1/flows/restore")
521 .header(HttpHeaders.AUTHORIZATION, authHeaderValue)
524 System.out.println(
format(
"===> Response = %s", response.toString()));
525 System.out.println(
format(
"===> Topology-Engine Restore Flows Time: %,.3f",
getTimeDuration(current)));
533 Set<String> flows =
new HashSet<>();
542 System.out.println(
format(
"=====> Cleanup Flows, nbflow count = %d",
545 nbFlows.forEach(flow -> flows.add(flow.getId()));
548 List<Flow> tpeFlows =
new ArrayList<>();
549 for (
int i = 0;
i < 10; ++
i) {
551 if (tpeFlows.size() == nbFlows.size() * 2) {
552 tpeFlows.forEach(flow -> flows.add(flow.getFlowId()));
555 TimeUnit.SECONDS.sleep(2);
557 System.out.println(
format(
"=====> Cleanup Flows, tpeFlows count = %d",
566 for (
int i = 0;
i < 10; ++
i) {
567 TimeUnit.SECONDS.sleep(2);
570 if (nbCount == 0 && terCount == 0) {
575 assertEquals(0, nbCount);
576 assertEquals(0, terCount);
583 }
catch (Exception exception) {
584 System.out.println(
format(
"Error during flow deletion: %s", exception.getMessage()));
585 exception.printStackTrace();
596 return format(
"%s-%s", flowId, FEATURE_TIME);
606 return (System.currentTimeMillis() - current) / 1000.0;
613 boolean isEnabled = Boolean.valueOf(System.getProperty(
"traffic",
"true"));
614 System.out.println(
format(
"\n=====> Traffic check is %s", isEnabled ?
"enabled" :
"disabled"));
622 System.out.println(
"\n==> toggle features status");
628 .target(northboundEndpoint)
629 .path(
"/api/v1/features")
630 .request(MediaType.APPLICATION_JSON)
631 .header(HttpHeaders.AUTHORIZATION, authHeaderValue)
633 .post(Entity.json(desired));
635 System.out.println(
format(
"===> Response = %s", response.toString()));
637 if (response.getStatus() != 200) {
638 System.out.println(
format(
"====> Error: Northbound Create Flow = POST status: %s", response.getStatus()));
643 .target(northboundEndpoint)
644 .path(
"/api/v1/features")
645 .request(MediaType.APPLICATION_JSON)
646 .header(HttpHeaders.AUTHORIZATION, authHeaderValue)
649 if (response.getStatus() != 200) {
650 System.out.println(
format(
"====> Error: Northbound Create Flow = GET status: %s", response.getStatus()));
661 System.out.println(
"\n==> Northbound Sync Flow Cache");
663 long current = System.currentTimeMillis();
666 client.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND,
true);
668 Response response = client
669 .target(northboundEndpoint)
670 .path(
"/api/v1/flows/cache")
671 .request(MediaType.APPLICATION_JSON)
672 .header(HttpHeaders.AUTHORIZATION, authHeaderValue)
678 if (response.getStatus() != 200) {
679 System.out.println(
format(
"====> Error: Northbound Sync Flow Cache = PATCH status: %s",
680 response.getStatus()));
684 System.out.println(
format(
"===> Response = %s", response.toString()));
692 System.out.println(
"\n==> Northbound Invalidate Flow Cache");
694 long current = System.currentTimeMillis();
697 Response response = client
698 .target(northboundEndpoint)
699 .path(
"/api/v1/flows/cache")
700 .request(MediaType.APPLICATION_JSON)
701 .header(HttpHeaders.AUTHORIZATION, authHeaderValue)
705 System.out.println(
format(
"===> Northbound Invalidate Flow Cache Time: %,.3f",
getTimeDuration(current)));
707 if (response.getStatus() != 200) {
709 format(
"====> Error: Northbound Invalidate Flow Cache = PATCH status: %s", response.getStatus()));
713 System.out.println(
format(
"===> Response = %s", response.toString()));
721 System.out.println(
"\n==> TopologyEngine Delete Flow");
723 long current = System.currentTimeMillis();
726 Response response = client
727 .target(topologyEndpoint)
728 .path(
"/api/v1/flow/{flowid}")
729 .resolveTemplate(
"flowid", flowId)
730 .request(MediaType.APPLICATION_JSON)
731 .header(HttpHeaders.AUTHORIZATION, authHeaderValue)
736 int status = response.getStatus();
738 System.out.println(String.format(
"====> Error: TopologyEngine Delete Flow = %s",
739 response.readEntity(String.class)));
743 System.out.println(
format(
"====> TopologyEngine Delete Flow = %s", response.readEntity(String.class)));
750 public static List<FlowValidationDto>
validateFlow(
final String flowId) {
751 System.out.println(
"\n==> Northbound Validate Flow");
753 Client client = ClientBuilder.newClient(
new ClientConfig());
755 Response response = client
756 .target(northboundEndpoint)
757 .path(
"/api/v1/flows/{flow-id}/validate")
758 .resolveTemplate(
"flow-id", flowId)
759 .request(MediaType.APPLICATION_JSON)
760 .header(HttpHeaders.AUTHORIZATION, authHeaderValue)
764 System.out.println(
format(
"===> Response = %s", response.toString()));
766 int responseCode = response.getStatus();
767 if (responseCode == 200) {
768 List<FlowValidationDto> flowDiscrepancy =
769 response.readEntity(
new GenericType<List<FlowValidationDto>>() {});
770 System.out.println(
format(
"====> Northbound Validate Flow = %s", flowDiscrepancy));
771 return flowDiscrepancy;
773 System.out.println(
format(
"====> Error: Northbound Validate Flow = %s",
787 throws JsonProcessingException {
788 System.out.println(
"\n==> Northbound Push Flow");
790 long current = System.currentTimeMillis();
793 String correlationId = String.valueOf(current);
794 flowInfo.setCorrelationId(correlationId);
796 String requestJson =
new ObjectMapper().writerFor(
new TypeReference<List<FlowInfoData>>() { })
797 .writeValueAsString(singletonList(flowInfo));
799 Response response = client
800 .target(northboundEndpoint)
801 .path(
"/api/v1/push/flows")
802 .queryParam(
"propagate", propagate)
803 .request(MediaType.APPLICATION_JSON)
804 .header(HttpHeaders.AUTHORIZATION, authHeaderValue)
806 .put(Entity.json(requestJson));
808 System.out.println(
format(
"===> Request Payload = %s", requestJson));
809 System.out.println(
format(
"===> Response = %s", response.toString()));
812 int responseCode = response.getStatus();
813 if (responseCode == 200) {
815 System.out.println(
format(
"====> Northbound Push Flow = %s",
result));
818 System.out.println(
format(
"====> Error: Northbound Push Flow = %s",
828 long currentTime = System.currentTimeMillis();
829 String correlationId = String.valueOf(currentTime);
831 System.out.println(String.format(
"\n==> Northbound verify Flow request (correlationId: %s)", correlationId));
832 Response response = client
833 .target(northboundEndpoint)
834 .path(
"/api/v1/flows/{id}/verify")
835 .resolveTemplate(
"id", flowId)
836 .request(MediaType.APPLICATION_JSON)
837 .header(HttpHeaders.AUTHORIZATION, authHeaderValue)
839 .method(
"PUT", Entity.json(payload));
841 System.out.println(
format(
"===> Response = %s", response.toString()));
844 int responseCode = response.getStatus();
845 if (responseCode == 200) {
847 System.out.println(
format(
"====> Northbound VERIFY Flow = %s",
result));
850 System.out.println(
format(
"====> Error: Northbound VERIFY Flow = %s",
static FlowPayload updateFlow(final String flowId, final FlowPayload payload)
static VerificationOutput verifyFlow(String flowId, VerificationInput payload)
static boolean deleteFlowViaTe(final String flowId)
static List< FlowPayload > getFlowDump()
static final String topologyUsername
static boolean isTrafficTestsEnabled()
static Client clientFactory()
static FlowPayload deleteFlow(final String flowId)
ImmutablePair< PathInfoData, PathInfoData > getPath(Flow flow, AvailableNetwork network, Strategy strategy)
static List< Flow > dumpFlows()
static FlowPathPayload getFlowPath(final String flowId)
static FlowIdStatusPayload getFlowStatus(final String flowId)
static void cleanupFlows()
static FlowCacheSyncResults invalidateFlowCache()
static final String CORRELATION_ID
static FlowPayload getFlow(final String flowId)
static List< FlowValidationDto > validateFlow(final String flowId)
static void waitFlowDeletion(String flowId)
static FeatureTogglePayload updateFeaturesStatus(FeatureTogglePayload desired)
static FlowPayload putFlow(final FlowPayload payload)
static final Auth neoAuth
static int getHealthCheck()
static BatchResults pushFlow(FlowInfoData flowInfo, boolean propagate)
static final String topologyEndpoint
static FlowCacheSyncResults syncFlowCache()
static FlowIdStatusPayload waitFlowStatus(String flowName, FlowState expected)
static void restoreFlows()
static String getFlowName(final String flowId)
static final String topologyPassword
static final String northboundEndpoint
static double getTimeDuration(final long current)
static ImmutablePair< PathInfoData, PathInfoData > getFlowPath(Flow flow)
static Integer getLinkBandwidth(final SwitchId srcSwitch, final String srcPort)