summaryrefslogtreecommitdiffstats
path: root/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/HostSuspensionHandler.java
diff options
context:
space:
mode:
Diffstat (limited to 'orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/HostSuspensionHandler.java')
-rw-r--r--orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/HostSuspensionHandler.java81
1 files changed, 81 insertions, 0 deletions
diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/HostSuspensionHandler.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/HostSuspensionHandler.java
new file mode 100644
index 00000000000..ca720ec8b68
--- /dev/null
+++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/HostSuspensionHandler.java
@@ -0,0 +1,81 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.orchestrator.resources;
+
+import com.google.common.util.concurrent.UncheckedTimeoutException;
+import com.google.inject.Inject;
+import com.yahoo.container.jdisc.LoggingRequestHandler;
+import com.yahoo.jdisc.Response;
+import com.yahoo.restapi.JacksonJsonResponse;
+import com.yahoo.restapi.RestApi;
+import com.yahoo.restapi.RestApiException;
+import com.yahoo.restapi.RestApiRequestHandler;
+import com.yahoo.vespa.applicationmodel.HostName;
+import com.yahoo.vespa.orchestrator.BatchHostNameNotFoundException;
+import com.yahoo.vespa.orchestrator.BatchInternalErrorException;
+import com.yahoo.vespa.orchestrator.Orchestrator;
+import com.yahoo.vespa.orchestrator.policy.BatchHostStateChangeDeniedException;
+import com.yahoo.vespa.orchestrator.restapi.wire.BatchOperationResult;
+
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+/**
+ * @author hakonhall
+ * @author bjorncs
+ */
+public class HostSuspensionHandler extends RestApiRequestHandler<HostSuspensionHandler> {
+
+ private static final Logger log = Logger.getLogger(HostSuspensionHandler.class.getName());
+
+ private final Orchestrator orchestrator;
+
+ @Inject
+ public HostSuspensionHandler(LoggingRequestHandler.Context context, Orchestrator orchestrator) {
+ super(context, HostSuspensionHandler::createRestApiDefinition);
+ this.orchestrator = orchestrator;
+ }
+
+ private static RestApi createRestApiDefinition(HostSuspensionHandler self) {
+ return RestApi.builder()
+ .addRoute(RestApi.route("/orchestrator/v1/suspensions/hosts/{hostname}")
+ .put(self::suspendAll))
+ .registerJacksonResponseEntity(BatchOperationResult.class)
+ .build();
+ }
+
+ private BatchOperationResult suspendAll(RestApi.RequestContext context) {
+ String parentHostnameString = context.pathParameters().getStringOrThrow("hostname");
+ List<String> hostnamesAsStrings = context.queryParameters().getStringList("hostname");
+
+ HostName parentHostname = new HostName(parentHostnameString);
+ List<HostName> hostnames = hostnamesAsStrings.stream().map(HostName::new).collect(Collectors.toList());
+ try {
+ orchestrator.suspendAll(parentHostname, hostnames);
+ } catch (BatchHostStateChangeDeniedException e) {
+ log.log(Level.FINE, "Failed to suspend nodes " + hostnames + " with parent host " + parentHostname, e);
+ throw createRestApiException(e.getMessage(), Response.Status.CONFLICT, e);
+ } catch (UncheckedTimeoutException e) {
+ log.log(Level.FINE, "Failed to suspend nodes " + hostnames + " with parent host " + parentHostname, e);
+ throw createRestApiException(e.getMessage(), Response.Status.CONFLICT, e);
+ } catch (BatchHostNameNotFoundException e) {
+ log.log(Level.FINE, "Failed to suspend nodes " + hostnames + " with parent host " + parentHostname, e);
+ // Note that we're returning BAD_REQUEST instead of NOT_FOUND because the resource identified
+ // by the URL path was found. It's one of the hostnames in the request it failed to find.
+ throw createRestApiException(e.getMessage(), Response.Status.BAD_REQUEST, e);
+ } catch (BatchInternalErrorException e) {
+ log.log(Level.FINE, "Failed to suspend nodes " + hostnames + " with parent host " + parentHostname, e);
+ throw createRestApiException(e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ log.log(Level.FINE, "Suspended " + hostnames + " with parent " + parentHostname);
+ return BatchOperationResult.successResult();
+ }
+
+ private RestApiException createRestApiException(String errorMessage, int statusCode, Throwable cause) {
+ return new RestApiException(
+ new JacksonJsonResponse<>(statusCode, new BatchOperationResult(errorMessage), true),
+ errorMessage,
+ cause);
+ }
+}