diff --git a/app-runner-router-lib/pom.xml b/app-runner-router-lib/pom.xml index b6a63a2..7ab3a5e 100644 --- a/app-runner-router-lib/pom.xml +++ b/app-runner-router-lib/pom.xml @@ -57,24 +57,6 @@ murp 1.1.5 - - org.eclipse.jetty - jetty-http - ${jetty.version} - test - - - org.eclipse.jetty - jetty-util - ${jetty.version} - test - - - org.eclipse.jetty - jetty-client - ${jetty.version} - test - diff --git a/app-runner-router-lib/src/test/java/com/danielflower/apprunner/router/lib/web/CreateAppHandlerTest.java b/app-runner-router-lib/src/test/java/com/danielflower/apprunner/router/lib/web/CreateAppHandlerTest.java index 100de58..21001d6 100644 --- a/app-runner-router-lib/src/test/java/com/danielflower/apprunner/router/lib/web/CreateAppHandlerTest.java +++ b/app-runner-router-lib/src/test/java/com/danielflower/apprunner/router/lib/web/CreateAppHandlerTest.java @@ -2,8 +2,8 @@ import org.junit.Test; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertThat; public class CreateAppHandlerTest { diff --git a/app-runner-router-lib/src/test/java/e2e/AvailabilityTest.java b/app-runner-router-lib/src/test/java/e2e/AvailabilityTest.java index fd24046..64e6859 100644 --- a/app-runner-router-lib/src/test/java/e2e/AvailabilityTest.java +++ b/app-runner-router-lib/src/test/java/e2e/AvailabilityTest.java @@ -4,7 +4,6 @@ import com.danielflower.apprunner.router.lib.AppRunnerRouterSettings; import com.danielflower.apprunner.router.lib.mgmt.SystemInfo; import io.muserver.MuServerBuilder; -import org.eclipse.jetty.client.api.ContentResponse; import org.json.JSONArray; import org.json.JSONObject; import org.junit.*; @@ -49,7 +48,7 @@ public void create() throws Exception { httpClient.registerRunner(unhealthyRunner.id(), unhealthyRunner.httpUrl(), 10); httpClient.deploy("app1"); - Waiter.waitForApp(httpClient.targetURI(), "app1"); + Waiter.waitForApp(httpClient.targetURI(), "app1").close(); assertThat(httpClient.get("/app1/"), ContentResponseMatcher.equalTo(200, containsString("My Maven App"))); unhealthyRunner.shutDown(); @@ -71,8 +70,8 @@ public static void deleteRunners() { public void appsReturnsPartialListWhenAnAppRunnerIsAvailableAndHasErrorMessages() throws Exception { // querying for all the apps returns a combined list - ContentResponse appsResponse = httpClient.get("/api/v1/apps"); - JSONObject actual = new JSONObject(appsResponse.getContentAsString()); + var appsResponse = httpClient.get("/api/v1/apps"); + JSONObject actual = new JSONObject(appsResponse.body()); JSONAssert.assertEquals("{ " + "'appCount': 1," + "'apps': [ { 'name': 'app1', 'url': '" + httpClient.targetURI().resolve("/app1/") + "', 'appRunnerInstanceId': 'healthy-app-runner', } ]" + @@ -84,8 +83,8 @@ public void appsReturnsPartialListWhenAnAppRunnerIsAvailableAndHasErrorMessages( @Test public void systemCallStillReturnsEvenWhenRunnersAreUnavailable() throws Exception { - ContentResponse systemResponse = httpClient.get("/api/v1/system"); - JSONObject all = new JSONObject(systemResponse.getContentAsString()); + var systemResponse = httpClient.get("/api/v1/system"); + JSONObject all = new JSONObject(systemResponse.body()); assertThat(all.getBoolean("appRunnerStarted"), equalTo(false)); JSONArray runners = all.getJSONArray("runners"); assertThat(runners.length(), equalTo(2)); diff --git a/app-runner-router-lib/src/test/java/e2e/HttpsTest.java b/app-runner-router-lib/src/test/java/e2e/HttpsTest.java index 71b65c7..37ceb7c 100644 --- a/app-runner-router-lib/src/test/java/e2e/HttpsTest.java +++ b/app-runner-router-lib/src/test/java/e2e/HttpsTest.java @@ -10,6 +10,7 @@ import scaffolding.RestClient; import java.io.File; +import java.net.ConnectException; import java.util.concurrent.ExecutionException; import static io.muserver.MuServerBuilder.muServer; @@ -62,7 +63,7 @@ private static void assertDoesNotWork(RestClient client) throws Exception { try { client.getAppRunners(); Assert.fail("Should not have worked"); - } catch (ExecutionException e) { + } catch (ConnectException e) { // correct behaviour } } diff --git a/app-runner-router-lib/src/test/java/e2e/RoutingTest.java b/app-runner-router-lib/src/test/java/e2e/RoutingTest.java index 88456a1..66cf7c9 100644 --- a/app-runner-router-lib/src/test/java/e2e/RoutingTest.java +++ b/app-runner-router-lib/src/test/java/e2e/RoutingTest.java @@ -10,7 +10,6 @@ import io.muserver.murp.ReverseProxyBuilder; import jakarta.ws.rs.BadRequestException; import jakarta.ws.rs.WebApplicationException; -import org.eclipse.jetty.client.api.ContentResponse; import org.hamcrest.CoreMatchers; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; @@ -33,8 +32,7 @@ import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.hasItem; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.startsWith; +import static org.hamcrest.Matchers.*; import static scaffolding.ContentResponseMatcher.equalTo; import static scaffolding.Photocopier.projectRoot; @@ -108,17 +106,17 @@ public void appRunnersCanBeRegisteredAndDeregisteredWithTheRestAPIWithAnHTTPRout assertThat(httpClient.registerRunner(latestAppRunnerWithoutNode.id(), urlOfLatest, 1), equalTo(201, containsString(latestAppRunnerWithoutNode.id()))); assertThat(httpClient.registerRunner(oldAppRunner.id(), oldAppRunner.httpUrl(), 2), equalTo(201, containsString(oldAppRunner.id()))); - ContentResponse appRunners = httpClient.getAppRunners(); - assertThat(appRunners.getStatus(), is(200)); + var appRunners = httpClient.getAppRunners(); + assertThat(appRunners.statusCode(), is(200)); JSONAssert.assertEquals("{ 'runners': [" + " { 'id': 'app-runner-1', 'url': '" + urlOfLatest + "', 'appCount': 0, 'maxApps': 1, " + "'systemUrl': '" + urlOfLatest.resolve("/api/v1/system") + "', 'appsUrl': '" + urlOfLatest.resolve("/api/v1/apps") + "' }," + " { 'id': 'app-runner-2', 'url': '" + oldAppRunner.httpUrl().toString() + "', 'appCount': 0, 'maxApps': 2 }" + - "]}", appRunners.getContentAsString(), JSONCompareMode.LENIENT); + "]}", appRunners.body(), JSONCompareMode.LENIENT); - ContentResponse appRunner = httpClient.getRunner("app-runner-2"); - assertThat(appRunner.getStatus(), is(200)); + var appRunner = httpClient.getRunner("app-runner-2"); + assertThat(appRunner.statusCode(), is(200)); JSONAssert.assertEquals("{ 'id': 'app-runner-2', 'url': '" + oldAppRunner.httpUrl().toString() + "', 'maxApps': 2 }" - , appRunner.getContentAsString(), JSONCompareMode.LENIENT); + , appRunner.body(), JSONCompareMode.LENIENT); assertThat(httpClient.deleteRunner(oldAppRunner.id()), equalTo(200, containsString(oldAppRunner.id()))); assertThat(httpClient.getRunner(oldAppRunner.id()), equalTo(404, containsString(oldAppRunner.id()))); @@ -127,7 +125,7 @@ public void appRunnersCanBeRegisteredAndDeregisteredWithTheRestAPIWithAnHTTPRout @Test public void runnersWithInvalidUrlsAreRejected() throws Exception { - ContentResponse resp = httpsClient.registerRunner("someid", URI.create("https://badurl.example.org"), 1); + var resp = httpsClient.registerRunner("someid", URI.create("https://badurl.example.org"), 1); assertThat(resp, equalTo(400, containsString("That is an invalid runner URL"))); } @@ -144,13 +142,13 @@ public void proxyHeadersAreForwardedCorrectlyToTheApp() throws Exception { httpsClient.deploy("app1"); Waiter.waitForApp(httpsClient.targetURI(), "app1"); - String headersFromOne = httpsClient.get("/app1/headers").getContentAsString(); + String headersFromOne = httpsClient.get("/app1/headers").body(); httpsClient.createApp(app2.gitUrl(), "app2"); httpsClient.deploy("app2"); Waiter.waitForApp(httpsClient.targetURI(), "app2"); - String headersFromTwo = httpsClient.get("/app2/headers").getContentAsString(); + String headersFromTwo = httpsClient.get("/app2/headers").body(); assertThat(headersFromOne, containsString(";proto=https\r\n")); assertThat(headersFromOne, containsString(";proto=http\r\n")); @@ -158,8 +156,8 @@ public void proxyHeadersAreForwardedCorrectlyToTheApp() throws Exception { assertThat(headersFromOne, containsString("X-Forwarded-Proto:https\r\n")); assertThat(headersFromTwo, containsString("X-Forwarded-Proto:https\r\n")); - assertThat(headersFromOne, containsString("\r\nHost:" + httpsClient.targetURI().getAuthority() + "\r\n")); - assertThat(headersFromTwo, containsString("\r\nHost:" + httpsClient.targetURI().getAuthority() + "\r\n")); + assertThat(headersFromOne, containsString("Host:" + httpsClient.targetURI().getAuthority() + "\r\n")); + assertThat(headersFromTwo, containsString("Host:" + httpsClient.targetURI().getAuthority() + "\r\n")); httpsClient.stop("app1"); httpsClient.stop("app2"); @@ -204,7 +202,7 @@ public void slowRequestsTimeOut() throws Exception { httpsClient.createApp(app1.gitUrl(), appName); httpsClient.deploy(appName); Waiter.waitForApp(httpsClient.targetURI(), appName); - assertThat(httpsClient.get("/" + appName + "/slow?millis=" + waitTime).getStatus(), is(504)); + assertThat(httpsClient.get("/" + appName + "/slow?millis=" + waitTime).statusCode(), is(504)); httpsClient.stop(appName); } } @@ -213,13 +211,13 @@ private static void appsCanBeAddedToTheRouterAndItWillDistributeThoseToTheRunner AppRepo app1 = AppRepo.create("maven"); AppRepo app2 = AppRepo.create("maven"); - ContentResponse app1Creation = client.createApp(app1.gitUrl(), "app1"); - assertThat("Error returned: " + app1Creation.getContentAsString(), app1Creation.getStatus(), is(201)); + var app1Creation = client.createApp(app1.gitUrl(), "app1"); + assertThat("Error returned: " + app1Creation.body(), app1Creation.statusCode(), is(201)); - ContentResponse app1DuplicateCreation = client.createApp(app1.gitUrl(), "app1"); - assertThat("Body returned: " + app1DuplicateCreation.getContentAsString(), app1DuplicateCreation.getStatus(), is(409)); + var app1DuplicateCreation = client.createApp(app1.gitUrl(), "app1"); + assertThat("Body returned: " + app1DuplicateCreation.body(), app1DuplicateCreation.statusCode(), is(409)); - JSONObject app1Json = new JSONObject(app1Creation.getContentAsString()); + JSONObject app1Json = new JSONObject(app1Creation.body()); assertThat(app1Json.getString("url"), startsWith(client.routerUrl)); client.deploy("app1"); @@ -236,22 +234,22 @@ private static void appsCanBeAddedToTheRouterAndItWillDistributeThoseToTheRunner assertThat(numberOfApps(oldAppRunner), is(1)); // a runner can be deleted and added back and the number reported is accurate - JSONObject savedInfo = new JSONObject(client.getRunner(latestAppRunner.id()).getContentAsString()); + JSONObject savedInfo = new JSONObject(client.getRunner(latestAppRunner.id()).body()); client.deleteRunner(latestAppRunner.id()); client.registerRunner(latestAppRunner.id(), URI.create(savedInfo.getString("url")), savedInfo.getInt("maxApps")); assertThat(numberOfApps(latestAppRunner), is(1)); // querying for all the apps returns a combined list - ContentResponse appsResponse = client.get("/api/v1/apps"); + var appsResponse = client.get("/api/v1/apps"); JSONAssert.assertEquals("{ " + "'appCount': 2," + "'apps': [ " + "{ 'name': 'app1', 'url': '" + client.targetURI().resolve("/app1/") + "' }," + "{ 'name': 'app2', 'url': '" + client.targetURI().resolve("/app2/") + "' }" + - "] }", appsResponse.getContentAsString(), JSONCompareMode.STRICT_ORDER); + "] }", appsResponse.body(), JSONCompareMode.STRICT_ORDER); - assertThat(appsResponse.getStatus(), is(200)); + assertThat(appsResponse.statusCode(), is(200)); assertThat(client.get("/api/v1/swagger.json"), equalTo(200, containsString("/apps/{name}"))); @@ -259,7 +257,7 @@ private static void appsCanBeAddedToTheRouterAndItWillDistributeThoseToTheRunner "{ id: " + latestAppRunner.id() + ", 'appCount': 1 }," + "{ id: " + oldAppRunner.id() + ", 'appCount': 1 }" + "] }", - client.getAppRunners().getContentAsString(), JSONCompareMode.LENIENT); + client.getAppRunners().body(), JSONCompareMode.LENIENT); client.stop("app1"); client.stop("app2"); @@ -267,7 +265,7 @@ private static void appsCanBeAddedToTheRouterAndItWillDistributeThoseToTheRunner private static int numberOfApps(AppRunnerInstance appRunner) throws Exception { RestClient c = RestClient.create(appRunner.httpUrl().toString()); - JSONObject apps = new JSONObject(c.get("/api/v1/apps").getContentAsString()); + JSONObject apps = new JSONObject(c.get("/api/v1/apps").body()); return apps.getJSONArray("apps").length(); } @@ -343,7 +341,7 @@ public void runnerDetailsCanBeUpdated() throws Exception { assertThat(httpClient.updateRunner(latestAppRunnerWithoutNode.id(), oldAppRunner.httpUrl(), 100), equalTo(200, Matchers.containsString("100"))); - JSONArray runners = new JSONObject(httpClient.getAppRunners().getContentAsString()).getJSONArray("runners"); + JSONArray runners = new JSONObject(httpClient.getAppRunners().body()).getJSONArray("runners"); assertThat(runners.length(), is(1)); JSONAssert.assertEquals("{ 'id': '" + latestAppRunnerWithoutNode.id() + "', 'url': '" + oldAppRunner.httpUrl() + "', maxApps: 100 }", runners.get(0).toString(), JSONCompareMode.LENIENT); } @@ -355,9 +353,9 @@ public void appsAddedToAnInstanceBeforeItJoinsTheClusterAreAvailable() throws Ex direct.createApp(app1.gitUrl(), "app1"); direct.deploy(app1.name); httpClient.registerRunner(latestAppRunnerWithoutNode.id(), latestAppRunnerWithoutNode.httpUrl(), 1); - ContentResponse contentResponse = httpClient.get("/api/v1/apps/app1"); - assertThat(contentResponse.getStatus(), is(200)); - JSONObject json = new JSONObject(contentResponse.getContentAsString()); + var contentResponse = httpClient.get("/api/v1/apps/app1"); + assertThat(contentResponse.statusCode(), is(200)); + JSONObject json = new JSONObject(contentResponse.body()); JSONAssert.assertEquals("{ 'name': 'app1', 'url': '" + httpClient.routerUrl + "/app1/' }", json, JSONCompareMode.LENIENT); httpClient.stop(app1.name); @@ -369,20 +367,20 @@ public void theRunnerAppsAPIGivesTheAppsOfARunner() throws Exception { AppRepo app1 = AppRepo.create("maven"); httpClient.createApp(app1.gitUrl(), "my-app"); - ContentResponse resp = httpClient.getRunnerApps(latestAppRunnerWithoutNode.id()); - assertThat(resp.getStatus(), is(200)); - assertThat(resp.getHeaders().get("Content-Type"), Matchers.equalTo("application/json")); - JSONObject appJson = new JSONObject(resp.getContentAsString()); + var resp = httpClient.getRunnerApps(latestAppRunnerWithoutNode.id()); + assertThat(resp.statusCode(), is(200)); + assertThat(resp.headers().allValues("Content-Type"), contains("application/json")); + JSONObject appJson = new JSONObject(resp.body()); assertThat(appJson.getJSONArray("apps").length(), is(1)); } @Test public void theRunnerAppsAPIGivesTheSystemOfARunner() throws Exception { httpClient.registerRunner(latestAppRunnerWithoutNode.id(), latestAppRunnerWithoutNode.httpUrl(), 1); - ContentResponse resp = httpClient.getRunnerSystem(latestAppRunnerWithoutNode.id()); - assertThat(resp.getStatus(), is(200)); - assertThat(resp.getHeaders().get("Content-Type"), Matchers.equalTo("application/json")); - JSONObject json = new JSONObject(resp.getContentAsString()); + var resp = httpClient.getRunnerSystem(latestAppRunnerWithoutNode.id()); + assertThat(resp.statusCode(), is(200)); + assertThat(resp.headers().allValues("Content-Type"), contains("application/json")); + JSONObject json = new JSONObject(resp.body()); assertThat(json.getBoolean("appRunnerStarted"), is(true)); } @@ -410,7 +408,7 @@ public void theSystemApiReturnsTheSetOfAllSampleAppsAndRunnerInfoAcrossAllTheIns httpClient.registerRunner(latestAppRunnerWithoutNode.id(), latestAppRunnerWithoutNode.httpUrl(), 1); httpClient.registerRunner(oldAppRunner.id(), oldAppRunner.httpUrl(), 2); - JSONObject system = new JSONObject(httpClient.getSystem().getContentAsString()); + JSONObject system = new JSONObject(httpClient.getSystem().body()); JSONArray runners = system.getJSONArray("runners"); assertThat(runners.length(), is(2)); @@ -426,9 +424,9 @@ public void theSystemApiReturnsTheSetOfAllSampleAppsAndRunnerInfoAcrossAllTheIns ids.add(SystemResource.getSampleID(sample)); String zipUrl = sample.getString("url"); assertThat(zipUrl, containsString(httpClient.routerUrl)); - ContentResponse zip = httpClient.getAbsolute(zipUrl); - MatcherAssert.assertThat(zipUrl, zip.getStatus(), CoreMatchers.is(200)); - MatcherAssert.assertThat(zipUrl, zip.getHeaders().get("Content-Type"), CoreMatchers.is("application/zip")); + var zip = httpClient.getAbsolute(zipUrl); + MatcherAssert.assertThat(zipUrl, zip.statusCode(), CoreMatchers.is(200)); + MatcherAssert.assertThat(zipUrl, zip.headers().allValues("Content-Type"), contains("application/zip")); } assertThat(ids, hasItem(CoreMatchers.equalTo("maven"))); diff --git a/app-runner-router-lib/src/test/java/manual/RunLocal.java b/app-runner-router-lib/src/test/java/manual/RunLocal.java index a2522d8..c86dd73 100644 --- a/app-runner-router-lib/src/test/java/manual/RunLocal.java +++ b/app-runner-router-lib/src/test/java/manual/RunLocal.java @@ -7,7 +7,6 @@ import io.muserver.MuServerBuilder; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; -import org.eclipse.jetty.client.api.ContentResponse; import org.json.JSONArray; import org.json.JSONObject; import org.slf4j.Logger; @@ -94,7 +93,7 @@ private static void setupSampleApps(RestClientThatThrows client) throws Exceptio File repoRoot = new File(projectRoot(), "target/local/repos/" + System.currentTimeMillis()); log.info("Creating git repos for apps at " + fullPath(repoRoot)); FileUtils.forceMkdir(repoRoot); - JSONObject system = new JSONObject(client.getSystem().getContentAsString()); + JSONObject system = new JSONObject(client.getSystem().body()); JSONArray samples = system.getJSONArray("samples"); for (Object sampleObj : samples) { JSONObject sample = (JSONObject) sampleObj; @@ -106,8 +105,8 @@ private static void setupSampleApps(RestClientThatThrows client) throws Exceptio } log.info("Going to download " + zipUrl); File zip = new File(repoRoot, id + ".zip"); - ContentResponse zipResponse = client.getAbsolute(zipUrl); - FileUtils.writeByteArrayToFile(zip, zipResponse.getContent()); + var zipResponse = client.getAbsoluteByteArray(zipUrl); + FileUtils.writeByteArrayToFile(zip, zipResponse.body()); File target = new File(repoRoot, id); if (!target.mkdir()) { throw new RuntimeException("Could not make " + fullPath(target)); @@ -143,9 +142,9 @@ private static void unzip(File zip, File outputDir) throws IOException { private static void registerRunner(RestClientThatThrows client, AppRunnerInstance runner, int maxInstances) throws Exception { log.info("Registering " + runner.httpUrl() + " with the router"); - ContentResponse contentResponse = client.registerRunner(runner.id(), runner.httpUrl(), maxInstances); - if (contentResponse.getStatus() != 201) { - throw new RuntimeException("Could not register " + runner.httpUrl() + ": " + contentResponse.getStatus() + " - " + contentResponse.getContentAsString()); + var contentResponse = client.registerRunner(runner.id(), runner.httpUrl(), maxInstances); + if (contentResponse.statusCode() != 201) { + throw new RuntimeException("Could not register " + runner.httpUrl() + ": " + contentResponse.statusCode() + " - " + contentResponse.body()); } } diff --git a/app-runner-router-lib/src/test/java/scaffolding/AppRunnerInstance.java b/app-runner-router-lib/src/test/java/scaffolding/AppRunnerInstance.java index f08eecf..a728907 100644 --- a/app-runner-router-lib/src/test/java/scaffolding/AppRunnerInstance.java +++ b/app-runner-router-lib/src/test/java/scaffolding/AppRunnerInstance.java @@ -109,7 +109,7 @@ public String id() { public void clearApps() throws Exception { RestClient client = RestClient.create(httpUrl().toString()); while (true) { - JSONArray apps = new JSONObject(client.get("/api/v1/apps").getContentAsString()) + JSONArray apps = new JSONObject(client.get("/api/v1/apps").body()) .getJSONArray("apps"); if (apps.isEmpty()) { break; diff --git a/app-runner-router-lib/src/test/java/scaffolding/ContentResponseMatcher.java b/app-runner-router-lib/src/test/java/scaffolding/ContentResponseMatcher.java index bd41a38..a0ce92f 100644 --- a/app-runner-router-lib/src/test/java/scaffolding/ContentResponseMatcher.java +++ b/app-runner-router-lib/src/test/java/scaffolding/ContentResponseMatcher.java @@ -1,30 +1,31 @@ package scaffolding; -import org.eclipse.jetty.client.api.ContentResponse; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeDiagnosingMatcher; +import java.net.http.HttpResponse; + import static org.hamcrest.CoreMatchers.is; public class ContentResponseMatcher { - public static Matcher equalTo(int statusCode, Matcher contentMatcher) { + public static Matcher> equalTo(int statusCode, Matcher contentMatcher) { Matcher statusCodeMatcher = is(statusCode); - return new TypeSafeDiagnosingMatcher() { - protected boolean matchesSafely(ContentResponse t, Description description) { + return new TypeSafeDiagnosingMatcher>() { + protected boolean matchesSafely(HttpResponse t, Description description) { boolean matches = true; - if (!statusCodeMatcher.matches(t.getStatus())) { + if (!statusCodeMatcher.matches(t.statusCode())) { description.appendText("statusCode "); - statusCodeMatcher.describeMismatch(t.getStatus(), description); + statusCodeMatcher.describeMismatch(t.statusCode(), description); matches = false; } - if (!contentMatcher.matches(t.getContentAsString())) { + if (!contentMatcher.matches(t.body())) { if (!matches) description.appendText(", "); description.appendText("content "); - contentMatcher.describeMismatch(t.getContentAsString(), description); + contentMatcher.describeMismatch(t.body(), description); matches = false; } diff --git a/app-runner-router-lib/src/test/java/scaffolding/ProcessStarter.java b/app-runner-router-lib/src/test/java/scaffolding/ProcessStarter.java index 9c1fd20..3383ca2 100644 --- a/app-runner-router-lib/src/test/java/scaffolding/ProcessStarter.java +++ b/app-runner-router-lib/src/test/java/scaffolding/ProcessStarter.java @@ -59,7 +59,7 @@ private void logEndTime(CommandLine command, long startTime) { } private Executor createExecutor(File workingDir, ExecuteWatchdog watchDog) { - Executor executor = new DefaultExecutor(); + Executor executor = new DefaultExecutor.Builder().get(); executor.setWorkingDirectory(workingDir); executor.setWatchdog(watchDog); executor.setStreamHandler(new PumpStreamHandler(new LogOutputStream() { diff --git a/app-runner-router-lib/src/test/java/scaffolding/RestClient.java b/app-runner-router-lib/src/test/java/scaffolding/RestClient.java index 07effbc..3d8b42a 100644 --- a/app-runner-router-lib/src/test/java/scaffolding/RestClient.java +++ b/app-runner-router-lib/src/test/java/scaffolding/RestClient.java @@ -1,32 +1,21 @@ package scaffolding; -import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.api.ContentResponse; -import org.eclipse.jetty.client.util.FormContentProvider; -import org.eclipse.jetty.util.Fields; -import org.eclipse.jetty.util.ssl.SslContextFactory; +import io.muserver.Mutils; +import io.muserver.murp.ReverseProxyBuilder; import java.net.URI; import java.net.URLEncoder; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; import static io.muserver.Mutils.urlEncode; +import static java.net.http.HttpRequest.BodyPublishers.noBody; public class RestClient { - public static final HttpClient client; - - static { - SslContextFactory.Client sslContextFactory = new SslContextFactory.Client(true); - sslContextFactory.setEndpointIdentificationAlgorithm("HTTPS"); - HttpClient c = new HttpClient(sslContextFactory); - c.setConnectTimeout(10000); - try { - c.start(); - } catch (Exception e) { - throw new RuntimeException("Unable to make client", e); - } - client = c; - } + public static final HttpClient client = ReverseProxyBuilder.createHttpClientBuilder(true).build(); public static RestClient create(String appRunnerUrl) { if (appRunnerUrl.endsWith("/")) { @@ -45,91 +34,109 @@ public URI targetURI() { return URI.create(routerUrl); } - public ContentResponse createApp(String gitUrl, String appName) throws Exception { - Fields fields = new Fields(); - fields.add("gitUrl", gitUrl); + public HttpResponse createApp(String gitUrl, String appName) throws Exception { + + var sb = new StringBuilder(); + sb.append("gitUrl=").append(Mutils.urlEncode(gitUrl)); if (appName != null) { - fields.add("appName", appName); + sb.append("&appName=").append(Mutils.urlEncode(appName)); } - return client.POST(routerUrl + "/api/v1/apps") - .content(new FormContentProvider(fields)).send(); + return client.send(req(routerUrl + "/api/v1/apps") + .method("POST", HttpRequest.BodyPublishers.ofString(sb.toString())) + .header("content-type", "application/x-www-form-urlencoded") + .build(), HttpResponse.BodyHandlers.ofString()); } - public ContentResponse updateApp(String gitUrl, String appName) throws Exception { - Fields fields = new Fields(); - fields.add("gitUrl", gitUrl); - return client.newRequest(routerUrl + "/api/v1/apps/" + appName) - .method("PUT") - .content(new FormContentProvider(fields)).send(); + private static HttpRequest.Builder req(String uri) { + return req(URI.create(uri)); + } + private static HttpRequest.Builder req(URI uri) { + return HttpRequest.newBuilder(uri); } - public ContentResponse deploy(String app) throws Exception { - return client.POST(routerUrl + "/api/v1/apps/" + app + "/deploy") + public HttpResponse updateApp(String gitUrl, String appName) throws Exception { + return client.send(req(routerUrl + "/api/v1/apps/" + appName) + .method("PUT", HttpRequest.BodyPublishers.ofString("gitUrl=" + Mutils.urlEncode(gitUrl))) + .header("content-type", "application/x-www-form-urlencoded") + .build(), HttpResponse.BodyHandlers.ofString()); + } + + public HttpResponse deploy(String app) throws Exception { + return client.send(req(routerUrl + "/api/v1/apps/" + app + "/deploy") + .method("POST", noBody()) .header("Accept", "application/json") // to simulate products like the Stash commit hook - .send(); + .header("content-type", "application/json") + .build(), HttpResponse.BodyHandlers.ofString()); } - public ContentResponse stop(String app) throws Exception { - return client.newRequest(routerUrl + "/api/v1/apps/" + app + "/stop").method("PUT").send(); + public HttpResponse stop(String app) throws Exception { + return client.send(req(routerUrl + "/api/v1/apps/" + app + "/stop") + .method("PUT", noBody()).build(), HttpResponse.BodyHandlers.ofString()); } - public ContentResponse deleteApp(String appName) throws Exception { - return client.newRequest(routerUrl + "/api/v1/apps/" + appName).method("DELETE").send(); + public HttpResponse deleteApp(String appName) throws Exception { + return client.send(req(routerUrl + "/api/v1/apps/" + appName).method("DELETE", noBody()).build(), + HttpResponse.BodyHandlers.ofString()); } - public ContentResponse homepage(String appName) throws Exception { - return client.GET(routerUrl + "/" + appName + "/"); + public HttpResponse homepage(String appName) throws Exception { + return client.send(req(routerUrl + "/" + appName + "/").build(), HttpResponse.BodyHandlers.ofString()); } - public ContentResponse get(String url) throws Exception { + public HttpResponse get(String url) throws Exception { return getAbsolute(routerUrl + url); } - public ContentResponse getAbsolute(String absoluteUrl) throws Exception { - return client.GET(absoluteUrl); + public HttpResponse getAbsolute(String absoluteUrl) throws Exception { + return client.send(req(absoluteUrl).build(), HttpResponse.BodyHandlers.ofString()); + } + + public HttpResponse getAbsoluteByteArray(String absoluteUrl) throws Exception { + return client.send(req(absoluteUrl).build(), HttpResponse.BodyHandlers.ofByteArray()); } - public ContentResponse registerRunner(String id, URI url, int maxInstances) throws Exception { - Fields fields = new Fields(); - fields.add("id", id); - fields.add("url", url.toString()); - fields.add("maxApps", String.valueOf(maxInstances)); - return client.POST(routerUrl + "/api/v1/runners") - .content(new FormContentProvider(fields)).send(); + public HttpResponse registerRunner(String id, URI url, int maxInstances) throws Exception { + String body = "id=" + urlEncode(id) + "&url=" + urlEncode(url.toString()) + "&maxApps=" + maxInstances; + return client.send(req(routerUrl + "/api/v1/runners") + .method("POST", HttpRequest.BodyPublishers.ofString(body)) + .header("content-type", "application/x-www-form-urlencoded") + .build(), HttpResponse.BodyHandlers.ofString()); } - public ContentResponse updateRunner(String id, URI url, int maxInstances) throws Exception { - Fields fields = new Fields(); - fields.add("url", url.toString()); - fields.add("maxApps", String.valueOf(maxInstances)); - return client.newRequest(routerUrl + "/api/v1/runners/" + id) - .method("PUT") - .content(new FormContentProvider(fields)).send(); + public HttpResponse updateRunner(String id, URI url, int maxInstances) throws Exception { + String body = "url=" + urlEncode(url.toString()) + "&maxApps=" + maxInstances; + + return client.send(req(routerUrl + "/api/v1/runners/" + id) + .method("PUT", HttpRequest.BodyPublishers.ofString(body)) + .header("content-type", "application/x-www-form-urlencoded") + .build(), + HttpResponse.BodyHandlers.ofString()); } - public ContentResponse getAppRunners() throws Exception { + public HttpResponse getAppRunners() throws Exception { return get("/api/v1/runners"); } - public ContentResponse getSystem() throws Exception { + public HttpResponse getSystem() throws Exception { return get("/api/v1/system"); } - public ContentResponse getRunner(String id) throws Exception { + public HttpResponse getRunner(String id) throws Exception { return get("/api/v1/runners/" + urlEncode(id)); } - public ContentResponse getRunnerApps(String id) throws Exception { + public HttpResponse getRunnerApps(String id) throws Exception { return get("/api/v1/runners/" + urlEncode(id) + "/apps"); } - public ContentResponse getRunnerSystem(String id) throws Exception { + public HttpResponse getRunnerSystem(String id) throws Exception { return get("/api/v1/runners/" + urlEncode(id) + "/system"); } - public ContentResponse deleteRunner(String id) throws Exception { - return client.newRequest(routerUrl + "/api/v1/runners/" + URLEncoder.encode(id, "UTF-8")).method("DELETE").send(); + public HttpResponse deleteRunner(String id) throws Exception { + return client.send(req(routerUrl + "/api/v1/runners/" + URLEncoder.encode(id, StandardCharsets.UTF_8)) + .method("DELETE", noBody()).build(), HttpResponse.BodyHandlers.ofString()); } } diff --git a/app-runner-router-lib/src/test/java/scaffolding/RestClientThatThrows.java b/app-runner-router-lib/src/test/java/scaffolding/RestClientThatThrows.java index 63e40c1..6109764 100644 --- a/app-runner-router-lib/src/test/java/scaffolding/RestClientThatThrows.java +++ b/app-runner-router-lib/src/test/java/scaffolding/RestClientThatThrows.java @@ -1,10 +1,10 @@ package scaffolding; -import org.eclipse.jetty.client.api.ContentResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.URI; +import java.net.http.HttpResponse; public class RestClientThatThrows { private static final Logger log = LoggerFactory.getLogger(RestClientThatThrows.class); @@ -15,63 +15,73 @@ public RestClientThatThrows(RestClient underlying) { this.underlying = underlying; } - private ContentResponse verify(ContentResponse resp) { - int status = resp.getStatus(); + private HttpResponse verify(HttpResponse resp) { + int status = resp.statusCode(); if (status <= 99 || status >= 400) { - throw new RuntimeException("Error returned: " + status + " with response: " + resp.getContentAsString()); + throw new RuntimeException("Error returned: " + status + " with response: " + resp.body()); } return resp; } - public ContentResponse createApp(String gitUrl, String appName) throws Exception { + public HttpResponse createApp(String gitUrl, String appName) throws Exception { log.info("Create app " + appName + " at " + gitUrl); return verify(underlying.createApp(gitUrl, appName)); } - public ContentResponse deploy(String app) throws Exception { + public HttpResponse deploy(String app) throws Exception { log.info("Deploy app " + app); return verify(underlying.deploy(app)); } - public ContentResponse stop(String app) throws Exception { + public HttpResponse stop(String app) throws Exception { return verify(underlying.stop(app)); } - public ContentResponse deleteApp(String appName) throws Exception { + public HttpResponse deleteApp(String appName) throws Exception { return verify(underlying.deleteApp(appName)); } - public ContentResponse homepage(String appName) throws Exception { + public HttpResponse homepage(String appName) throws Exception { return verify(underlying.homepage(appName)); } - public ContentResponse get(String url) throws Exception { + public HttpResponse get(String url) throws Exception { return verify(underlying.get(url)); } - public ContentResponse getAbsolute(String absoluteUrl) throws Exception { + public HttpResponse getAbsolute(String absoluteUrl) throws Exception { log.info("Downloading " + absoluteUrl); return verify(underlying.getAbsolute(absoluteUrl)); } - public ContentResponse registerRunner(String id, URI url, int maxInstances) throws Exception { + public HttpResponse getAbsoluteByteArray(String absoluteUrl) throws Exception { + log.info("Downloading " + absoluteUrl); + HttpResponse resp = underlying.getAbsoluteByteArray(absoluteUrl); + int status = resp.statusCode(); + if (status <= 99 || status >= 400) { + throw new RuntimeException("Error returned: " + status + " with response: " + resp.body()); + } + return resp; + } + + public HttpResponse registerRunner(String id, URI url, int maxInstances) throws Exception { log.info("Registering runner " + id + " at " + url); return verify(underlying.registerRunner(id, url, maxInstances)); } - public ContentResponse getAppRunners() throws Exception { + public HttpResponse getAppRunners() throws Exception { return verify(underlying.getAppRunners()); } - public ContentResponse getSystem() throws Exception { + public HttpResponse getSystem() throws Exception { return verify(underlying.getSystem()); } - public ContentResponse getRunner(String id) throws Exception { + public HttpResponse getRunner(String id) throws Exception { return verify(underlying.getRunner(id)); } - public ContentResponse deleteRunner(String id) throws Exception { + public HttpResponse deleteRunner(String id) throws Exception { return verify(underlying.deleteRunner(id)); } diff --git a/app-runner-router-lib/src/test/java/scaffolding/Waiter.java b/app-runner-router-lib/src/test/java/scaffolding/Waiter.java index b25117b..d17875c 100644 --- a/app-runner-router-lib/src/test/java/scaffolding/Waiter.java +++ b/app-runner-router-lib/src/test/java/scaffolding/Waiter.java @@ -1,10 +1,13 @@ package scaffolding; -import org.eclipse.jetty.client.HttpClient; +import io.muserver.murp.ReverseProxyBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.Predicate; @@ -17,7 +20,7 @@ public class Waiter implements AutoCloseable { private final String name; private final long timeout; private final TimeUnit unit; - private final HttpClient client = new HttpClient(); + private final HttpClient client = ReverseProxyBuilder.createHttpClientBuilder(true).build(); public Waiter(String name, Predicate predicate, long timeout, TimeUnit unit) { this.predicate = predicate; @@ -31,7 +34,6 @@ public void or(Predicate other) { } public void blockUntilReady() throws Exception { - client.start(); long start = System.currentTimeMillis(); while ((System.currentTimeMillis() - start) < unit.toMillis(timeout)) { Thread.sleep(POLL_INTERVAL); @@ -44,10 +46,6 @@ public void blockUntilReady() throws Exception { throw new TimeoutException(); } - public void close() throws Exception { - client.stop(); - } - public static Waiter waitForApp(URI appServer, String appName) { URI url = appServer.resolve(appName + "/"); return waitFor(appName, url, 30, TimeUnit.SECONDS); @@ -56,7 +54,7 @@ public static Waiter waitForApp(URI appServer, String appName) { public static Waiter waitFor(String name, URI url, long timeout, TimeUnit unit) { return new Waiter(name, client -> { try { - client.GET(url); + client.send(HttpRequest.newBuilder(url).build(), HttpResponse.BodyHandlers.discarding()); return true; } catch (InterruptedException e) { return true; // erg... really want to bubble this but can't @@ -65,4 +63,8 @@ public static Waiter waitFor(String name, URI url, long timeout, TimeUnit unit) } }, timeout, unit); } + + @Override + public void close() { + } } diff --git a/app-runner-router/pom.xml b/app-runner-router/pom.xml index e252e08..0c6b126 100644 --- a/app-runner-router/pom.xml +++ b/app-runner-router/pom.xml @@ -49,18 +49,6 @@ murp 1.1.4 - - org.eclipse.jetty - jetty-client - ${jetty.version} - test - - - org.eclipse.jetty - jetty-util - ${jetty.version} - test - org.hamcrest hamcrest diff --git a/pom.xml b/pom.xml index 9a47074..2ae6281 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,6 @@ UTF-8 - 9.4.56.v20240826