diff options
author | jonmv <venstad@gmail.com> | 2024-05-22 13:36:10 +0200 |
---|---|---|
committer | jonmv <venstad@gmail.com> | 2024-05-22 13:36:10 +0200 |
commit | 404a8e500011d835898a3322f60103d8087f780d (patch) | |
tree | 92938a1571abd27a6b94e65b2ab724af3ba5a1a9 /configserver | |
parent | 0c63bb70d57d05444f3e899fbaa93d51057f0699 (diff) |
Signal tester suspension explicitly
Diffstat (limited to 'configserver')
4 files changed, 45 insertions, 38 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java index 22199dfc5b4..ee827e02082 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java @@ -42,6 +42,7 @@ import com.yahoo.path.Path; import com.yahoo.slime.Slime; import com.yahoo.transaction.NestedTransaction; import com.yahoo.transaction.Transaction; +import com.yahoo.vespa.applicationmodel.HostName; import com.yahoo.vespa.applicationmodel.InfrastructureApplication; import com.yahoo.vespa.config.server.application.ActiveTokenFingerprints; import com.yahoo.vespa.config.server.application.ActiveTokenFingerprints.Token; @@ -837,7 +838,11 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye } private String getTesterHostname(ApplicationId applicationId) { - return getTesterServiceInfo(applicationId).getHostName(); + String hostname = getTesterServiceInfo(applicationId).getHostName(); + if (orchestrator.getNodeStatus(new HostName(hostname)).isSuspended()) + throw new TesterSuspendedException("tester container is suspended"); + + return hostname; } private int getTesterPort(ApplicationId applicationId) { @@ -855,6 +860,12 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye .orElseThrow(() -> new InternalServerException("Could not find any tester container for tester app " + applicationId.toFullString())); } + public static class TesterSuspendedException extends RuntimeException { + public TesterSuspendedException(String message) { + super(message); + } + } + // ---------------- Session operations ---------------------------------------------------------------- public Activation activate(Session session, ApplicationId applicationId, Tenant tenant, boolean force) { diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/HttpErrorResponse.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/HttpErrorResponse.java index c230e4e5a7a..e6025ec6a38 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/HttpErrorResponse.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/HttpErrorResponse.java @@ -54,6 +54,7 @@ public class HttpErrorResponse extends HttpResponse { CONFIG_NOT_CONVERGED, REINDEXING_STATUS_UNAVAILABLE, PRECONDITION_FAILED, + TESTER_SUSPENDED, QUOTA_EXCEEDED } @@ -121,6 +122,10 @@ public class HttpErrorResponse extends HttpResponse { return new HttpErrorResponse(PRECONDITION_FAILED, ErrorCode.PRECONDITION_FAILED.name(), msg); } + public static HttpResponse testerSuspended(String msg) { + return new HttpErrorResponse(CONFLICT, ErrorCode.TESTER_SUSPENDED.name(), msg); + } + public static HttpResponse quotaExceeded(String msg) { return new HttpErrorResponse(BAD_REQUEST, ErrorCode.QUOTA_EXCEEDED.name(), msg); } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/TesterClient.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/TesterClient.java index 53f3b4fb976..a18f96e83bb 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/TesterClient.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/TesterClient.java @@ -1,6 +1,11 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.config.server.http; +import ai.vespa.http.DomainName; +import ai.vespa.http.HttpURL; +import ai.vespa.http.HttpURL.Path; +import ai.vespa.http.HttpURL.Query; +import ai.vespa.http.HttpURL.Scheme; import ai.vespa.util.http.hc5.VespaHttpClientBuilder; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.yolean.Exceptions; @@ -15,6 +20,7 @@ import org.apache.http.client.utils.URIBuilder; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -27,40 +33,30 @@ public class TesterClient { private static final Logger logger = Logger.getLogger(TesterClient.class.getName()); public HttpResponse getStatus(String testerHostname, int port) { - URI testerUri = createURI(testerHostname, port, "/tester/v1/status"); - + URI testerUri = testerUrl(testerHostname, port, "tester", "v1", "status").asURI(); return execute(new HttpGet(testerUri), "Failed to get tester status"); } public HttpResponse getLog(String testerHostname, int port, Long after) { - URI testerUri; - try { - testerUri = createBuilder(testerHostname, port, "/tester/v1/log") - .addParameter("after", String.valueOf(after)) - .build(); - } catch (URISyntaxException e) { - throw new IllegalArgumentException(e); - } - + URI testerUri = testerUrl(testerHostname, port, "tester", "v1", "log") + .withQuery(Query.empty().set("after", Long.toString(after))).asURI(); return execute(new HttpGet(testerUri), "Failed to get tester logs"); } public HttpResponse startTests(String testerHostname, int port, String suite, byte[] config) { - URI testerUri = createURI(testerHostname, port, "/tester/v1/run/" + suite); + URI testerUri = testerUrl(testerHostname, port, "tester", "v1", "run", suite).asURI(); HttpPost request = new HttpPost(testerUri); request.setEntity(new ByteArrayEntity(config, ContentType.DEFAULT_BINARY)); - return execute(request, "Failed to start tests"); } public HttpResponse isTesterReady(String testerHostname, int port) { - URI testerUri = createURI(testerHostname, port, "/status.html"); - + URI testerUri = testerUrl(testerHostname, port, "status.html").asURI(); return execute(new HttpGet(testerUri), "/status.html did not return 200 OK"); } public HttpResponse getReport(String testerHostname, int port) { - URI testerUri = createURI(testerHostname, port, "/tester/v1/report"); + URI testerUri = testerUrl(testerHostname, port, "tester", "v1", "report").asURI(); return execute(new HttpGet(testerUri), "Failed to get test report"); } @@ -75,20 +71,8 @@ public class TesterClient { } } - private URIBuilder createBuilder(String testerHostname, int port, String path) { - return new URIBuilder() - .setScheme("https") - .setHost(testerHostname) - .setPort(port) - .setPath(path); - } - - private URI createURI(String testerHostname, int port, String path) { - try { - return createBuilder(testerHostname, port, path).build(); - } catch (URISyntaxException e) { - throw new IllegalArgumentException(e); - } + private HttpURL testerUrl(String testerHostname, int port, String... path) { + return HttpURL.create(Scheme.https, DomainName.of(testerHostname), port, Path.empty().append(List.of(path))); } } 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 13914227971..aebf6df5a07 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 @@ -31,11 +31,13 @@ import com.yahoo.slime.Slime; import com.yahoo.slime.SlimeUtils; import com.yahoo.text.StringUtilities; import com.yahoo.vespa.config.server.ApplicationRepository; +import com.yahoo.vespa.config.server.ApplicationRepository.TesterSuspendedException; import com.yahoo.vespa.config.server.application.ApplicationReindexing; import com.yahoo.vespa.config.server.application.ClusterReindexing; import com.yahoo.vespa.config.server.application.ConfigConvergenceChecker; 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; @@ -231,13 +233,18 @@ public class ApplicationHandler extends HttpHandler { } private HttpResponse testerRequest(ApplicationId applicationId, String command, HttpRequest request) { - return switch (command) { - case "status" -> applicationRepository.getTesterStatus(applicationId); - case "log" -> applicationRepository.getTesterLog(applicationId, Long.valueOf(request.getProperty("after"))); - case "ready" -> applicationRepository.isTesterReady(applicationId); - case "report" -> applicationRepository.getTestReport(applicationId); - default -> throw new IllegalArgumentException("Unknown tester command in request " + request.getUri().toString()); - }; + try { + return switch (command) { + case "status" -> applicationRepository.getTesterStatus(applicationId); + case "log" -> applicationRepository.getTesterLog(applicationId, Long.valueOf(request.getProperty("after"))); + case "ready" -> applicationRepository.isTesterReady(applicationId); + case "report" -> applicationRepository.getTestReport(applicationId); + default -> throw new IllegalArgumentException("Unknown tester command in request " + request.getUri().toString()); + }; + } + catch (TesterSuspendedException e) { + return HttpErrorResponse.testerSuspended(e.getMessage()); + } } private HttpResponse quotaUsage(ApplicationId applicationId) { |