aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Marius Venstad <venstad@gmail.com>2021-01-11 09:13:54 +0100
committerJon Marius Venstad <venstad@gmail.com>2021-01-11 09:13:54 +0100
commit65d8b3d6e2a3a95a495e9b3096660e15581d1bed (patch)
tree7723978d8ec06f6f8237e0da901f88bb289b5487
parent00d005ea8544ee5677c2f18d5358cf65afebbf32 (diff)
Add suspension mojo
-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/restapi/application/ApplicationApiHandler.java10
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTest.java2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java4
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerMock.java3
-rw-r--r--docproc/src/test/java/com/yahoo/docproc/util/SplitterJoinerTestCase.java2
-rw-r--r--hosted-api/src/main/java/ai/vespa/hosted/api/ControllerHttpClient.java11
-rw-r--r--orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/ApplicationSuspensionApi.java1
-rw-r--r--orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/ApplicationSuspensionResourceTest.java2
-rw-r--r--orchestrator/src/test/java/com/yahoo/vespa/orchestrator/status/ZkStatusServiceTest.java1
11 files changed, 40 insertions, 5 deletions
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 0c9a415beab..11940b30ac1 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
@@ -144,4 +144,8 @@ public interface ConfigServer {
/** Get maximum resources consumed */
QuotaUsage getQuotaUsage(DeploymentId deploymentId);
+
+ /** Sets suspension status — whether application node operations are orchestrated — for the given deployment. */
+ void setSuspension(DeploymentId deploymentId, boolean suspend);
+
}
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 832668bf9f7..e071221dd05 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
@@ -985,4 +985,9 @@ public class ApplicationController {
return Map.copyOf(warnings);
}
+ /** Sets suspension status of the given deployment in its zone. */
+ public void setSuspension(DeploymentId deploymentId, boolean suspend) {
+ configServer.setSuspension(deploymentId, suspend);
+ }
+
}
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 0dff1600751..67490bf9d8c 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
@@ -292,6 +292,7 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/environment/{environment}/region/{region}/reindex")) return reindex(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), request);
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/environment/{environment}/region/{region}/reindexing")) return enableReindexing(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), request);
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/environment/{environment}/region/{region}/restart")) return restart(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), request);
+ if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/environment/{environment}/region/{region}/suspend")) return suspend(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), true);
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/environment/{environment}/region/{region}/instance/{instance}")) return deploy(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), request);
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/environment/{environment}/region/{region}/instance/{instance}/deploy")) return deploy(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), request); // legacy synonym of the above
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/environment/{environment}/region/{region}/instance/{instance}/restart")) return restart(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), request);
@@ -319,6 +320,7 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/job/{jobtype}/pause")) return resume(appIdFromPath(path), jobTypeFromPath(path));
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/environment/{environment}/region/{region}")) return deactivate(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), request);
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/environment/{environment}/region/{region}/reindexing")) return disableReindexing(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), request);
+ if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/environment/{environment}/region/{region}/suspend")) return suspend(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), false);
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/environment/{environment}/region/{region}/global-rotation/override")) return setGlobalRotationOverride(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), true, request);
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/environment/{environment}/region/{region}/instance/{instance}")) return deactivate(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), request);
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/environment/{environment}/region/{region}/instance/{instance}/global-rotation/override")) return setGlobalRotationOverride(path.get("tenant"), path.get("application"), path.get("instance"), path.get("environment"), path.get("region"), true, request);
@@ -1651,6 +1653,14 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
return new MessageResponse("Requested restart of " + deploymentId);
}
+ /** Set suspension status of the given deployment. */
+ private HttpResponse suspend(String tenantName, String applicationName, String instanceName, String environment, String region, boolean suspend) {
+ DeploymentId deploymentId = new DeploymentId(ApplicationId.from(tenantName, applicationName, instanceName),
+ requireZone(environment, region));
+ controller.applications().setSuspension(deploymentId, suspend);
+ return new MessageResponse((suspend ? "Suspended" : "Resumed") + " orchestration of " + deploymentId);
+ }
+
private HttpResponse jobDeploy(ApplicationId id, JobType type, HttpRequest request) {
if ( ! type.environment().isManuallyDeployed() && ! isOperator(request))
throw new IllegalArgumentException("Direct deployments are only allowed to manually deployed environments.");
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTest.java
index 569c22d8bf6..8fcbb365804 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTest.java
@@ -667,7 +667,7 @@ public class ControllerTest {
DeploymentId deployment2 = context.deploymentIdIn(ZoneId.from(Environment.prod, RegionName.from("us-east-3")));
assertFalse(tester.configServer().isSuspended(deployment1));
assertFalse(tester.configServer().isSuspended(deployment2));
- tester.configServer().setSuspended(deployment1, true);
+ tester.configServer().setSuspension(deployment1, true);
assertTrue(tester.configServer().isSuspended(deployment1));
assertFalse(tester.configServer().isSuspended(deployment2));
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java
index 9b1eff60831..724ba61da2b 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java
@@ -253,7 +253,7 @@ public class DeploymentTriggerTest {
var application = tester.newDeploymentContext().submit().deploy();
// The first production zone is suspended:
- tester.configServer().setSuspended(application.deploymentIdIn(ZoneId.from("prod", "us-central-1")), true);
+ tester.configServer().setSuspension(application.deploymentIdIn(ZoneId.from("prod", "us-central-1")), true);
// A new change needs to be pushed out, but should not go beyond the suspended zone:
application.submit()
@@ -265,7 +265,7 @@ public class DeploymentTriggerTest {
application.assertNotRunning(productionUsWest1);
// The zone is unsuspended so jobs start:
- tester.configServer().setSuspended(application.deploymentIdIn(ZoneId.from("prod", "us-central-1")), false);
+ tester.configServer().setSuspension(application.deploymentIdIn(ZoneId.from("prod", "us-central-1")), false);
tester.triggerJobs();
application.runJob(productionUsWest1).runJob(productionUsEast3);
assertEquals(Change.empty(), application.instance().change());
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 ab31b7e21fe..7753570b72d 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
@@ -244,7 +244,8 @@ public class ConfigServerMock extends AbstractComponent implements ConfigServer
return Optional.ofNullable(applications.get(new DeploymentId(id, zone)));
}
- public void setSuspended(DeploymentId deployment, boolean suspend) {
+ @Override
+ public void setSuspension(DeploymentId deployment, boolean suspend) {
if (suspend)
suspendedApplications.add(deployment);
else
diff --git a/docproc/src/test/java/com/yahoo/docproc/util/SplitterJoinerTestCase.java b/docproc/src/test/java/com/yahoo/docproc/util/SplitterJoinerTestCase.java
index aa55d5b6a41..6c8c485aacb 100644
--- a/docproc/src/test/java/com/yahoo/docproc/util/SplitterJoinerTestCase.java
+++ b/docproc/src/test/java/com/yahoo/docproc/util/SplitterJoinerTestCase.java
@@ -18,7 +18,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
- * @author <a href="mailto:einarmr@yahoo-inc.com">Einar M R Rosenvinge</a>
+ * @author Einar M R Rosenvinge
*/
@SuppressWarnings({"unchecked"})
public class SplitterJoinerTestCase {
diff --git a/hosted-api/src/main/java/ai/vespa/hosted/api/ControllerHttpClient.java b/hosted-api/src/main/java/ai/vespa/hosted/api/ControllerHttpClient.java
index 3a848b33c76..f17816f224d 100644
--- a/hosted-api/src/main/java/ai/vespa/hosted/api/ControllerHttpClient.java
+++ b/hosted-api/src/main/java/ai/vespa/hosted/api/ControllerHttpClient.java
@@ -121,6 +121,13 @@ public abstract class ControllerHttpClient {
DELETE)));
}
+ /** Sets suspension status of the given application in the given zone. */
+ public String suspend(ApplicationId id, ZoneId zone, boolean suspend) {
+ return toMessage(send(request(HttpRequest.newBuilder(suspendPath(id, zone))
+ .timeout(Duration.ofSeconds(10)),
+ suspend ? POST : DELETE)));
+ }
+
/** Returns the default {@link ZoneId} for the given environment, if any. */
public ZoneId defaultZone(Environment environment) {
Inspector rootObject = toInspector(send(request(HttpRequest.newBuilder(defaultRegionPath(environment))
@@ -225,6 +232,10 @@ public abstract class ControllerHttpClient {
"region", zone.region().value());
}
+ private URI suspendPath(ApplicationId id, ZoneId zone) {
+ return concatenated(deploymentPath(id, zone), "suspend");
+ }
+
private URI deploymentJobPath(ApplicationId id, ZoneId zone) {
return concatenated(instancePath(id),
"deploy", jobNameOf(zone));
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
index 1c597a73d01..e44f6fa0df7 100644
--- 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
@@ -18,6 +18,7 @@ import java.util.Set;
*
* @author smorgrav
*/
+@Path("/orchestrator" + ApplicationSuspensionApi.PATH_PREFIX)
public interface ApplicationSuspensionApi {
/**
* Path prefix for this api. Resources implementing this API should use this with a @Path annotation.
diff --git a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/ApplicationSuspensionResourceTest.java b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/ApplicationSuspensionResourceTest.java
index 4035e29d91a..770cb7f35d2 100644
--- a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/ApplicationSuspensionResourceTest.java
+++ b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/ApplicationSuspensionResourceTest.java
@@ -91,6 +91,7 @@ public class ApplicationSuspensionResourceTest {
@Test
public void delete_works_on_suspended_and_not_suspended_applications() {
// Delete an application that is not suspended
+ var v = webTarget.path(RESOURCE_1).request();
Response reply = webTarget.path(RESOURCE_1).request().delete();
assertEquals(204, reply.getStatus());
@@ -114,6 +115,7 @@ public class ApplicationSuspensionResourceTest {
@Test
public void list_applications_returns_the_correct_list_of_suspended_applications() {
// Test that initially we have the empty set
+ var v = webTarget.request(MediaType.APPLICATION_JSON);
Response reply = webTarget.request(MediaType.APPLICATION_JSON).get();
assertEquals(200, reply.getStatus());
assertEquals("[]", reply.readEntity(String.class));
diff --git a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/status/ZkStatusServiceTest.java b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/status/ZkStatusServiceTest.java
index 230290a632a..9a79828bc7b 100644
--- a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/status/ZkStatusServiceTest.java
+++ b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/status/ZkStatusServiceTest.java
@@ -225,6 +225,7 @@ public class ZkStatusServiceTest {
};
}
+ @SuppressWarnings("deprecation")
private static void killSession(CuratorFramework curatorFramework, TestingServer testingServer) {
try {
KillSession.kill(curatorFramework.getZookeeperClient().getZooKeeper(), testingServer.getConnectString());