From d7b41688d2228b3918617828e8910c752638e552 Mon Sep 17 00:00:00 2001 From: Jon Marius Venstad Date: Wed, 9 Jan 2019 11:54:26 +0100 Subject: Move badges to separate, minimal API --- .../restapi/application/ApplicationApiHandler.java | 24 ------ .../restapi/deployment/BadgeApiHandler.java | 87 ++++++++++++++++++++++ .../restapi/ControllerContainerTest.java | 3 + .../restapi/application/ApplicationApiTest.java | 7 -- .../restapi/deployment/BadgeApiTest.java | 46 ++++++++++++ 5 files changed, 136 insertions(+), 31 deletions(-) create mode 100644 controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/BadgeApiHandler.java create mode 100644 controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/deployment/BadgeApiTest.java (limited to 'controller-server') diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java index c8104c6e2b0..12f5fa88af9 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java @@ -175,8 +175,6 @@ public class ApplicationApiHandler extends LoggingRequestHandler { if (path.matches("/application/v4/tenant/{tenant}/application")) return applications(path.get("tenant"), request); if (path.matches("/application/v4/tenant/{tenant}/application/{application}")) return application(path.get("tenant"), path.get("application"), request); if (path.matches("/application/v4/tenant/{tenant}/application/{application}/environment/{environment}/region/{region}/instance/{instance}/logs")) return logs(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), request.getUri().getQuery()); - if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/badge")) return badge(path.get("tenant"), path.get("application"), path.get("instance")); - if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/badge/{job}")) return badge(path.get("tenant"), path.get("application"), path.get("instance"), path.get("job"), request.getProperty("historyLength")); if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/job")) return JobControllerApiHandlerHelper.jobTypeResponse(controller, appIdFromPath(path), request.getUri()); if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/job/{jobtype}")) return JobControllerApiHandlerHelper.runResponse(controller.jobController().runs(appIdFromPath(path), jobTypeFromPath(path)), request.getUri()); if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/job/{jobtype}/run/{number}")) return JobControllerApiHandlerHelper.runDetailsResponse(controller.jobController(), runIdFromPath(path), request.getProperty("after")); @@ -963,28 +961,6 @@ public class ApplicationApiHandler extends LoggingRequestHandler { } } - /** Returns a URI which points to an overview badge for the given application. */ - private HttpResponse badge(String tenant, String application, String instance) { - URI location = controller.jobController().overviewBadge(ApplicationId.from(tenant, application, instance)); - return redirect(location); - } - - /** Returns a URI which points to a history badge for the given application and job type. */ - private HttpResponse badge(String tenant, String application, String instance, String jobName, String historyLength) { - URI location = controller.jobController().historicBadge(ApplicationId.from(tenant, application, instance), - JobType.fromJobName(jobName), - historyLength == null ? 5 : Math.min(32, Math.max(0, Integer.parseInt(historyLength)))); - return redirect(location); - } - - private static HttpResponse redirect(URI location) { - HttpResponse httpResponse = new HttpResponse(Response.Status.FOUND) { - @Override public void render(OutputStream outputStream) { } - }; - httpResponse.headers().add("Location", location.toString()); - return httpResponse; - } - private static DeploymentJobs.JobReport toJobReport(String tenantName, String applicationName, Inspector report) { Optional jobError = Optional.empty(); if (report.field("jobError").valid()) { diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/BadgeApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/BadgeApiHandler.java new file mode 100644 index 00000000000..35fa812851a --- /dev/null +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/BadgeApiHandler.java @@ -0,0 +1,87 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.controller.restapi.deployment; + +import com.yahoo.config.provision.ApplicationId; +import com.yahoo.container.jdisc.HttpRequest; +import com.yahoo.container.jdisc.HttpResponse; +import com.yahoo.container.jdisc.LoggingRequestHandler; +import com.yahoo.jdisc.Response; +import com.yahoo.jdisc.http.HttpRequest.Method; +import com.yahoo.restapi.Path; +import com.yahoo.vespa.hosted.controller.Controller; +import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType; +import com.yahoo.vespa.hosted.controller.restapi.ErrorResponse; +import com.yahoo.yolean.Exceptions; + +import java.io.OutputStream; +import java.net.URI; +import java.util.logging.Level; +import java.util.logging.Logger; + +import static java.util.stream.Collectors.joining; + +/** + * This API serves redirects to a badge server. + * + * @author jonmv + */ +@SuppressWarnings("unused") // Handler +public class BadgeApiHandler extends LoggingRequestHandler { + + private final static Logger log = Logger.getLogger(BadgeApiHandler.class.getName()); + + private final Controller controller; + + public BadgeApiHandler(Context parentCtx, Controller controller) { + super(parentCtx); + this.controller = controller; + } + + @Override + public HttpResponse handle(HttpRequest request) { + Method method = request.getMethod(); + try { + switch (method) { + case GET: return get(request); + default: return ErrorResponse.methodNotAllowed("Method '" + method + "' is unsupported"); + } + } catch (IllegalArgumentException|IllegalStateException e) { + return ErrorResponse.badRequest(Exceptions.toMessageString(e)); + } catch (RuntimeException e) { + log.log(Level.WARNING, "Unexpected error handling '" + request.getUri() + "'", e); + return ErrorResponse.internalServerError(Exceptions.toMessageString(e)); + } + } + + private HttpResponse get(HttpRequest request) { + Path path = new Path(request.getUri().getPath()); + if (path.matches("/badge/v1/{tenant}/{application}/{instance}")) return badge(path.get("tenant"), path.get("application"), path.get("instance")); + if (path.matches("/badge/v1/{tenant}/{application}/{instance}/{jobName}")) return badge(path.get("tenant"), path.get("application"), path.get("instance"), path.get("jobName"), request.getProperty("historyLength")); + + return ErrorResponse.notFoundError(String.format("No '%s' handler at '%s'", request.getMethod(), + request.getUri().getPath())); + } + + /** Returns a URI which points to an overview badge for the given application. */ + private HttpResponse badge(String tenant, String application, String instance) { + URI location = controller.jobController().overviewBadge(ApplicationId.from(tenant, application, instance)); + return redirect(location); + } + + /** Returns a URI which points to a history badge for the given application and job type. */ + private HttpResponse badge(String tenant, String application, String instance, String jobName, String historyLength) { + URI location = controller.jobController().historicBadge(ApplicationId.from(tenant, application, instance), + JobType.fromJobName(jobName), + historyLength == null ? 5 : Math.min(32, Math.max(0, Integer.parseInt(historyLength)))); + return redirect(location); + } + + private static HttpResponse redirect(URI location) { + HttpResponse httpResponse = new HttpResponse(Response.Status.FOUND) { + @Override public void render(OutputStream outputStream) { } + }; + httpResponse.headers().add("Location", location.toString()); + return httpResponse; + } + +} diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java index 40132523988..f0a26bb2dd4 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java @@ -105,6 +105,9 @@ public class ControllerContainerTest { " \n" + " http://*/deployment/v1/*\n" + " \n" + + " \n" + + " http://*/badge/v1/*\n" + + " \n" + " \n" + " http://*/controller/v1/*\n" + " \n" + diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java index d455218f4e9..d267dabe9a6 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java @@ -463,13 +463,6 @@ public class ApplicationApiTest extends ControllerContainerTest { .data(createApplicationSubmissionData(packageWithService)), "{\"version\":\"1.0.43-d00d\"}"); - tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/default/badge", GET) - .userIdentity(USER_ID), - "", 302); - tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/default/badge/system-test?historyLength=2", GET) - .userIdentity(USER_ID), - "", 302); - ApplicationId app1 = ApplicationId.from("tenant1", "application1", "default"); tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/jobreport", POST) .screwdriverIdentity(SCREWDRIVER_ID) diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/deployment/BadgeApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/deployment/BadgeApiTest.java new file mode 100644 index 00000000000..ba4924432d0 --- /dev/null +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/deployment/BadgeApiTest.java @@ -0,0 +1,46 @@ +package com.yahoo.vespa.hosted.controller.restapi.deployment; + +import com.yahoo.config.provision.AthenzService; +import com.yahoo.config.provision.Environment; +import com.yahoo.vespa.hosted.controller.Application; +import com.yahoo.vespa.hosted.controller.api.identifiers.ScrewdriverId; +import com.yahoo.vespa.hosted.controller.api.identifiers.UserId; +import com.yahoo.vespa.hosted.controller.api.integration.deployment.SourceRevision; +import com.yahoo.vespa.hosted.controller.application.ApplicationPackage; +import com.yahoo.vespa.hosted.controller.deployment.ApplicationPackageBuilder; +import com.yahoo.vespa.hosted.controller.restapi.ContainerControllerTester; +import com.yahoo.vespa.hosted.controller.restapi.ControllerContainerTest; +import org.junit.Test; + +/** + * @author jonmv + */ +public class BadgeApiTest extends ControllerContainerTest { + + private static final String responseFiles = "src/test/java/com/yahoo/vespa/hosted/controller/restapi/deployment/responses/"; + private static final ScrewdriverId SCREWDRIVER_ID = new ScrewdriverId("12345"); + private static final UserId USER_ID = new UserId("myuser"); + + @Test + public void testBadgeApi() { + ContainerControllerTester tester = new ContainerControllerTester(container, responseFiles); + Application application = tester.createApplication("domain", "tenant", "application"); + ApplicationPackage packageWithService = new ApplicationPackageBuilder() + .environment(Environment.prod) + .athenzIdentity(com.yahoo.config.provision.AthenzDomain.from("domain"), AthenzService.from("service")) + .region("us-west-1") + .build(); + tester.controller().jobController().submit(application.id(), + new SourceRevision("repository", "branch", "commit"), + "foo@bar", + 123, + packageWithService.zippedContent(), + new byte[0]); + + tester.assertResponse(authenticatedRequest("http://localhost:8080/badge/v1/tenant/application/default"), + "", 302); + tester.assertResponse(authenticatedRequest("http://localhost:8080/badge/v1/tenant/application/default/system-test?historyLength=10"), + "", 302); + } + +} -- cgit v1.2.3