From 316ff09406bc1dcef0558f90755a12109824e81d Mon Sep 17 00:00:00 2001 From: Valerij Fredriksen Date: Tue, 6 Jul 2021 16:58:25 +0200 Subject: Cleanup ApplicationHandler --- .../config/server/http/v2/ApplicationHandler.java | 452 +++++++-------------- 1 file changed, 145 insertions(+), 307 deletions(-) (limited to 'configserver') diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java index f1704af99c8..e56fb0b1bcc 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java @@ -6,24 +6,22 @@ import com.yahoo.component.Version; import com.yahoo.config.application.api.ApplicationFile; import com.yahoo.config.model.api.Model; import com.yahoo.config.provision.ApplicationId; -import com.yahoo.config.provision.ApplicationName; import com.yahoo.config.provision.HostFilter; -import com.yahoo.config.provision.TenantName; +import com.yahoo.config.provision.InstanceName; import com.yahoo.config.provision.Zone; import com.yahoo.container.jdisc.HttpRequest; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.io.IOUtils; import com.yahoo.jdisc.Response; -import com.yahoo.jdisc.application.BindingMatch; -import com.yahoo.jdisc.application.UriPattern; +import com.yahoo.restapi.ErrorResponse; +import com.yahoo.restapi.MessageResponse; +import com.yahoo.restapi.Path; import com.yahoo.slime.SlimeUtils; import com.yahoo.text.StringUtilities; import com.yahoo.vespa.config.server.ApplicationRepository; import com.yahoo.vespa.config.server.http.ContentHandler; import com.yahoo.vespa.config.server.http.ContentRequest; -import com.yahoo.vespa.config.server.http.HttpErrorResponse; import com.yahoo.vespa.config.server.http.HttpHandler; -import com.yahoo.vespa.config.server.http.JSONResponse; import com.yahoo.vespa.config.server.http.NotFoundException; import com.yahoo.vespa.config.server.http.v2.request.ApplicationContentRequest; import com.yahoo.vespa.config.server.http.v2.response.ApplicationSuspendedResponse; @@ -34,22 +32,16 @@ import com.yahoo.vespa.config.server.http.v2.response.ReindexingResponse; import com.yahoo.vespa.config.server.tenant.Tenant; import java.io.IOException; -import java.net.URLDecoder; import java.time.Duration; import java.time.Instant; -import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.StringJoiner; import java.util.TreeMap; import java.util.TreeSet; -import java.util.stream.Stream; import static com.yahoo.yolean.Exceptions.uncheck; -import static java.nio.charset.StandardCharsets.UTF_8; -import static java.util.stream.Collectors.toList; /** * Operations on applications (delete, wait for config convergence, restart, application content etc.) @@ -58,28 +50,6 @@ import static java.util.stream.Collectors.toList; */ public class ApplicationHandler extends HttpHandler { - private static final List URI_PATTERNS = Stream.of( - "http://*/application/v2/tenant/*/application/*/environment/*/region/*/instance/*/content/*", - "http://*/application/v2/tenant/*/application/*/environment/*/region/*/instance/*/filedistributionstatus", - "http://*/application/v2/tenant/*/application/*/environment/*/region/*/instance/*/restart", - "http://*/application/v2/tenant/*/application/*/environment/*/region/*/instance/*/reindex", - "http://*/application/v2/tenant/*/application/*/environment/*/region/*/instance/*/reindexing", - "http://*/application/v2/tenant/*/application/*/environment/*/region/*/instance/*/suspended", - "http://*/application/v2/tenant/*/application/*/environment/*/region/*/instance/*/serviceconverge", - "http://*/application/v2/tenant/*/application/*/environment/*/region/*/instance/*/serviceconverge/*", - "http://*/application/v2/tenant/*/application/*/environment/*/region/*/instance/*/clustercontroller/*/status/*", - "http://*/application/v2/tenant/*/application/*/environment/*/region/*/instance/*/metrics/*", - "http://*/application/v2/tenant/*/application/*/environment/*/region/*/instance/*/metrics/*", - "http://*/application/v2/tenant/*/application/*/environment/*/region/*/instance/*/logs", - "http://*/application/v2/tenant/*/application/*/environment/*/region/*/instance/*/validate-secret-store", - "http://*/application/v2/tenant/*/application/*/environment/*/region/*/instance/*/tester/*/*", - "http://*/application/v2/tenant/*/application/*/environment/*/region/*/instance/*/tester/*", - "http://*/application/v2/tenant/*/application/*/environment/*/region/*/instance/*/quota", - "http://*/application/v2/tenant/*/application/*/environment/*/region/*/instance/*", - "http://*/application/v2/tenant/*/application/*") - .map(UriPattern::new) - .collect(toList()); - private final Zone zone; private final ApplicationRepository applicationRepository; @@ -93,152 +63,135 @@ public class ApplicationHandler extends HttpHandler { } @Override - public HttpResponse handleDELETE(HttpRequest request) { - ApplicationId applicationId = getApplicationIdFromRequest(request); - - if (isReindexingRequest(request)) { - applicationRepository.modifyReindexing(applicationId, reindexing -> reindexing.enabled(false)); - return createMessageResponse("Reindexing disabled"); - } + public HttpResponse handleGET(HttpRequest request) { + Path path = new Path(request.getUri()); + + if (path.matches("/application/v2/tenant/{tenant}/application/{application}")) return getApplicationResponse(ApplicationId.from(path.get("tenant"), path.get("application"), InstanceName.defaultName().value())); + if (path.matches("/application/v2/tenant/{tenant}/application/{application}/environment/{ignore}/region/{ignore}/instance/{instance}")) return getApplicationResponse(applicationId(path)); + if (path.matches("/application/v2/tenant/{tenant}/application/{application}/environment/{ignore}/region/{ignore}/instance/{instance}/clustercontroller/{hostname}/status/{*}")) return clusterControllerStatusPage(applicationId(path), path.get("hostname"), path.getRest()); + if (path.matches("/application/v2/tenant/{tenant}/application/{application}/environment/{ignore}/region/{ignore}/instance/{instance}/content/{*}")) return content(applicationId(path), path.getRest(), request); + if (path.matches("/application/v2/tenant/{tenant}/application/{application}/environment/{ignore}/region/{ignore}/instance/{instance}/filedistributionstatus")) return filedistributionStatus(applicationId(path), request); + if (path.matches("/application/v2/tenant/{tenant}/application/{application}/environment/{ignore}/region/{ignore}/instance/{instance}/logs")) return logs(applicationId(path), request); + if (path.matches("/application/v2/tenant/{tenant}/application/{application}/environment/{ignore}/region/{ignore}/instance/{instance}/metrics/deployment")) return deploymentMetrics(applicationId(path)); + if (path.matches("/application/v2/tenant/{tenant}/application/{application}/environment/{ignore}/region/{ignore}/instance/{instance}/metrics/proton")) return protonMetrics(applicationId(path)); + if (path.matches("/application/v2/tenant/{tenant}/application/{application}/environment/{ignore}/region/{ignore}/instance/{instance}/reindexing")) return getReindexingStatus(applicationId(path)); + if (path.matches("/application/v2/tenant/{tenant}/application/{application}/environment/{ignore}/region/{ignore}/instance/{instance}/serviceconverge")) return listServiceConverge(applicationId(path), request); + if (path.matches("/application/v2/tenant/{tenant}/application/{application}/environment/{ignore}/region/{ignore}/instance/{instance}/serviceconverge/{hostAndPort}")) return checkServiceConverge(applicationId(path), path.get("hostAndPort"), request); + if (path.matches("/application/v2/tenant/{tenant}/application/{application}/environment/{ignore}/region/{ignore}/instance/{instance}/suspended")) return isSuspended(applicationId(path)); + if (path.matches("/application/v2/tenant/{tenant}/application/{application}/environment/{ignore}/region/{ignore}/instance/{instance}/tester/{command}")) return testerRequest(applicationId(path), path.get("command"), request); + if (path.matches("/application/v2/tenant/{tenant}/application/{application}/environment/{ignore}/region/{ignore}/instance/{instance}/quota")) return quotaUsage(applicationId(path)); + return ErrorResponse.notFoundError("Nothing at " + path); + } - if (applicationRepository.delete(applicationId)) - return new DeleteApplicationResponse(applicationId); + @Override + public HttpResponse handlePOST(HttpRequest request) { + Path path = new Path(request.getUri()); - return HttpErrorResponse.notFoundError("Unable to delete " + applicationId.toFullString() + ": Not found"); + if (path.matches("/application/v2/tenant/{tenant}/application/{application}/environment/{ignore}/region/{ignore}/instance/{instance}/reindex")) return triggerReindexing(applicationId(path), request); + if (path.matches("/application/v2/tenant/{tenant}/application/{application}/environment/{ignore}/region/{ignore}/instance/{instance}/reindexing")) return enableReindexing(applicationId(path)); + if (path.matches("/application/v2/tenant/{tenant}/application/{application}/environment/{ignore}/region/{ignore}/instance/{instance}/restart")) return restart(applicationId(path), request); + if (path.matches("/application/v2/tenant/{tenant}/application/{application}/environment/{ignore}/region/{ignore}/instance/{instance}/tester/run/{suite}")) return testerStartTests(applicationId(path), path.get("suite"), request); + if (path.matches("/application/v2/tenant/{tenant}/application/{application}/environment/{ignore}/region/{ignore}/instance/{instance}/validate-secret-store")) return validateSecretStore(applicationId(path), request); + return ErrorResponse.notFoundError("Nothing at " + path); } @Override - public HttpResponse handleGET(HttpRequest request) { - ApplicationId applicationId = getApplicationIdFromRequest(request); - Duration timeout = HttpHandler.getRequestTimeout(request, Duration.ofSeconds(5)); - - if (isServiceConvergeRequest(request)) { - // Expects both hostname and port in the request (hostname:port) - String hostAndPort = getHostNameFromRequest(request); - return applicationRepository.checkServiceForConfigConvergence(applicationId, hostAndPort, request.getUri(), - timeout, getVespaVersionFromRequest(request)); - } + public HttpResponse handleDELETE(HttpRequest request) { + Path path = new Path(request.getUri()); - if (isClusterControllerStatusRequest(request)) { - String hostName = getHostNameFromRequest(request); - String pathSuffix = URLDecoder.decode(getPathSuffix(request), UTF_8); - return applicationRepository.clusterControllerStatusPage(applicationId, hostName, pathSuffix); - } + if (path.matches("/application/v2/tenant/{tenant}/application/{application}")) return deleteApplication(ApplicationId.from(path.get("tenant"), path.get("application"), InstanceName.defaultName().value())); + if (path.matches("/application/v2/tenant/{tenant}/application/{application}/environment/{ignore}/region/{ignore}/instance/{instance}")) return deleteApplication(applicationId(path)); + if (path.matches("/application/v2/tenant/{tenant}/application/{application}/environment/{ignore}/region/{ignore}/instance/{instance}/reindexing")) return disableReindexing(applicationId(path)); + return ErrorResponse.notFoundError("Nothing at " + path); + } - if (isReindexingRequest(request)) { - return getReindexingStatus(applicationId); - } + private HttpResponse listServiceConverge(ApplicationId applicationId, HttpRequest request) { + return applicationRepository.servicesToCheckForConfigConvergence(applicationId, request.getUri(), + getTimeoutFromRequest(request), getVespaVersionFromRequest(request)); + } - if (isContentRequest(request)) { - long sessionId = applicationRepository.getSessionIdForApplication(applicationId); - String contentPath = getBindingMatch(request).group(7); - ApplicationFile applicationFile = - applicationRepository.getApplicationFileFromSession(applicationId.tenant(), - sessionId, - contentPath, - ContentRequest.getApplicationFileMode(request.getMethod())); - ApplicationContentRequest contentRequest = new ApplicationContentRequest(request, - sessionId, - applicationId, - zone, - contentPath, - applicationFile); - return new ContentHandler().get(contentRequest); - } + private HttpResponse checkServiceConverge(ApplicationId applicationId, String hostAndPort, HttpRequest request) { + return applicationRepository.checkServiceForConfigConvergence(applicationId, hostAndPort, request.getUri(), + getTimeoutFromRequest(request), getVespaVersionFromRequest(request)); + } - if (isServiceConvergeListRequest(request)) { - return applicationRepository.servicesToCheckForConfigConvergence(applicationId, request.getUri(), timeout, - getVespaVersionFromRequest(request)); - } + private HttpResponse clusterControllerStatusPage(ApplicationId applicationId, String hostname, String pathSuffix) { + return applicationRepository.clusterControllerStatusPage(applicationId, hostname, pathSuffix); + } - if (isFiledistributionStatusRequest(request)) { - return applicationRepository.filedistributionStatus(applicationId, timeout); - } + private HttpResponse content(ApplicationId applicationId, String contentPath, HttpRequest request) { + long sessionId = applicationRepository.getSessionIdForApplication(applicationId); + ApplicationFile applicationFile = + applicationRepository.getApplicationFileFromSession(applicationId.tenant(), + sessionId, + contentPath, + ContentRequest.getApplicationFileMode(request.getMethod())); + ApplicationContentRequest contentRequest = new ApplicationContentRequest(request, + sessionId, + applicationId, + zone, + contentPath, + applicationFile); + return new ContentHandler().get(contentRequest); + } - if (isLogRequest(request)) { - Optional hostname = Optional.ofNullable(request.getProperty("hostname")); - String apiParams = Optional.ofNullable(request.getUri().getQuery()).map(q -> "?" + q).orElse(""); - return applicationRepository.getLogs(applicationId, hostname, apiParams); - } + private HttpResponse filedistributionStatus(ApplicationId applicationId, HttpRequest request) { + return applicationRepository.filedistributionStatus(applicationId, getTimeoutFromRequest(request)); + } - if (isProtonMetricsRequest(request)) { - return applicationRepository.getProtonMetrics(applicationId); - } + private HttpResponse logs(ApplicationId applicationId, HttpRequest request) { + Optional hostname = Optional.ofNullable(request.getProperty("hostname")); + String apiParams = Optional.ofNullable(request.getUri().getQuery()).map(q -> "?" + q).orElse(""); + return applicationRepository.getLogs(applicationId, hostname, apiParams); + } - if (isDeploymentMetricsRequest(request)) { - return applicationRepository.getDeploymentMetrics(applicationId); - } + private HttpResponse protonMetrics(ApplicationId applicationId) { + return applicationRepository.getProtonMetrics(applicationId); + } - if (isIsSuspendedRequest(request)) { - return new ApplicationSuspendedResponse(applicationRepository.isSuspended(applicationId)); - } + private HttpResponse deploymentMetrics(ApplicationId applicationId) { + return applicationRepository.getDeploymentMetrics(applicationId); + } - if (isTesterRequest(request)) { - String testerCommand = getTesterCommandFromRequest(request); - switch (testerCommand) { - case "status": - return applicationRepository.getTesterStatus(applicationId); - case "log": - Long after = Long.valueOf(request.getProperty("after")); - return applicationRepository.getTesterLog(applicationId, after); - case "ready": - return applicationRepository.isTesterReady(applicationId); - case "report": - return applicationRepository.getTestReport(applicationId); - default: - throw new IllegalArgumentException("Unknown tester command in request " + request.getUri().toString()); - } - } + private HttpResponse isSuspended(ApplicationId applicationId) { + return new ApplicationSuspendedResponse(applicationRepository.isSuspended(applicationId)); + } - if (isQuotaUsageRequest(request)) { - var quotaUsageRate = applicationRepository.getQuotaUsageRate(applicationId); - return new QuotaUsageResponse(quotaUsageRate); + private HttpResponse testerRequest(ApplicationId applicationId, String command, HttpRequest request) { + switch (command) { + case "status": + return applicationRepository.getTesterStatus(applicationId); + case "log": + Long after = Long.valueOf(request.getProperty("after")); + return applicationRepository.getTesterLog(applicationId, after); + case "ready": + return applicationRepository.isTesterReady(applicationId); + case "report": + return applicationRepository.getTestReport(applicationId); + default: + throw new IllegalArgumentException("Unknown tester command in request " + request.getUri().toString()); } + } - return getApplicationResponse(applicationId); + private HttpResponse quotaUsage(ApplicationId applicationId) { + double quotaUsageRate = applicationRepository.getQuotaUsageRate(applicationId); + return new QuotaUsageResponse(quotaUsageRate); } - GetApplicationResponse getApplicationResponse(ApplicationId applicationId) { + private HttpResponse getApplicationResponse(ApplicationId applicationId) { return new GetApplicationResponse(Response.Status.OK, - applicationRepository.getApplicationGeneration(applicationId), - applicationRepository.getAllVersions(applicationId), - applicationRepository.getApplicationPackageReference(applicationId)); + applicationRepository.getApplicationGeneration(applicationId), + applicationRepository.getAllVersions(applicationId), + applicationRepository.getApplicationPackageReference(applicationId)); } - @Override - public HttpResponse handlePOST(HttpRequest request) { - ApplicationId applicationId = getApplicationIdFromRequest(request); - - if (isRestartRequest(request)) - return restart(request, applicationId); - - if (isTesterStartTestsRequest(request)) { - byte[] data; - try { - data = IOUtils.readBytes(request.getData(), 1024 * 1000); - } catch (IOException e) { - throw new IllegalArgumentException("Could not read data in request " + request); - } - return applicationRepository.startTests(applicationId, getSuiteFromRequest(request), data); - } - - if (isReindexRequest(request)) { - return triggerReindexing(request, applicationId); - } - - if (isReindexingRequest(request)) { - applicationRepository.modifyReindexing(applicationId, reindexing -> reindexing.enabled(true)); - return createMessageResponse("Reindexing enabled"); - } - - if (isValidateSecretStoreRequest(request)) { - var slime = uncheck(() -> SlimeUtils.jsonToSlime(request.getData().readAllBytes())); - return applicationRepository.validateSecretStore(applicationId, zone.system(), slime); - } - - throw new NotFoundException("Illegal POST request '" + request.getUri() + "'"); + public HttpResponse deleteApplication(ApplicationId applicationId) { + if (applicationRepository.delete(applicationId)) + return new DeleteApplicationResponse(applicationId); + return ErrorResponse.notFoundError("Unable to delete " + applicationId.toFullString() + ": Not found"); } + private Model getActiveModelOrThrow(ApplicationId id) { return applicationRepository.getActiveApplicationSet(id) .orElseThrow(() -> new NotFoundException("Application '" + id + "' not found")) @@ -246,7 +199,7 @@ public class ApplicationHandler extends HttpHandler { .getModel(); } - private HttpResponse triggerReindexing(HttpRequest request, ApplicationId applicationId) { + private HttpResponse triggerReindexing(ApplicationId applicationId, HttpRequest request) { Model model = getActiveModelOrThrow(applicationId); Map> documentTypes = model.documentTypesByCluster(); Map> indexedDocumentTypes = model.indexedDocumentTypesByCluster(); @@ -277,7 +230,7 @@ public class ApplicationHandler extends HttpHandler { return reindexing; }); - return createMessageResponse(reindexed.entrySet().stream() + return new MessageResponse(reindexed.entrySet().stream() .filter(cluster -> ! cluster.getValue().isEmpty()) .map(cluster -> "[" + String.join(", ", cluster.getValue()) + "] in '" + cluster.getKey() + "'") .reduce(new StringJoiner(", ", "Reindexing document types ", " of application " + applicationId) @@ -287,6 +240,16 @@ public class ApplicationHandler extends HttpHandler { .toString()); } + public HttpResponse disableReindexing(ApplicationId applicationId) { + applicationRepository.modifyReindexing(applicationId, reindexing -> reindexing.enabled(false)); + return new MessageResponse("Reindexing disabled"); + } + + private HttpResponse enableReindexing(ApplicationId applicationId) { + applicationRepository.modifyReindexing(applicationId, reindexing -> reindexing.enabled(true)); + return new MessageResponse("Reindexing enabled"); + } + private HttpResponse getReindexingStatus(ApplicationId applicationId) { Tenant tenant = applicationRepository.getTenant(applicationId); if (tenant == null) @@ -297,167 +260,42 @@ public class ApplicationHandler extends HttpHandler { applicationRepository.getClusterReindexingStatus(applicationId)); } - private HttpResponse restart(HttpRequest request, ApplicationId applicationId) { - if (getBindingMatch(request).groupCount() != 7) - throw new NotFoundException("Illegal POST restart request '" + request.getUri() + - "': Must have 6 arguments but had " + (getBindingMatch(request).groupCount() - 1)); - applicationRepository.restart(applicationId, hostFilterFrom(request)); - return new JSONResponse(Response.Status.OK); // return empty - } - - private HostFilter hostFilterFrom(HttpRequest request) { - return HostFilter.from(request.getProperty("hostname"), - request.getProperty("flavor"), - request.getProperty("clusterType"), - request.getProperty("clusterId")); - } - - private static BindingMatch getBindingMatch(HttpRequest request) { - return URI_PATTERNS.stream() - .map(pattern -> { - UriPattern.Match match = pattern.match(request.getUri()); - if (match == null) return null; - return new BindingMatch<>(match, new Object(), pattern); - }) - .filter(Objects::nonNull) - .findFirst() - .orElseThrow(() -> new IllegalArgumentException("Illegal url for config request: " + request.getUri())); - } - - private static boolean isRestartRequest(HttpRequest request) { - return getBindingMatch(request).groupCount() == 7 && - request.getUri().getPath().endsWith("/restart"); - } - - private static boolean isReindexRequest(HttpRequest request) { - return getBindingMatch(request).groupCount() == 7 && - request.getUri().getPath().endsWith("/reindex"); - } - - private static boolean isReindexingRequest(HttpRequest request) { - return getBindingMatch(request).groupCount() == 7 && - request.getUri().getPath().endsWith("/reindexing"); - } - - private static boolean isIsSuspendedRequest(HttpRequest request) { - return getBindingMatch(request).groupCount() == 7 && - request.getUri().getPath().endsWith("/suspended"); - } - - private static boolean isProtonMetricsRequest(HttpRequest request) { - return getBindingMatch(request).groupCount() == 8 && - request.getUri().getPath().endsWith("/metrics/proton"); - } - - private static boolean isDeploymentMetricsRequest(HttpRequest request) { - return getBindingMatch(request).groupCount() == 8 && - request.getUri().getPath().endsWith("/metrics/deployment"); - } - - private static boolean isLogRequest(HttpRequest request) { - return getBindingMatch(request).groupCount() == 7 && - request.getUri().getPath().endsWith("/logs"); - } - - private static boolean isValidateSecretStoreRequest(HttpRequest request) { - return getBindingMatch(request).groupCount() == 7 && - request.getUri().getPath().endsWith("/validate-secret-store"); + private HttpResponse restart(ApplicationId applicationId, HttpRequest request) { + HostFilter filter = HostFilter.from(request.getProperty("hostname"), + request.getProperty("flavor"), + request.getProperty("clusterType"), + request.getProperty("clusterId")); + applicationRepository.restart(applicationId, filter); + return new MessageResponse("Success"); } - private static boolean isServiceConvergeListRequest(HttpRequest request) { - return getBindingMatch(request).groupCount() == 7 && - request.getUri().getPath().endsWith("/serviceconverge"); - } - - private static boolean isServiceConvergeRequest(HttpRequest request) { - return getBindingMatch(request).groupCount() == 8 && - request.getUri().getPath().contains("/serviceconverge/"); - } - - private static boolean isClusterControllerStatusRequest(HttpRequest request) { - return getBindingMatch(request).groupCount() == 9 && - request.getUri().getPath().contains("/clustercontroller/"); - } - - private static boolean isContentRequest(HttpRequest request) { - return getBindingMatch(request).groupCount() > 7 && - request.getUri().getPath().contains("/content/"); - } - - private static boolean isFiledistributionStatusRequest(HttpRequest request) { - return getBindingMatch(request).groupCount() == 7 && - request.getUri().getPath().contains("/filedistributionstatus"); - } - - private static boolean isTesterRequest(HttpRequest request) { - return getBindingMatch(request).groupCount() == 8 && - request.getUri().getPath().contains("/tester"); - } - - private static boolean isTesterStartTestsRequest(HttpRequest request) { - return getBindingMatch(request).groupCount() == 9 && - request.getUri().getPath().contains("/tester/run/"); - } - - private static boolean isQuotaUsageRequest(HttpRequest request) { - return getBindingMatch(request).groupCount() == 7 && - request.getUri().getPath().endsWith("/quota"); - } - - private static String getHostNameFromRequest(HttpRequest req) { - BindingMatch bm = getBindingMatch(req); - return bm.group(7); - } - - private static String getTesterCommandFromRequest(HttpRequest req) { - BindingMatch bm = getBindingMatch(req); - return bm.group(7); - } - - private static String getSuiteFromRequest(HttpRequest req) { - BindingMatch bm = getBindingMatch(req); - return bm.group(8); - } - - private static String getPathSuffix(HttpRequest req) { - BindingMatch bm = getBindingMatch(req); - return bm.group(8); + private HttpResponse testerStartTests(ApplicationId applicationId, String suite, HttpRequest request) { + byte[] data; + try { + data = IOUtils.readBytes(request.getData(), 1024 * 1000); + } catch (IOException e) { + throw new IllegalArgumentException("Could not read data in request " + request); + } + return applicationRepository.startTests(applicationId, suite, data); } - private static ApplicationId getApplicationIdFromRequest(HttpRequest req) { - // Two bindings for this: with full app id or only application name - BindingMatch bm = getBindingMatch(req); - if (bm.groupCount() > 4) return createFromRequestFullAppId(bm); - return createFromRequestSimpleAppId(bm); + private HttpResponse validateSecretStore(ApplicationId applicationId, HttpRequest request) { + var slime = uncheck(() -> SlimeUtils.jsonToSlime(request.getData().readAllBytes())); + return applicationRepository.validateSecretStore(applicationId, zone.system(), slime); } - // The URL pattern with only tenant and application given - private static ApplicationId createFromRequestSimpleAppId(BindingMatch bm) { - TenantName tenant = TenantName.from(bm.group(2)); - ApplicationName application = ApplicationName.from(bm.group(3)); - return new ApplicationId.Builder().tenant(tenant).applicationName(application).build(); + private static ApplicationId applicationId(Path path) { + return ApplicationId.from(path.get("tenant"), path.get("application"), path.get("instance")); } - // The URL pattern with full app id given - private static ApplicationId createFromRequestFullAppId(BindingMatch bm) { - String tenant = bm.group(2); - String application = bm.group(3); - String instance = bm.group(6); - return new ApplicationId.Builder() - .tenant(tenant) - .applicationName(application).instanceName(instance) - .build(); + private static Duration getTimeoutFromRequest(HttpRequest request) { + return HttpHandler.getRequestTimeout(request, Duration.ofSeconds(5)); } private static Optional getVespaVersionFromRequest(HttpRequest request) { - String vespaVersion = request.getProperty("vespaVersion"); - return (vespaVersion == null || vespaVersion.isEmpty()) - ? Optional.empty() - : Optional.of(Version.fromString(vespaVersion)); - } - - private static JSONResponse createMessageResponse(String message) { - return new JSONResponse(Response.Status.OK) { { object.setString("message", message); } }; + return Optional.ofNullable(request.getProperty("vespaVersion")) + .filter(s -> !s.isEmpty()) + .map(Version::fromString); } } -- cgit v1.2.3