diff options
author | Martin Polden <mpolden@mpolden.no> | 2018-09-21 15:02:25 +0200 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2018-09-24 10:34:13 +0200 |
commit | 718466ef345c30d80901b566f88d2b0d2a14cc42 (patch) | |
tree | 03b2336330d5424561057e02e68d2b45d1f1c898 /controller-server/src | |
parent | 53c7f12a5205b4828964370f4895b5bd1f82bbdb (diff) |
Use cached rotation status in application API
Diffstat (limited to 'controller-server/src')
7 files changed, 107 insertions, 100 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Controller.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Controller.java index 9f4b58f69b5..731ed718fc0 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Controller.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Controller.java @@ -24,14 +24,11 @@ import com.yahoo.vespa.hosted.controller.api.integration.dns.NameService; import com.yahoo.vespa.hosted.controller.api.integration.entity.EntityService; import com.yahoo.vespa.hosted.controller.api.integration.github.GitHub; import com.yahoo.vespa.hosted.controller.api.integration.organization.Organization; -import com.yahoo.vespa.hosted.controller.api.integration.routing.GlobalRoutingService; -import com.yahoo.vespa.hosted.controller.api.integration.routing.RotationStatus; import com.yahoo.vespa.hosted.controller.api.integration.routing.RoutingGenerator; import com.yahoo.vespa.hosted.controller.api.integration.zone.CloudName; import com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneRegistry; import com.yahoo.vespa.hosted.controller.deployment.JobController; import com.yahoo.vespa.hosted.controller.persistence.CuratorDb; -import com.yahoo.vespa.hosted.controller.rotation.Rotation; import com.yahoo.vespa.hosted.controller.versions.OsVersion; import com.yahoo.vespa.hosted.controller.versions.OsVersionStatus; import com.yahoo.vespa.hosted.controller.versions.VersionStatus; @@ -74,7 +71,6 @@ public class Controller extends AbstractComponent { private final Clock clock; private final GitHub gitHub; private final EntityService entityService; - private final GlobalRoutingService globalRoutingService; private final ZoneRegistry zoneRegistry; private final ConfigServer configServer; private final MetricsService metricsService; @@ -89,14 +85,13 @@ public class Controller extends AbstractComponent { @Inject public Controller(CuratorDb curator, RotationsConfig rotationsConfig, GitHub gitHub, EntityService entityService, Organization organization, - GlobalRoutingService globalRoutingService, ZoneRegistry zoneRegistry, ConfigServer configServer, MetricsService metricsService, NameService nameService, RoutingGenerator routingGenerator, Chef chef, AthenzClientFactory athenzClientFactory, ArtifactRepository artifactRepository, ApplicationStore applicationStore, TesterCloud testerCloud, BuildService buildService, RunDataStore runDataStore) { this(curator, rotationsConfig, - gitHub, entityService, globalRoutingService, zoneRegistry, + gitHub, entityService, zoneRegistry, configServer, metricsService, nameService, routingGenerator, chef, Clock.systemUTC(), athenzClientFactory, artifactRepository, applicationStore, testerCloud, buildService, runDataStore, com.yahoo.net.HostName::getLocalhost); @@ -104,7 +99,6 @@ public class Controller extends AbstractComponent { public Controller(CuratorDb curator, RotationsConfig rotationsConfig, GitHub gitHub, EntityService entityService, - GlobalRoutingService globalRoutingService, ZoneRegistry zoneRegistry, ConfigServer configServer, MetricsService metricsService, NameService nameService, RoutingGenerator routingGenerator, Chef chef, Clock clock, @@ -116,7 +110,6 @@ public class Controller extends AbstractComponent { this.curator = Objects.requireNonNull(curator, "Curator cannot be null"); this.gitHub = Objects.requireNonNull(gitHub, "GitHub cannot be null"); this.entityService = Objects.requireNonNull(entityService, "EntityService cannot be null"); - this.globalRoutingService = Objects.requireNonNull(globalRoutingService, "GlobalRoutingService cannot be null"); this.zoneRegistry = Objects.requireNonNull(zoneRegistry, "ZoneRegistry cannot be null"); this.configServer = Objects.requireNonNull(configServer, "ConfigServer cannot be null"); this.metricsService = Objects.requireNonNull(metricsService, "MetricsService cannot be null"); @@ -168,11 +161,6 @@ public class Controller extends AbstractComponent { public ZoneRegistry zoneRegistry() { return zoneRegistry; } - // TODO: Remove once DeploymentMetricsMaintainer has stored rotation status for all applications at least once - public Map<String, RotationStatus> rotationStatus(Rotation rotation) { - return globalRoutingService.getHealthStatus(rotation.name()); - } - public ApplicationView getApplicationView(String tenantName, String applicationName, String instanceName, String environment, String region) { return configServer.getApplicationView(tenantName, applicationName, instanceName, environment, region); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentMetricsMaintainer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentMetricsMaintainer.java index 6ea9d548367..1507cc8fedd 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentMetricsMaintainer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentMetricsMaintainer.java @@ -38,7 +38,7 @@ public class DeploymentMetricsMaintainer extends Maintainer { private final ApplicationController applications; - DeploymentMetricsMaintainer(Controller controller, Duration duration, JobControl jobControl) { + public DeploymentMetricsMaintainer(Controller controller, Duration duration, JobControl jobControl) { super(controller, duration, jobControl); this.applications = controller.applications(); } 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 154c4e632de..808bb2e716a 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 @@ -52,7 +52,6 @@ import com.yahoo.vespa.hosted.controller.api.integration.configserver.Log; import com.yahoo.vespa.hosted.controller.api.integration.configserver.Logs; import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType; import com.yahoo.vespa.hosted.controller.api.integration.deployment.RunId; -import com.yahoo.vespa.hosted.controller.api.integration.routing.RotationStatus; import com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneId; import com.yahoo.vespa.hosted.controller.application.ApplicationPackage; import com.yahoo.vespa.hosted.controller.application.ApplicationVersion; @@ -64,6 +63,7 @@ import com.yahoo.vespa.hosted.controller.application.DeploymentCost; import com.yahoo.vespa.hosted.controller.application.DeploymentJobs; import com.yahoo.vespa.hosted.controller.application.DeploymentMetrics; import com.yahoo.vespa.hosted.controller.application.JobStatus; +import com.yahoo.vespa.hosted.controller.application.RotationStatus; import com.yahoo.vespa.hosted.controller.application.SourceRevision; import com.yahoo.vespa.hosted.controller.restapi.ErrorResponse; import com.yahoo.vespa.hosted.controller.restapi.MessageResponse; @@ -89,7 +89,6 @@ import java.security.Principal; import java.time.DayOfWeek; import java.time.Duration; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -443,10 +442,9 @@ public class ApplicationApiHandler extends LoggingRequestHandler { deploymentObject.setString("environment", deployment.zone().environment().value()); deploymentObject.setString("region", deployment.zone().region().value()); deploymentObject.setString("instance", application.id().instance().value()); // pointless - controller.applications().rotationRepository().getRotation(application).ifPresent(rotation -> { - Map<String, RotationStatus> rotationHealthStatus = controller.rotationStatus(rotation); - setRotationStatus(deployment, rotationHealthStatus, deploymentObject); - }); + if (application.rotation().isPresent() && deployment.zone().environment() == Environment.prod) { + toSlime(application.rotationStatus(deployment), deploymentObject); + } if (recurseOverDeployments(request)) // List full deployment information when recursive. toSlime(deploymentObject, new DeploymentId(application.id(), deployment.zone()), deployment, request); @@ -557,6 +555,11 @@ public class ApplicationApiHandler extends LoggingRequestHandler { object.setString("gitCommit", revision.get().commit()); } + private void toSlime(RotationStatus status, Cursor object) { + Cursor bcpStatus = object.setObject("bcpStatus"); + bcpStatus.setString("rotationStatus", status.name().toUpperCase()); + } + private URI monitoringSystemUri(DeploymentId deploymentId) { return controller.zoneRegistry().getMonitoringSystemUri(deploymentId); } @@ -617,24 +620,18 @@ public class ApplicationApiHandler extends LoggingRequestHandler { private HttpResponse rotationStatus(String tenantName, String applicationName, String instanceName, String environment, String region) { ApplicationId applicationId = ApplicationId.from(tenantName, applicationName, instanceName); Application application = controller.applications().require(applicationId); + ZoneId zone = ZoneId.from(environment, region); if (!application.rotation().isPresent()) { - throw new NotExistsException("global rotation does not exist for '" + environment + "." + region + "'"); + throw new NotExistsException("global rotation does not exist for " + application); + } + Deployment deployment = application.deployments().get(zone); + if (deployment == null) { + throw new NotExistsException(application + " has no deployment in " + zone); } Slime slime = new Slime(); Cursor response = slime.setObject(); - - Map<String, RotationStatus> rotationStatus = controller.applications().rotationRepository() - .getRotation(application) - .map(controller::rotationStatus) - .orElseGet(Collections::emptyMap); - for (String rotationEndpoint : rotationStatus.keySet()) { - if (rotationEndpoint.contains(toDns(environment)) && rotationEndpoint.contains(toDns(region))) { - Cursor bcpStatusObject = response.setObject("bcpStatus"); - bcpStatusObject.setString("rotationStatus", rotationStatus.getOrDefault(rotationEndpoint, RotationStatus.UNKNOWN).name()); - } - } - + toSlime(application.rotationStatus(deployment), response); return new SlimeJsonResponse(slime); } @@ -991,28 +988,6 @@ public class ApplicationApiHandler extends LoggingRequestHandler { } } - private void setRotationStatus(Deployment deployment, Map<String, RotationStatus> healthStatus, Cursor object) { - if ( ! deployment.zone().environment().equals(Environment.prod)) return; - - Cursor bcpStatusObject = object.setObject("bcpStatus"); - bcpStatusObject.setString("rotationStatus", findRotationStatus(deployment, healthStatus).name()); - } - - private RotationStatus findRotationStatus(Deployment deployment, Map<String, RotationStatus> healthStatus) { - for (String endpoint : healthStatus.keySet()) { - if (endpoint.contains(toDns(deployment.zone().environment().value())) && - endpoint.contains(toDns(deployment.zone().region().value()))) { - return healthStatus.getOrDefault(endpoint, RotationStatus.UNKNOWN); - } - } - - return RotationStatus.UNKNOWN; - } - - private String toDns(String id) { - return id.replace('_', '-'); - } - private long asLong(String valueOrNull, long defaultWhenNull) { if (valueOrNull == null) return defaultWhenNull; try { diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java index 61b921aa6c1..287fbe8c36d 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java @@ -23,7 +23,6 @@ import com.yahoo.vespa.hosted.controller.api.integration.entity.EntityService; import com.yahoo.vespa.hosted.controller.api.integration.entity.MemoryEntityService; import com.yahoo.vespa.hosted.controller.api.integration.github.GitHubMock; import com.yahoo.vespa.hosted.controller.api.integration.organization.MockOrganization; -import com.yahoo.vespa.hosted.controller.api.integration.routing.MemoryGlobalRoutingService; import com.yahoo.vespa.hosted.controller.api.integration.routing.RoutingGenerator; import com.yahoo.vespa.hosted.controller.api.integration.stubs.MockBuildService; import com.yahoo.vespa.hosted.controller.api.integration.stubs.MockRunDataStore; @@ -301,7 +300,6 @@ public final class ControllerTester { rotationsConfig, gitHub, entityService, - new MemoryGlobalRoutingService(), zoneRegistryMock, configServer, metricsService, diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/MetricsServiceMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/MetricsServiceMock.java index 474af154b09..d5fa3d14c62 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/MetricsServiceMock.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/MetricsServiceMock.java @@ -1,6 +1,7 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.controller.integration; +import com.yahoo.component.AbstractComponent; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.HostName; import com.yahoo.vespa.hosted.controller.api.integration.MetricsService; @@ -13,7 +14,7 @@ import java.util.Map; /** * @author bratseth */ -public class MetricsServiceMock implements MetricsService { +public class MetricsServiceMock extends AbstractComponent implements MetricsService { private final Map<String, Double> metrics = new HashMap<>(); private final Map<String, Map<HostName, RotationStatus>> rotationStatus = new HashMap<>(); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java index 2decbe54cb0..992e3cfcd36 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ControllerContainerTest.java @@ -69,7 +69,6 @@ public class ControllerContainerTest { " <component id='com.yahoo.vespa.hosted.controller.api.integration.dns.MemoryNameService'/>\n" + " <component id='com.yahoo.vespa.hosted.controller.api.integration.entity.MemoryEntityService'/>\n" + " <component id='com.yahoo.vespa.hosted.controller.api.integration.github.GitHubMock'/>\n" + - " <component id='com.yahoo.vespa.hosted.controller.api.integration.routing.MemoryGlobalRoutingService'/>\n" + " <component id='com.yahoo.vespa.hosted.controller.api.integration.stubs.LoggingDeploymentIssues'/>\n" + " <component id='com.yahoo.vespa.hosted.controller.api.integration.stubs.DummyOwnershipIssues'/>\n" + " <component id='com.yahoo.vespa.hosted.controller.api.integration.stubs.MockRunDataStore'/>\n" + diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java index aa219aab05d..83605c31b42 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java @@ -46,7 +46,9 @@ import com.yahoo.vespa.hosted.controller.athenz.mock.AthenzDbMock; import com.yahoo.vespa.hosted.controller.deployment.ApplicationPackageBuilder; import com.yahoo.vespa.hosted.controller.deployment.BuildJob; import com.yahoo.vespa.hosted.controller.integration.ConfigServerMock; +import com.yahoo.vespa.hosted.controller.integration.MetricsServiceMock; import com.yahoo.vespa.hosted.controller.maintenance.ContactInformationMaintainer; +import com.yahoo.vespa.hosted.controller.maintenance.DeploymentMetricsMaintainer; import com.yahoo.vespa.hosted.controller.maintenance.JobControl; import com.yahoo.vespa.hosted.controller.restapi.ContainerControllerTester; import com.yahoo.vespa.hosted.controller.restapi.ContainerTester; @@ -433,28 +435,7 @@ public class ApplicationApiTest extends ControllerContainerTest { tester.assertResponse(request("/application/v4/", Request.Method.OPTIONS), ""); - // GET global rotation status - tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default/global-rotation", GET) - .userIdentity(USER_ID), - new File("global-rotation.json")); - - // GET global rotation override status - tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default/global-rotation/override", GET) - .userIdentity(USER_ID), - new File("global-rotation-get.json")); - - // SET global rotation override status - tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2/environment/prod/region/us-west-1/instance/default/global-rotation/override", PUT) - .userIdentity(USER_ID) - .data("{\"reason\":\"because i can\"}"), - new File("global-rotation-put.json")); - - // DELETE global rotation override status - tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2/environment/prod/region/us-west-1/instance/default/global-rotation/override", DELETE) - .userIdentity(USER_ID) - .data("{\"reason\":\"because i can\"}"), - new File("global-rotation-delete.json")); - + // Promote from pipeline tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/promote", POST) .screwdriverIdentity(SCREWDRIVER_ID), "{\"message\":\"Successfully copied environment hosted-verified-prod to hosted-instance_tenant1_application1_placeholder_component_default\"}"); @@ -480,6 +461,58 @@ public class ApplicationApiTest extends ControllerContainerTest { } @Test + public void testRotationOverride() { + // Setup + tester.computeVersionStatus(); + createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, USER_ID); + ApplicationPackage applicationPackage = new ApplicationPackageBuilder() + .globalServiceId("foo") + .region("us-west-1") + .region("us-east-3") + .build(); + + // Create tenant and deploy + ApplicationId id = createTenantAndApplication(); + long projectId = 1; + HttpEntity deployData = createApplicationDeployData(Optional.empty(), false); + startAndTestChange(controllerTester, id, projectId, applicationPackage, deployData, 100); + + // us-west-1 + tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default/deploy", POST) + .data(deployData) + .screwdriverIdentity(SCREWDRIVER_ID), + new File("deploy-result.json")); + controllerTester.jobCompletion(JobType.productionUsWest1) + .application(id) + .projectId(projectId) + .submit(); + setZoneInRotation("rotation-fqdn-1", ZoneId.from("prod", "us-west-1")); + + // GET global rotation status + setZoneInRotation("rotation-fqdn-1", ZoneId.from("prod", "us-west-1")); + tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default/global-rotation", GET) + .userIdentity(USER_ID), + new File("global-rotation.json")); + + // GET global rotation override status + tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default/global-rotation/override", GET) + .userIdentity(USER_ID), + new File("global-rotation-get.json")); + + // SET global rotation override status + tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default/global-rotation/override", PUT) + .userIdentity(USER_ID) + .data("{\"reason\":\"because i can\"}"), + new File("global-rotation-put.json")); + + // DELETE global rotation override status + tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default/global-rotation/override", DELETE) + .userIdentity(USER_ID) + .data("{\"reason\":\"because i can\"}"), + new File("global-rotation-delete.json")); + } + + @Test public void testDeployDirectly() { // Setup tester.computeVersionStatus(); @@ -537,31 +570,13 @@ public class ApplicationApiTest extends ControllerContainerTest { @Test public void testSortsDeploymentsAndJobs() { - // Setup tester.computeVersionStatus(); - createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, USER_ID); - - // Create tenant - tester.assertResponse(request("/application/v4/tenant/tenant1", POST) - .userIdentity(USER_ID) - .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}") - .nToken(N_TOKEN), - new File("tenant-without-applications.json")); - - // Create application - tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", POST) - .userIdentity(USER_ID) - .nToken(N_TOKEN), - new File("application-reference.json")); - - // Give Screwdriver project deploy access - addScrewdriverUserToDeployRole(SCREWDRIVER_ID, ATHENZ_TENANT_DOMAIN, new com.yahoo.vespa.hosted.controller.api.identifiers.ApplicationId("application1")); // Deploy ApplicationPackage applicationPackage = new ApplicationPackageBuilder() .region("us-east-3") .build(); - ApplicationId id = ApplicationId.from("tenant1", "application1", "default"); + ApplicationId id = createTenantAndApplication(); long projectId = 1; HttpEntity deployData = createApplicationDeployData(Optional.empty(), false); startAndTestChange(controllerTester, id, projectId, applicationPackage, deployData, 100); @@ -595,6 +610,8 @@ public class ApplicationApiTest extends ControllerContainerTest { .projectId(projectId) .submit(); + setZoneInRotation("rotation-fqdn-1", ZoneId.from("prod", "us-west-1")); + // us-east-3 tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-east-3/instance/default/deploy", POST) .data(deployData) @@ -1135,6 +1152,23 @@ public class ApplicationApiTest extends ControllerContainerTest { athenzApplication.addRoleMember(ApplicationAction.deploy, screwdriverIdentity); } + private ApplicationId createTenantAndApplication() { + createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, USER_ID); + tester.assertResponse(request("/application/v4/tenant/tenant1", POST) + .userIdentity(USER_ID) + .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}") + .nToken(N_TOKEN), + new File("tenant-without-applications.json")); + tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", POST) + .userIdentity(USER_ID) + .nToken(N_TOKEN), + new File("application-reference.json")); + addScrewdriverUserToDeployRole(SCREWDRIVER_ID, ATHENZ_TENANT_DOMAIN, + new com.yahoo.vespa.hosted.controller.api.identifiers.ApplicationId("application1")); + + return ApplicationId.from("tenant1", "application1", "default"); + } + private void startAndTestChange(ContainerControllerTester controllerTester, ApplicationId application, long projectId, ApplicationPackage applicationPackage, HttpEntity deployData, long buildNumber) { @@ -1211,10 +1245,22 @@ public class ApplicationApiTest extends ControllerContainerTest { } } + private MetricsServiceMock metricsService() { + return (MetricsServiceMock) tester.container().components().getComponent(MetricsServiceMock.class.getName()); + } + private MockOrganization organization() { return (MockOrganization) tester.container().components().getComponent(MockOrganization.class.getName()); } + private void setZoneInRotation(String rotationName, ZoneId zone) { + String vipName = "proxy." + zone.value() + ".vip.test"; + metricsService().addRotation(rotationName) + .setZoneIn(rotationName, vipName); + + new DeploymentMetricsMaintainer(tester.controller(), Duration.ofDays(1), new JobControl(tester.controller().curator())).run(); + } + private void updateContactInformation() { new ContactInformationMaintainer(tester.controller(), Duration.ofDays(1), new JobControl(tester.controller().curator()), |