diff options
author | Valerij Fredriksen <valerijf@verizonmedia.com> | 2020-09-17 13:20:30 +0200 |
---|---|---|
committer | Valerij Fredriksen <valerijf@verizonmedia.com> | 2020-09-17 13:21:18 +0200 |
commit | 61ef54a2e90dbe4918e76cc180f477023a31b085 (patch) | |
tree | a66210fa826a6cd335ec29991a32f687307cc24b | |
parent | 0327c08270ee4d538eaba6f0b5a94cf3edd72eca (diff) |
Implement content API in application v4
6 files changed, 70 insertions, 3 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java index 317b29cf621..23a9ca79b53 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java @@ -17,6 +17,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.noderepository.RestartF import com.yahoo.vespa.serviceview.bindings.ApplicationView; import java.io.InputStream; +import java.net.URI; import java.util.List; import java.util.Map; import java.util.Optional; @@ -55,6 +56,16 @@ public interface ConfigServer { */ InputStream getLogs(DeploymentId deployment, Map<String, String> queryParameters); + /** + * Gets the contents of a file inside the current application package for a given deployment. If the path is to + * a directly, a JSON list with URLs to contents is returned. + * + * @param deployment deployment to get application package content for + * @param path path within package to get + * @param requestUri request URI on the controller, used to rewrite paths in response from config server + */ + ProxyResponse getApplicationPackageContent(DeploymentId deployment, String path, URI requestUri); + List<ClusterMetrics> getDeploymentMetrics(DeploymentId deployment); List<ProtonMetrics> getProtonMetrics(DeploymentId deployment); diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ProxyResponse.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ProxyResponse.java new file mode 100644 index 00000000000..8570155861a --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ProxyResponse.java @@ -0,0 +1,33 @@ +package com.yahoo.vespa.hosted.controller.api.integration.configserver; + +import com.yahoo.container.jdisc.HttpResponse; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.util.Optional; + +/** + * @author valerijf + */ +public class ProxyResponse extends HttpResponse { + + private final String content; + private final String contentType; + + public ProxyResponse(String content, String contentType, int status) { + super(status); + this.content = content; + this.contentType = contentType; + } + + @Override + public void render(OutputStream outputStream) throws IOException { + outputStream.write(content.getBytes(StandardCharsets.UTF_8)); + } + + @Override + public String getContentType() { + return Optional.ofNullable(contentType).orElseGet(super::getContentType); + } +} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java index 571fd649f04..95f394aefef 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java @@ -111,6 +111,7 @@ enum PathGroup { "/application/v4/tenant/{tenant}/application/{application}/instance/{ignored}/job/{*}", "/application/v4/tenant/{tenant}/application/{application}/instance/{ignored}/environment/{environment}/region/{region}/nodes", "/application/v4/tenant/{tenant}/application/{application}/instance/{ignored}/environment/{environment}/region/{region}/clusters", + "/application/v4/tenant/{tenant}/application/{application}/instance/{ignored}/environment/{environment}/region/{region}/content/{*}", "/application/v4/tenant/{tenant}/application/{application}/instance/{ignored}/environment/{environment}/region/{region}/logs", "/application/v4/tenant/{tenant}/application/{application}/instance/{ignored}/environment/{environment}/region/{region}/suspended", "/application/v4/tenant/{tenant}/application/{application}/instance/{ignored}/environment/{environment}/region/{region}/service/{*}", 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 7da8ac74936..81b4c4cc72f 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 @@ -92,6 +92,9 @@ import com.yahoo.vespa.hosted.controller.versions.VersionStatus; import com.yahoo.vespa.hosted.controller.versions.VespaVersion; import com.yahoo.vespa.serviceview.bindings.ApplicationView; import com.yahoo.yolean.Exceptions; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; import javax.ws.rs.ForbiddenException; import javax.ws.rs.InternalServerErrorException; @@ -101,6 +104,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.URI; import java.net.URISyntaxException; +import java.nio.file.Paths; import java.security.DigestInputStream; import java.security.Principal; import java.security.PublicKey; @@ -120,9 +124,6 @@ import java.util.Scanner; import java.util.StringJoiner; import java.util.logging.Level; import java.util.stream.Collectors; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; import static com.yahoo.jdisc.Response.Status.BAD_REQUEST; import static com.yahoo.jdisc.Response.Status.CONFLICT; @@ -232,6 +233,7 @@ public class ApplicationApiHandler extends LoggingRequestHandler { if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/environment/{environment}/region/{region}/service/{service}/{*}")) return service(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), path.get("service"), path.getRest(), request); if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/environment/{environment}/region/{region}/nodes")) return nodes(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region")); if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/environment/{environment}/region/{region}/clusters")) return clusters(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region")); + if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/environment/{environment}/region/{region}/content/{*}")) return content(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), path.getRest(), request); if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/environment/{environment}/region/{region}/logs")) return logs(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), request.propertyMap()); if (path.matches("/application/v4/tenant/{tenant}/application/{application}/environment/{environment}/region/{region}/instance/{instance}/metrics")) return metrics(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region")); if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/environment/{environment}/region/{region}/global-rotation")) return rotationStatus(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), Optional.ofNullable(request.getProperty("endpointId"))); @@ -1316,6 +1318,11 @@ public class ApplicationApiHandler extends LoggingRequestHandler { return response; } + private HttpResponse content(String tenantName, String applicationName, String instanceName, String environment, String region, String restPath, HttpRequest request) { + DeploymentId deploymentId = new DeploymentId(ApplicationId.from(tenantName, applicationName, instanceName), ZoneId.from(environment, region)); + return controller.serviceRegistry().configServer().getApplicationPackageContent(deploymentId, "/" + restPath, request.getUri()); + } + private HttpResponse updateTenant(String tenantName, HttpRequest request) { getTenantOrThrow(tenantName); TenantName tenant = TenantName.from(tenantName); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java index 1dd3b4a7a47..85e456afa60 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java @@ -30,6 +30,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.configserver.Log; import com.yahoo.vespa.hosted.controller.api.integration.configserver.Node; import com.yahoo.vespa.hosted.controller.api.integration.configserver.NotFoundException; import com.yahoo.vespa.hosted.controller.api.integration.configserver.PrepareResponse; +import com.yahoo.vespa.hosted.controller.api.integration.configserver.ProxyResponse; import com.yahoo.vespa.hosted.controller.api.integration.configserver.ServiceConvergence; import com.yahoo.vespa.hosted.controller.api.integration.deployment.TestReport; import com.yahoo.vespa.hosted.controller.api.integration.deployment.TesterCloud; @@ -42,6 +43,7 @@ import com.yahoo.vespa.serviceview.bindings.ServiceView; import java.io.ByteArrayInputStream; import java.io.InputStream; +import java.net.URI; import java.nio.charset.StandardCharsets; import java.time.Instant; import java.util.ArrayList; @@ -516,6 +518,11 @@ public class ConfigServerMock extends AbstractComponent implements ConfigServer return new ByteArrayInputStream(log.getBytes(StandardCharsets.UTF_8)); } + @Override + public ProxyResponse getApplicationPackageContent(DeploymentId deployment, String path, URI requestUri) { + return new ProxyResponse("{\"path\":\"" + path + "\"}", "application/json", 200); + } + public void setLogStream(String log) { this.log = log; } 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 2f514bd05cd..8a16e066119 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 @@ -495,6 +495,14 @@ public class ApplicationApiTest extends ControllerContainerTest { .userIdentity(USER_ID), "INFO - All good"); + // Get content - root + tester.assertResponse(request("/application/v4/tenant/tenant2/application/application1/instance/default/environment/dev/region/us-central-1/content/", GET).userIdentity(USER_ID), + "{\"path\":\"/\"}"); + // Get content - ignore query params + tester.assertResponse(request("/application/v4/tenant/tenant2/application/application1/instance/default/environment/dev/region/us-central-1/content/bar/file.json?query=param", GET).userIdentity(USER_ID), + "{\"path\":\"/bar/file.json\"}"); + + updateMetrics(); // GET metrics |