Skip to content

Commit

Permalink
refactor to use redirect-handling webClient extensions, ensure selfte…
Browse files Browse the repository at this point in the history
…st target cleanup
  • Loading branch information
andrewazores committed Nov 23, 2023
1 parent 97f535b commit 1f2da3a
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 156 deletions.
2 changes: 1 addition & 1 deletion src/test/java/itest/UploadRecordingTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public void shouldLoadRecordingToDatasource() throws Exception {
"/api/v1/targets/%s/recordings/%s/upload",
getSelfReferenceConnectUrlEncoded(), RECORDING_NAME),
true,
null,
(Buffer) null,
0);

MatcherAssert.assertThat(resp.statusCode(), Matchers.equalTo(200));
Expand Down
214 changes: 64 additions & 150 deletions src/test/java/itest/bases/StandardSelfTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@

public abstract class StandardSelfTest {

private static final String SELF_JMX_URL = "service:jmx:rmi:///jndi/rmi://localhost:0/jmxrmi";
private static final String SELFTEST_ALIAS = "selftest";
public static final String SELF_JMX_URL = "service:jmx:rmi:///jndi/rmi://localhost:0/jmxrmi";
public static final String SELFTEST_ALIAS = "selftest";
private static final ExecutorService WORKER = Executors.newCachedThreadPool();
public static final Logger logger = Logger.getLogger(StandardSelfTest.class);
public static final ObjectMapper mapper = new ObjectMapper();
Expand All @@ -81,62 +81,36 @@ public static void assertPostconditions() throws Exception {
}

public static void assertNoRecordings() throws Exception {
CompletableFuture<JsonArray> listFuture = new CompletableFuture<>();
webClient
.get(
String.format(
"/api/v1/targets/%s/recordings",
getSelfReferenceConnectUrlEncoded()))
.basicAuthentication("user", "pass")
.send(
ar -> {
if (assertRequestStatus(ar, listFuture)) {
listFuture.complete(ar.result().bodyAsJsonArray());
}
});
JsonArray listResp = listFuture.get(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS);
JsonArray listResp =
webClient
.extensions()
.get(
String.format(
"/api/v1/targets/%s/recordings",
getSelfReferenceConnectUrlEncoded()),
true,
REQUEST_TIMEOUT_SECONDS)
.bodyAsJsonArray();
if (!listResp.isEmpty()) {
throw new ITestCleanupFailedException(
String.format("Unexpected recordings:\n%s", listResp.encodePrettily()));
}
}

// @AfterAll
public static void deleteSelfCustomTarget() {
if (StringUtils.isBlank(selfCustomTargetLocation)) {
@AfterAll
public static void deleteSelfCustomTarget()
throws InterruptedException, ExecutionException, TimeoutException {
if (!selfCustomTargetExists()) {
return;
}
logger.infov("Deleting self custom target at {0}", selfCustomTargetLocation);
String path = URI.create(selfCustomTargetLocation).getPath();
CompletableFuture<String> future = new CompletableFuture<>();
try {
WORKER.submit(
() -> {
webClient
.delete(path)
.basicAuthentication("user", "pass")
.timeout(TimeUnit.SECONDS.toMillis(REQUEST_TIMEOUT_SECONDS))
.send(
ar -> {
if (ar.failed()) {
logger.error(ar.cause());
future.completeExceptionally(ar.cause());
return;
}
HttpResponse<Buffer> resp = ar.result();
logger.infov(
"DELETE {0} -> HTTP {1} {2}: [{3}]",
path,
resp.statusCode(),
resp.statusMessage(),
resp.headers());
future.complete(null);
});
});
selfCustomTargetLocation = future.get(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS);
} catch (Exception e) {
logger.error(e);
}
HttpResponse<Buffer> resp =
webClient.extensions().delete(path, true, REQUEST_TIMEOUT_SECONDS);
logger.infov(
"DELETE {0} -> HTTP {1} {2}: [{3}]",
path, resp.statusCode(), resp.statusMessage(), resp.headers());
selfCustomTargetLocation = null;
}

public static void waitForDiscovery(int otherTargetsCount) {
Expand Down Expand Up @@ -194,38 +168,21 @@ private static boolean selfCustomTargetExists() {
if (StringUtils.isBlank(selfCustomTargetLocation)) {
return false;
}
CompletableFuture<Boolean> future = new CompletableFuture<>();
try {
WORKER.submit(
() -> {
webClient
.getAbs(selfCustomTargetLocation)
.basicAuthentication("user", "pass")
.timeout(TimeUnit.SECONDS.toMillis(REQUEST_TIMEOUT_SECONDS))
.send(
ar -> {
if (ar.failed()) {
logger.error(ar.cause());
future.completeExceptionally(ar.cause());
return;
}
HttpResponse<Buffer> resp = ar.result();
logger.infov(
"POST /api/v2/targets -> HTTP {0} {1}: [{2}]",
resp.statusCode(),
resp.statusMessage(),
resp.headers());
future.complete(
HttpStatusCodeIdentifier.isSuccessCode(
resp.statusCode()));
});
});
boolean result = future.get(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS);
HttpResponse<Buffer> resp =
webClient
.extensions()
.get(selfCustomTargetLocation, true, REQUEST_TIMEOUT_SECONDS);
logger.infov(
"POST /api/v2/targets -> HTTP {0} {1}: [{2}]",
resp.statusCode(), resp.statusMessage(), resp.headers());
boolean result = HttpStatusCodeIdentifier.isSuccessCode(resp.statusCode());
if (!result) {
selfCustomTargetLocation = null;
}
return result;
} catch (Exception e) {
selfCustomTargetLocation = null;
logger.error(e);
return false;
}
Expand All @@ -236,88 +193,45 @@ private static void tryDefineSelfCustomTarget() {
return;
}
logger.info("Trying to define self-referential custom target...");
CompletableFuture<String> future = new CompletableFuture<>();
JsonObject self =
new JsonObject(Map.of("connectUrl", SELF_JMX_URL, "alias", SELFTEST_ALIAS));
HttpResponse<Buffer> resp;
try {
JsonObject self =
new JsonObject(Map.of("connectUrl", SELF_JMX_URL, "alias", SELFTEST_ALIAS));
WORKER.submit(
() -> {
webClient
.post("/api/v2/targets")
.basicAuthentication("user", "pass")
.timeout(TimeUnit.SECONDS.toMillis(REQUEST_TIMEOUT_SECONDS))
.sendJson(
self,
ar -> {
if (ar.failed()) {
logger.error(ar.cause());
future.completeExceptionally(ar.cause());
return;
}
HttpResponse<Buffer> resp = ar.result();
logger.infov(
"POST /api/v2/targets -> HTTP {0} {1}: [{2}]",
resp.statusCode(),
resp.statusMessage(),
resp.headers());
if (HttpStatusCodeIdentifier.isSuccessCode(
resp.statusCode())) {
future.complete(
resp.headers().get(HttpHeaders.LOCATION));
} else {
future.completeExceptionally(
new IllegalStateException(
Integer.toString(
resp.statusCode())));
}
});
});
selfCustomTargetLocation = future.get(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS);
} catch (Exception e) {
logger.error(e);
resp =
webClient
.extensions()
.post(
"/api/v2/targets",
true,
Buffer.buffer(self.encode()),
REQUEST_TIMEOUT_SECONDS);
logger.infov(
"POST /api/v2/targets -> HTTP {0} {1}: [{2}]",
resp.statusCode(), resp.statusMessage(), resp.headers());
if (!HttpStatusCodeIdentifier.isSuccessCode(resp.statusCode())) {
throw new IllegalStateException(Integer.toString(resp.statusCode()));
}
selfCustomTargetLocation =
URI.create(resp.headers().get(HttpHeaders.LOCATION)).getPath();
} catch (InterruptedException | ExecutionException | TimeoutException e) {
throw new IllegalStateException(e);
}
}

public static String getSelfReferenceConnectUrl() {
tryDefineSelfCustomTarget();
CompletableFuture<JsonObject> future = new CompletableFuture<>();
WORKER.submit(
() -> {
String path = URI.create(selfCustomTargetLocation).getPath();
webClient
.get(path)
.basicAuthentication("user", "pass")
.as(BodyCodec.jsonObject())
.timeout(TimeUnit.SECONDS.toMillis(REQUEST_TIMEOUT_SECONDS))
.send(
ar -> {
if (ar.failed()) {
logger.error(ar.cause());
future.completeExceptionally(ar.cause());
return;
}
HttpResponse<JsonObject> resp = ar.result();
JsonObject body = resp.body();
logger.infov(
"GET {0} -> HTTP {1} {2}: [{3}] = {4}",
path,
resp.statusCode(),
resp.statusMessage(),
resp.headers(),
body);
if (!HttpStatusCodeIdentifier.isSuccessCode(
resp.statusCode())) {
future.completeExceptionally(
new IllegalStateException(
Integer.toString(resp.statusCode())));
return;
}
future.complete(body);
});
});
try {
JsonObject obj = future.get(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS);
return obj.getString("connectUrl");
tryDefineSelfCustomTarget();
String path = URI.create(selfCustomTargetLocation).getPath();
HttpResponse<Buffer> resp =
webClient.extensions().get(path, true, REQUEST_TIMEOUT_SECONDS);
JsonObject body = resp.bodyAsJsonObject();
logger.infov(
"GET {0} -> HTTP {1} {2}: [{3}] = {4}",
path, resp.statusCode(), resp.statusMessage(), resp.headers(), body);
if (!HttpStatusCodeIdentifier.isSuccessCode(resp.statusCode())) {
throw new IllegalStateException(Integer.toString(resp.statusCode()));
}
return body.getString("connectUrl");
} catch (Exception e) {
throw new RuntimeException("Could not determine own connectUrl", e);
}
Expand Down
50 changes: 45 additions & 5 deletions src/test/java/itest/util/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,10 @@ public interface RedirectExtensions {
HttpResponse<Buffer> get(String url, boolean authentication, int timeout)
throws InterruptedException, ExecutionException, TimeoutException;

HttpResponse<Buffer> post(String url, boolean authentication, MultiMap form, int timeout)
HttpResponse<Buffer> post(String url, boolean authentication, Buffer payload, int timeout)
throws InterruptedException, ExecutionException, TimeoutException;

HttpResponse<Buffer> post(String url, boolean authentication, MultiMap payload, int timeout)
throws InterruptedException, ExecutionException, TimeoutException;

HttpResponse<Buffer> delete(String url, boolean authentication, int timeout)
Expand Down Expand Up @@ -138,17 +141,53 @@ public HttpResponse<Buffer> get(String url, boolean authentication, int timeout)
}

public HttpResponse<Buffer> post(
String url, boolean authentication, MultiMap form, int timeout)
String url, boolean authentication, Buffer payload, int timeout)
throws InterruptedException, ExecutionException, TimeoutException {
CompletableFuture<HttpResponse<Buffer>> future = new CompletableFuture<>();
RequestOptions options = new RequestOptions().setURI(url);
HttpRequest<Buffer> req = TestWebClient.this.request(HttpMethod.POST, options);
if (authentication) {
req.basicAuthentication("user", "pass");
}
if (payload != null) {
req.sendBuffer(
payload,
ar -> {
if (ar.succeeded()) {
future.complete(ar.result());
} else {
future.completeExceptionally(ar.cause());
}
});
} else {
req.send(
ar -> {
if (ar.succeeded()) {
future.complete(ar.result());
} else {
future.completeExceptionally(ar.cause());
}
});
}
if (future.get().statusCode() == 308) {
return post(
future.get().getHeader("Location"), authentication, payload, timeout);
}
return future.get(timeout, TimeUnit.SECONDS);
}

public HttpResponse<Buffer> post(
String url, boolean authentication, MultiMap payload, int timeout)
throws InterruptedException, ExecutionException, TimeoutException {
CompletableFuture<HttpResponse<Buffer>> future = new CompletableFuture<>();
RequestOptions options = new RequestOptions().setURI(url);
HttpRequest<Buffer> req = TestWebClient.this.request(HttpMethod.POST, options);
if (authentication) {
req.basicAuthentication("user", "pass");
}
if (form != null) {
if (payload != null) {
req.sendForm(
form,
payload,
ar -> {
if (ar.succeeded()) {
future.complete(ar.result());
Expand All @@ -167,7 +206,8 @@ public HttpResponse<Buffer> post(
});
}
if (future.get().statusCode() == 308) {
return post(future.get().getHeader("Location"), authentication, form, timeout);
return post(
future.get().getHeader("Location"), authentication, payload, timeout);
}
return future.get(timeout, TimeUnit.SECONDS);
}
Expand Down

0 comments on commit 1f2da3a

Please sign in to comment.