aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java13
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/HttpErrorResponse.java5
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/TesterClient.java44
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java21
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) {