aboutsummaryrefslogtreecommitdiffstats
path: root/orchestrator-restapi/src/main/java/com/yahoo
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
commit72231250ed81e10d66bfe70701e64fa5fe50f712 (patch)
tree2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /orchestrator-restapi/src/main/java/com/yahoo
Publish
Diffstat (limited to 'orchestrator-restapi/src/main/java/com/yahoo')
-rw-r--r--orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/ApplicationSuspensionApi.java90
-rw-r--r--orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/HostApi.java69
-rw-r--r--orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/HostSuspensionApi.java31
-rw-r--r--orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/BatchHostSuspendRequest.java48
-rw-r--r--orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/BatchOperationResult.java33
-rw-r--r--orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/GetHostResponse.java55
-rw-r--r--orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/HostStateChangeDenialReason.java66
-rw-r--r--orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/UpdateHostResponse.java56
8 files changed, 448 insertions, 0 deletions
diff --git a/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/ApplicationSuspensionApi.java b/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/ApplicationSuspensionApi.java
new file mode 100644
index 00000000000..e40e06062c2
--- /dev/null
+++ b/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/ApplicationSuspensionApi.java
@@ -0,0 +1,90 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.orchestrator.restapi;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import java.util.Set;
+
+/**
+ * Definition of Orchestrator's REST API for suspensions of applications aka application instances.
+ *
+ * Implementing classes must not put any JAX-RS annotation on the overridden methods. Doing so will cause all
+ * method annotations in this interface to be ignored by the JAX-RS container (see section 3.6 of JSR-339).
+ *
+ * @author <a href="mailto:smorgrav@yahoo-inc.com">Toby</a>
+ */
+public interface ApplicationSuspensionApi {
+ /**
+ * Path prefix for this api. Resources implementing this API should use this with a @Path annotation.
+ */
+ String PATH_PREFIX = "/v1/suspensions/applications";
+
+ /**
+ * Lists all applications that is currently suspended.
+ *
+ * HTTP Behavior:
+ * Always 200
+ *
+ * @return A list of application ids of suspended applications
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ Set<String> getApplications();
+
+ /**
+ * Shows the Orchestrator status for an application instance
+ *
+ * HTTP Behavior:
+ * 204 if the application is suspended
+ * 400 if the applicationId is invalid
+ * 404 if the application is not suspended
+ *
+ * @param applicationIdString the fully qualified application id.
+ */
+ @GET
+ @Path("/{application}")
+ @Produces(MediaType.APPLICATION_JSON)
+ void getApplication(@PathParam("application") String applicationIdString);
+
+ /**
+ * Ask for permission to temporarily suspend all services for an application instance.
+ *
+ * On success all content nodes for this application instance have been set in maintenance mode.
+ *
+ * Once the application is ready to resume normal operations, it must finish with resume() (see below).
+ *
+ * If the application has already been granted permission to suspend all services, requesting
+ * suspension again is idempotent and will succeed.
+ *
+ * HTTP Behavior:
+ * 204 is the suspend operation was successful
+ * 400 if the applicationId is invalid
+ * 409 if the suspend was denied
+ *
+ * @param applicationIdString the fully qualified application id.
+ */
+ @POST
+ void suspend(String applicationIdString);
+
+ /**
+ * Resume normal operations for all services for an application
+ * instance that has previously been allowed suspension.
+ *
+ * If the host is already registered as running normal operations, then resume() is idempotent
+ * and will succeed.
+ *
+ * HTTP Behavior:
+ * Returns 204 is the resume operation was successful (or the application was not suspended)
+ * Returns 400 if the applicationId is invalid
+ *
+ * @param applicationIdString the fully qualified application id.
+ */
+ @DELETE
+ @Path("/{application}")
+ void resume(@PathParam("application") String applicationIdString);
+}
diff --git a/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/HostApi.java b/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/HostApi.java
new file mode 100644
index 00000000000..bdcc4fe51d0
--- /dev/null
+++ b/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/HostApi.java
@@ -0,0 +1,69 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.orchestrator.restapi;
+
+import com.yahoo.vespa.orchestrator.restapi.wire.GetHostResponse;
+import com.yahoo.vespa.orchestrator.restapi.wire.UpdateHostResponse;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+/**
+ * Definition of Orchestrator's REST API for hosts.
+ *
+ * Implementing classes must not put any JAX-RS annotation on the overridden methods. Doing so will cause all
+ * method annotations in this interface to be ignored by the JAX-RS container (see section 3.6 of JSR-339).
+ *
+ * @author <a href="mailto:bakksjo@yahoo-inc.com">Oyvind Bakksjo</a>
+ */
+public interface HostApi {
+ /**
+ * Path prefix for this api. Resources implementing this API should use this with a @Path annotation.
+ */
+ String PATH_PREFIX = "/v1/hosts";
+
+ /**
+ * Shows the Orchestrator state of a host.
+ *
+ * @param hostNameString the fully qualified host name
+ */
+ @GET
+ @Path("/{hostname}")
+ @Produces(MediaType.APPLICATION_JSON)
+ GetHostResponse getHost(@PathParam("hostname") String hostNameString);
+
+ /**
+ * Ask for permission to temporarily suspend all services on a host.
+ *
+ * On success, none, some, or all services on the host may already have been effectively suspended,
+ * e.g. as of Feb 2015, a content node would already be set in the maintenance state.
+ *
+ * Once the host is ready to resume normal operations, it must finish with resume() (see below).
+ *
+ * If the host has already been granted permission to suspend all services, requesting
+ * suspension again is idempotent and will succeed.
+ *
+ * @param hostNameString the fully qualified host name.
+ */
+ @PUT
+ @Path("/{hostname}/suspended")
+ @Produces(MediaType.APPLICATION_JSON)
+ UpdateHostResponse suspend(@PathParam("hostname") String hostNameString);
+
+ /**
+ * Resume normal operations for all services on a host that has previously been allowed suspension.
+ *
+ * If the host is already registered as running normal operations, then resume() is idempotent
+ * and will succeed.
+ *
+ * @param hostNameString the fully qualified host name.
+ */
+ @DELETE
+ @Path("/{hostname}/suspended")
+ @Produces(MediaType.APPLICATION_JSON)
+ UpdateHostResponse resume(@PathParam("hostname") String hostNameString);
+}
diff --git a/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/HostSuspensionApi.java b/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/HostSuspensionApi.java
new file mode 100644
index 00000000000..3456e5ae3ae
--- /dev/null
+++ b/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/HostSuspensionApi.java
@@ -0,0 +1,31 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.orchestrator.restapi;
+
+import com.yahoo.vespa.orchestrator.restapi.wire.BatchHostSuspendRequest;
+import com.yahoo.vespa.orchestrator.restapi.wire.BatchOperationResult;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+public interface HostSuspensionApi {
+ /**
+ * Path prefix for this api. Resources implementing this API should use this with a @Path annotation.
+ */
+ String PATH_PREFIX = "/v1/suspensions/hosts";
+
+ /**
+ * Ask for permission to temporarily suspend all services on a set of hosts.
+ *
+ * See HostApi::suspend for semantics of suspending a host.
+ *
+ * On failure, it tries to resume ALL hosts. It needs to try to resume all hosts because any or all hosts
+ * may have been suspended in an earlier attempt. Ending with resumption of all hosts makes sure other
+ * batch-requests for suspension of hosts succeed.
+ */
+ @PUT
+ @Produces(MediaType.APPLICATION_JSON)
+ @Consumes(MediaType.APPLICATION_JSON)
+ BatchOperationResult suspendAll(BatchHostSuspendRequest request);
+}
diff --git a/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/BatchHostSuspendRequest.java b/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/BatchHostSuspendRequest.java
new file mode 100644
index 00000000000..eca9e10f3b7
--- /dev/null
+++ b/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/BatchHostSuspendRequest.java
@@ -0,0 +1,48 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.orchestrator.restapi.wire;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import javax.annotation.concurrent.Immutable;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+@Immutable
+public class BatchHostSuspendRequest {
+ public static final String PARENT_HOSTNAME_FIELD = "parentHostname";
+ public static final String HOSTNAMES_FIELD = "hostnames";
+
+ public final Optional<String> parentHostname;
+ public final Optional<List<String>> hostnames;
+
+ @JsonCreator
+ public BatchHostSuspendRequest(
+ @JsonProperty(PARENT_HOSTNAME_FIELD) String parentHostname,
+ @JsonProperty(HOSTNAMES_FIELD) List<String> hostnames) {
+ this.parentHostname = Optional.ofNullable(parentHostname);
+ this.hostnames = Optional.ofNullable(hostnames).map(Collections::unmodifiableList);
+ }
+
+ /**
+ * @return The hostname of the parent of the hostnames, if applicable, which can be used for debugging.
+ */
+ @JsonProperty(PARENT_HOSTNAME_FIELD)
+ public Optional<String> getParentHostname() {
+ return parentHostname;
+ }
+
+ @JsonProperty(HOSTNAMES_FIELD)
+ public Optional<List<String>> getHostnames() {
+ return hostnames;
+ }
+
+ @Override
+ public String toString() {
+ return "BatchHostSuspendRequest{" +
+ "parentHostname=" + parentHostname +
+ ", hostnames=" + hostnames +
+ '}';
+ }
+}
diff --git a/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/BatchOperationResult.java b/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/BatchOperationResult.java
new file mode 100644
index 00000000000..b4689247cc3
--- /dev/null
+++ b/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/BatchOperationResult.java
@@ -0,0 +1,33 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.orchestrator.restapi.wire;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.Optional;
+
+public class BatchOperationResult {
+ private static final String FAILURE_REASON = "failure-reason";
+
+ private final Optional<String> failureReason;
+ // private final List<String> suppressedFailures;
+
+ public static BatchOperationResult successResult() {
+ return new BatchOperationResult(null);
+ }
+
+ @JsonCreator
+ public BatchOperationResult(
+ @JsonProperty(FAILURE_REASON) String failureReason) {
+ this.failureReason = Optional.ofNullable(failureReason);
+ }
+
+ @JsonProperty(FAILURE_REASON)
+ public Optional<String> getFailureReason() {
+ return failureReason;
+ }
+
+ public boolean success() {
+ return !failureReason.isPresent();
+ }
+}
diff --git a/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/GetHostResponse.java b/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/GetHostResponse.java
new file mode 100644
index 00000000000..a3ff86423e0
--- /dev/null
+++ b/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/GetHostResponse.java
@@ -0,0 +1,55 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.orchestrator.restapi.wire;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.Objects;
+
+/*
+ * @author andreer
+ */
+public class GetHostResponse {
+
+ public static final String FIELD_NAME_HOSTNAME = "hostname";
+ public static final String FIELD_NAME_STATE = "state";
+
+ private final String hostname;
+ private final String state;
+
+ @JsonCreator
+ public GetHostResponse(
+ @JsonProperty(FIELD_NAME_HOSTNAME) final String hostname,
+ @JsonProperty(FIELD_NAME_STATE) final String state) {
+ this.hostname = hostname;
+ this.state = state;
+ }
+
+ @JsonProperty(FIELD_NAME_HOSTNAME)
+ public String hostname() {
+ return hostname;
+ }
+
+ @JsonProperty(FIELD_NAME_STATE)
+ public String state() {
+ return state;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (!(o instanceof GetHostResponse)) {
+ return false;
+ }
+
+ final GetHostResponse other = (GetHostResponse) o;
+ if (!Objects.equals(this.hostname, other.hostname)) return false;
+ if (!Objects.equals(this.state, other.state)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(hostname, state);
+ }
+}
diff --git a/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/HostStateChangeDenialReason.java b/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/HostStateChangeDenialReason.java
new file mode 100644
index 00000000000..37366e6efd3
--- /dev/null
+++ b/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/HostStateChangeDenialReason.java
@@ -0,0 +1,66 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.orchestrator.restapi.wire;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.Objects;
+
+/*
+ * A reason to reject a host state change request
+ * @author andreer
+ */
+public class HostStateChangeDenialReason {
+
+ public static final String FIELD_NAME_CONSTRAINT = "constraint";
+ public static final String FIELD_NAME_SERVICE_TYPE = "service-type";
+ public static final String FIELD_NAME_MESSAGE = "message";
+
+ private final String constraintName;
+ private final String serviceType;
+ private final String message;
+
+ @JsonCreator
+ public HostStateChangeDenialReason(
+ @JsonProperty(FIELD_NAME_CONSTRAINT) final String constraintName,
+ @JsonProperty(FIELD_NAME_SERVICE_TYPE) final String serviceType,
+ @JsonProperty(FIELD_NAME_MESSAGE) final String message) {
+ this.constraintName = constraintName;
+ this.serviceType = serviceType;
+ this.message = message;
+ }
+
+ @JsonProperty(FIELD_NAME_CONSTRAINT)
+ public String constraintName() {
+ return constraintName;
+ }
+
+ @JsonProperty(FIELD_NAME_SERVICE_TYPE)
+ public String serviceType() {
+ return serviceType;
+ }
+
+ @JsonProperty(FIELD_NAME_MESSAGE)
+ public String message() {
+ return message;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (!(o instanceof HostStateChangeDenialReason)) {
+ return false;
+ }
+
+ final HostStateChangeDenialReason other = (HostStateChangeDenialReason) o;
+ if (!Objects.equals(this.constraintName, other.constraintName)) return false;
+ if (!Objects.equals(this.serviceType, other.serviceType)) return false;
+ if (!Objects.equals(this.message, other.message)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(constraintName, serviceType, message);
+ }
+}
diff --git a/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/UpdateHostResponse.java b/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/UpdateHostResponse.java
new file mode 100644
index 00000000000..20921dec4de
--- /dev/null
+++ b/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/UpdateHostResponse.java
@@ -0,0 +1,56 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.orchestrator.restapi.wire;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import javax.annotation.Nullable;
+import java.util.Objects;
+
+/*
+ * @author andreer
+ */
+public class UpdateHostResponse {
+
+ public static final String FIELD_NAME_HOSTNAME = "hostname";
+ public static final String FIELD_NAME_REASON = "reason";
+
+ private final String hostname;
+ private final HostStateChangeDenialReason hostStateChangeDenialReason;
+
+ @JsonCreator
+ public UpdateHostResponse(
+ @JsonProperty(FIELD_NAME_HOSTNAME) final String hostname,
+ @JsonProperty(FIELD_NAME_REASON) @Nullable final HostStateChangeDenialReason hostStateChangeDenialReason) {
+ this.hostname = hostname;
+ this.hostStateChangeDenialReason = hostStateChangeDenialReason;
+ }
+
+ @JsonProperty(FIELD_NAME_HOSTNAME)
+ public String hostname() {
+ return hostname;
+ }
+
+ @JsonProperty(FIELD_NAME_REASON) @Nullable
+ public HostStateChangeDenialReason reason() {
+ return hostStateChangeDenialReason;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (!(o instanceof UpdateHostResponse)) {
+ return false;
+ }
+
+ final UpdateHostResponse other = (UpdateHostResponse) o;
+ if (!Objects.equals(this.hostname, other.hostname)) return false;
+ if (!Objects.equals(this.hostStateChangeDenialReason, other.hostStateChangeDenialReason)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(hostname, hostStateChangeDenialReason);
+ }
+}