summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configserver-client/pom.xml8
-rw-r--r--configserver-client/src/main/java/ai/vespa/hosted/client/AbstractConfigServerClient.java83
-rw-r--r--configserver-client/src/main/java/ai/vespa/hosted/client/ConfigServerClient.java19
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java4
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java5
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java2
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java4
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java28
8 files changed, 75 insertions, 78 deletions
diff --git a/configserver-client/pom.xml b/configserver-client/pom.xml
index cee6f6c067f..0a29ba003f4 100644
--- a/configserver-client/pom.xml
+++ b/configserver-client/pom.xml
@@ -55,13 +55,7 @@
<dependency>
<groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter-engine</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>com.yahoo.vespa</groupId>
- <artifactId>testutil</artifactId>
- <version>${project.version}</version>
+ <artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
diff --git a/configserver-client/src/main/java/ai/vespa/hosted/client/AbstractConfigServerClient.java b/configserver-client/src/main/java/ai/vespa/hosted/client/AbstractConfigServerClient.java
index 0ee9e320259..e11f0db7194 100644
--- a/configserver-client/src/main/java/ai/vespa/hosted/client/AbstractConfigServerClient.java
+++ b/configserver-client/src/main/java/ai/vespa/hosted/client/AbstractConfigServerClient.java
@@ -52,7 +52,7 @@ public abstract class AbstractConfigServerClient implements ConfigServerClient {
protected abstract ClassicHttpResponse execute(ClassicHttpRequest request, HttpClientContext context) throws IOException;
/** Executes the given request with response/error handling and retries. */
- private <T> T execute(RequestBuilder builder, BiFunction<ClassicHttpResponse, IOException, T> handler) {
+ private <T> T execute(RequestBuilder builder, Function<ClassicHttpResponse, T> handler, Function<IOException, T> catcher) {
HttpClientContext context = HttpClientContext.create();
context.setRequestConfig(builder.config);
@@ -62,10 +62,10 @@ public abstract class AbstractConfigServerClient implements ConfigServerClient {
request.setEntity(builder.entity);
try {
try {
- return handler.apply(execute(request, context), null);
+ return handler.apply(execute(request, context));
}
catch (IOException e) {
- return handler.apply(null, e);
+ return catcher.apply(e);
}
}
catch (RetryException e) {
@@ -133,7 +133,7 @@ public abstract class AbstractConfigServerClient implements ConfigServerClient {
}
@Override
- public RequestBuilder at(String... pathSegments) {
+ public RequestBuilder at(List<String> pathSegments) {
uriBuilder.setPathSegments(requireNonNull(pathSegments));
return this;
}
@@ -150,19 +150,19 @@ public abstract class AbstractConfigServerClient implements ConfigServerClient {
}
@Override
- public RequestBuilder parameters(String... pairs) {
- if (pairs.length % 2 != 0)
+ public RequestBuilder parameters(List<String> pairs) {
+ if (pairs.size() % 2 != 0)
throw new IllegalArgumentException("Must supply parameter key/values in pairs");
- for (int i = 0; i < pairs.length; )
- uriBuilder.setParameter(pairs[i++], pairs[i++]);
+ for (int i = 0; i < pairs.size(); )
+ uriBuilder.setParameter(pairs.get(i++), pairs.get(i++));
return this;
}
@Override
public RequestBuilder timeout(Duration timeout) {
- return config(RequestConfig.copy(defaultRequestConfig)
+ return config(RequestConfig.copy(config)
.setResponseTimeout(timeout.toMillis(), TimeUnit.MILLISECONDS)
.build());
}
@@ -175,8 +175,8 @@ public abstract class AbstractConfigServerClient implements ConfigServerClient {
}
@Override
- public <T> T handle(BiFunction<ClassicHttpResponse, IOException, T> handler) throws UncheckedIOException {
- return execute(this, requireNonNull(handler));
+ public <T> T handle(Function<ClassicHttpResponse, T> handler, Function<IOException, T> catcher) throws UncheckedIOException {
+ return execute(this, requireNonNull(handler), requireNonNull(catcher));
}
@Override
@@ -210,37 +210,38 @@ public abstract class AbstractConfigServerClient implements ConfigServerClient {
/** Returns the mapped body, if successful, retrying any IOException. The caller must close the body stream. */
private <T> T mapIfSuccess(Function<InputStream, T> mapper) {
- return handle((response, ioException) -> {
- if (response != null) {
- try {
- InputStream body = response.getEntity() != null ? response.getEntity().getContent()
- : InputStream.nullInputStream();
- if (response.getCode() >= HttpStatus.SC_REDIRECTION)
- throw readException(body.readAllBytes());
-
- return mapper.apply(new ForwardingInputStream(body) {
- @Override
- public void close() throws IOException {
- super.close();
- response.close();
+ return handle(response -> {
+ try {
+ InputStream body = response.getEntity() != null ? response.getEntity().getContent()
+ : InputStream.nullInputStream();
+ if (response.getCode() >= HttpStatus.SC_REDIRECTION)
+ throw readException(body.readAllBytes());
+
+ return mapper.apply(new ForwardingInputStream(body) {
+ @Override
+ public void close() throws IOException {
+ super.close();
+ response.close();
+ }
+ });
}
- });
- }
- catch (IOException | RuntimeException | Error e) {
- try {
- response.close();
- }
- catch (IOException f) {
- e.addSuppressed(f);
- }
- if (e instanceof IOException)
- ioException = (IOException) e;
- else
- sneakyThrow(e);
- }
- }
- throw new RetryException(ioException);
- });
+ catch (IOException | RuntimeException | Error e) {
+ try {
+ response.close();
+ }
+ catch (IOException f) {
+ e.addSuppressed(f);
+ }
+ if (e instanceof IOException)
+ throw new RetryException((IOException) e);
+ else
+ sneakyThrow(e);
+ throw new AssertionError("Should not happen");
+ }
+ },
+ ioException -> {
+ throw new RetryException(ioException);
+ });
}
}
diff --git a/configserver-client/src/main/java/ai/vespa/hosted/client/ConfigServerClient.java b/configserver-client/src/main/java/ai/vespa/hosted/client/ConfigServerClient.java
index 234dbe9ee06..61b7edea0cc 100644
--- a/configserver-client/src/main/java/ai/vespa/hosted/client/ConfigServerClient.java
+++ b/configserver-client/src/main/java/ai/vespa/hosted/client/ConfigServerClient.java
@@ -12,6 +12,7 @@ import java.io.UncheckedIOException;
import java.net.URI;
import java.time.Duration;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.BiFunction;
@@ -33,7 +34,10 @@ public interface ConfigServerClient extends AutoCloseable {
interface RequestBuilder {
/** Sets the request path. */
- RequestBuilder at(String... pathSegments);
+ default RequestBuilder at(String... pathSegments) { return at(List.of(pathSegments)); }
+
+ /** Sets the request path. */
+ RequestBuilder at(List<String> pathSegments);
/** Sets the request body as UTF-8 application/json. */
RequestBuilder body(byte[] json);
@@ -42,24 +46,29 @@ public interface ConfigServerClient extends AutoCloseable {
RequestBuilder body(HttpEntity entity);
/** Sets the parameter key/values for the request. Number of arguments must be even. */
- RequestBuilder parameters(String... pairs);
+ default RequestBuilder parameters(String... pairs) {
+ return parameters(Arrays.asList(pairs));
+ }
+
+ /** Sets the parameter key/values for the request. Number of arguments must be even. */
+ RequestBuilder parameters(List<String> pairs);
/** Overrides the default socket read timeout of the request. {@code Duration.ZERO} gives infinite timeout. */
RequestBuilder timeout(Duration timeout);
- /** Overrides the default socket read timeout of the request. {@code null} allows infinite timeout. */
+ /** Overrides the default request config of the request. */
RequestBuilder config(RequestConfig config);
/**
* Sets custom retry/failure logic for this.
* <p>
- * Exactly one of the arguments (response, exception) are non-null.
+ * Exactly one of the callbacks will be invoked, with a non-null argument.
* Return a value to have that returned to the caller;
* throw a {@link RetryException} to have the request retried; or
* throw any other unchecked exception to have this propagate out to the caller.
* The caller must close the provided response, if any.
*/
- <T> T handle(BiFunction<ClassicHttpResponse, IOException, T> handler) throws UncheckedIOException;
+ <T> T handle(Function<ClassicHttpResponse, T> handler, Function<IOException, T> catcher) throws UncheckedIOException;
/** Sets the response body mapper for this, for successful requests. */
<T> T read(Function<byte[], T> mapper) throws UncheckedIOException, ConfigServerException;
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 ed545dc35d1..81c4d7be483 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
@@ -39,7 +39,7 @@ public interface ConfigServer {
void reindex(DeploymentId deployment, List<String> clusterNames, List<String> documentTypes, boolean indexedOnly);
- Optional<ApplicationReindexing> getReindexing(DeploymentId deployment);
+ ApplicationReindexing getReindexing(DeploymentId deployment);
void disableReindexing(DeploymentId deployment);
@@ -47,7 +47,7 @@ public interface ConfigServer {
void restart(DeploymentId deployment, RestartFilter restartFilter);
- void deactivate(DeploymentId deployment) throws NotFoundException;
+ void deactivate(DeploymentId deployment);
boolean isSuspended(DeploymentId deployment);
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java
index 69d723edbe8..c85d23d58d1 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java
@@ -183,8 +183,7 @@ public class ApplicationController {
/** Returns the reindexing status for the given application in the given zone. */
public ApplicationReindexing applicationReindexing(ApplicationId id, ZoneId zoneId) {
- return configServer.getReindexing(new DeploymentId(id, zoneId))
- .orElseThrow(() -> new NotExistsException("Reindexing status not found for " + id + " in " + zoneId));
+ return configServer.getReindexing(new DeploymentId(id, zoneId));
}
/** Enables reindexing for the given application in the given zone. */
@@ -678,8 +677,6 @@ public class ApplicationController {
DeploymentId id = new DeploymentId(application.get().id().instance(instanceName), zone);
try {
configServer.deactivate(id);
- } catch (NotFoundException ignored) {
- // ok; already gone
} finally {
controller.routing().policies().refresh(application.get().id().instance(instanceName), application.get().deploymentSpec(), zone);
if (zone.environment().isManuallyDeployed())
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java
index 65d3f666309..3dc88d5d6d2 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java
@@ -532,8 +532,6 @@ public class JobController {
var zone = type.zone(controller.system());
try {
controller.serviceRegistry().configServer().deactivate(new DeploymentId(id.id(), zone));
- } catch (NotFoundException ignored) {
- // Already gone -- great!
} finally {
// Passing an empty DeploymentSpec here is fine as it's used for registering global endpoint names, and
// tester instances have none.
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 ffb5e040517..78dab2cceb6 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
@@ -203,11 +203,11 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
catch (ConfigServerException e) {
switch (e.getErrorCode()) {
case NOT_FOUND:
- return new ErrorResponse(NOT_FOUND, e.getErrorCode().name(), Exceptions.toMessageString(e));
+ return ErrorResponse.notFoundError(Exceptions.toMessageString(e));
case ACTIVATION_CONFLICT:
return new ErrorResponse(CONFLICT, e.getErrorCode().name(), Exceptions.toMessageString(e));
case INTERNAL_SERVER_ERROR:
- return new ErrorResponse(INTERNAL_SERVER_ERROR, e.getErrorCode().name(), Exceptions.toMessageString(e));
+ return ErrorResponse.internalServerError(Exceptions.toMessageString(e));
default:
return new ErrorResponse(BAD_REQUEST, e.getErrorCode().name(), Exceptions.toMessageString(e));
}
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 70651ada473..ca52e31d04c 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
@@ -432,21 +432,18 @@ public class ConfigServerMock extends AbstractComponent implements ConfigServer
public void reindex(DeploymentId deployment, List<String> clusterNames, List<String> documentTypes, boolean indexedOnly) { }
@Override
- public Optional<ApplicationReindexing> getReindexing(DeploymentId deployment) {
- return Optional.of(new ApplicationReindexing(true,
- Map.of("cluster",
- new ApplicationReindexing.Cluster(Map.of("type", 100L),
- Map.of("type", new Status(Instant.ofEpochMilli(345),
- Instant.ofEpochMilli(456),
- Instant.ofEpochMilli(567),
- ApplicationReindexing.State.FAILED,
- "(#`д´)ノ",
- 0.1))))));
-
-
+ public ApplicationReindexing getReindexing(DeploymentId deployment) {
+ return new ApplicationReindexing(true,
+ Map.of("cluster",
+ new ApplicationReindexing.Cluster(Map.of("type", 100L),
+ Map.of("type", new Status(Instant.ofEpochMilli(345),
+ Instant.ofEpochMilli(456),
+ Instant.ofEpochMilli(567),
+ ApplicationReindexing.State.FAILED,
+ "(#`д´)ノ",
+ 0.1)))));
}
-
@Override
public void disableReindexing(DeploymentId deployment) { }
@@ -464,12 +461,13 @@ public class ConfigServerMock extends AbstractComponent implements ConfigServer
}
@Override
- public void deactivate(DeploymentId deployment) throws NotFoundException {
+ public void deactivate(DeploymentId deployment) {
ApplicationId applicationId = deployment.applicationId();
nodeRepository().removeNodes(deployment.zoneId(),
nodeRepository().list(deployment.zoneId(), applicationId));
if ( ! applications.containsKey(deployment))
- throw new NotFoundException("No application with id " + applicationId + " exists, cannot deactivate");
+ return;
+
applications.remove(deployment);
serviceStatus.remove(deployment);
removeLoadBalancers(deployment.applicationId(), deployment.zoneId());