diff options
author | toby <smorgrav@yahoo-inc.com> | 2017-09-21 13:14:59 +0200 |
---|---|---|
committer | toby <smorgrav@yahoo-inc.com> | 2017-10-10 13:37:59 +0200 |
commit | 68be3728309ab82c817f4308c5a3b7d1decfd8e9 (patch) | |
tree | e18a4679f87a8db8c23ffe39b9462d850c286024 /controller-server | |
parent | 84d41e7604041d8439655dcd47463db9d8c21e71 (diff) |
Refactor cost APIs and modelling - this is a breaking change
Diffstat (limited to 'controller-server')
6 files changed, 85 insertions, 143 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 68912ac55ef..3b43991899c 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 @@ -18,7 +18,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.athens.Athens; import com.yahoo.vespa.hosted.controller.api.integration.athens.ZmsClient; import com.yahoo.vespa.hosted.controller.api.integration.chef.Chef; import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServerClient; -import com.yahoo.vespa.hosted.controller.api.integration.cost.ApplicationCost; +import com.yahoo.vespa.hosted.controller.api.integration.cost.CostApplication; import com.yahoo.vespa.hosted.controller.api.integration.cost.Cost; import com.yahoo.vespa.hosted.controller.api.integration.dns.NameService; import com.yahoo.vespa.hosted.controller.api.integration.entity.EntityService; @@ -175,7 +175,7 @@ public class Controller extends AbstractComponent { public Clock clock() { return clock; } - public ApplicationCost getApplicationCost(com.yahoo.config.provision.ApplicationId application, + public CostApplication getApplicationCost(com.yahoo.config.provision.ApplicationId application, com.yahoo.config.provision.Zone zone) throws NotFoundCheckedException { return cost.getApplicationCost(zone.environment(), zone.region(), application); 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 c2777a78f32..2f11530b1f5 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 @@ -55,8 +55,8 @@ import com.yahoo.vespa.hosted.controller.api.integration.athens.NToken; import com.yahoo.vespa.hosted.controller.api.integration.athens.ZmsException; import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServerException; import com.yahoo.vespa.hosted.controller.api.integration.configserver.Log; -import com.yahoo.vespa.hosted.controller.api.integration.cost.ApplicationCost; -import com.yahoo.vespa.hosted.controller.api.integration.cost.CostJsonModelAdapter; +import com.yahoo.vespa.hosted.controller.api.integration.cost.CostApplication; +import com.yahoo.vespa.hosted.controller.api.integration.cost.restapi.CostJsonModelAdapter; import com.yahoo.vespa.hosted.controller.api.integration.routing.RotationStatus; import com.yahoo.vespa.hosted.controller.application.ApplicationPackage; import com.yahoo.vespa.hosted.controller.application.ApplicationRevision; @@ -432,7 +432,7 @@ public class ApplicationApiHandler extends LoggingRequestHandler { // Cost try { - ApplicationCost appCost = controller.getApplicationCost(applicationId, zoneId); + CostApplication appCost = controller.getApplicationCost(applicationId, zoneId); Cursor costObject = response.setObject("cost"); CostJsonModelAdapter.toSlime(appCost, costObject); } catch (NotFoundCheckedException nfce) { 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 b5419bca0a5..de6e1b9af35 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 @@ -9,6 +9,7 @@ import com.yahoo.config.provision.RegionName; import com.yahoo.config.provision.TenantName; import com.yahoo.config.provision.Zone; import com.yahoo.test.ManualClock; +import com.yahoo.vespa.curator.Lock; import com.yahoo.vespa.hosted.controller.api.Tenant; import com.yahoo.vespa.hosted.controller.api.application.v4.model.DeployOptions; import com.yahoo.vespa.hosted.controller.api.application.v4.model.GitRevision; @@ -30,8 +31,8 @@ import com.yahoo.vespa.hosted.controller.api.integration.github.GitHubMock; import com.yahoo.vespa.hosted.controller.api.integration.jira.JiraMock; import com.yahoo.vespa.hosted.controller.api.integration.routing.MemoryGlobalRoutingService; import com.yahoo.vespa.hosted.controller.application.ApplicationPackage; +import com.yahoo.vespa.hosted.controller.application.Change; import com.yahoo.vespa.hosted.controller.cost.CostMock; -import com.yahoo.vespa.hosted.controller.cost.MockInsightBackend; import com.yahoo.vespa.hosted.controller.integration.MockMetricsService; import com.yahoo.vespa.hosted.controller.persistence.ControllerDb; import com.yahoo.vespa.hosted.controller.persistence.CuratorDb; @@ -48,69 +49,72 @@ import static org.junit.Assert.assertTrue; /** * Convenience methods for controller tests. - * + * This completely wraps TestEnvironment to make it easier to get rid of that in the future. + * * @author bratseth - * @author mpolden */ public final class ControllerTester { - private final ControllerDb db; - private final AthensDbMock athensDb; - private final ManualClock clock; - private final ConfigServerClientMock configServer; - private final ZoneRegistryMock zoneRegistry; - private final GitHubMock gitHub; - private final CuratorDb curator; - private final MemoryNameService nameService; - - private Controller controller; - - public ControllerTester() { - this(new MemoryControllerDb(), new AthensDbMock(), new ManualClock(), new ConfigServerClientMock(), - new ZoneRegistryMock(), new GitHubMock(), new MockCuratorDb(), new MemoryNameService()); - } - - public ControllerTester(ManualClock clock) { - this(new MemoryControllerDb(), new AthensDbMock(), clock, new ConfigServerClientMock(), - new ZoneRegistryMock(), new GitHubMock(), new MockCuratorDb(), new MemoryNameService()); - } - - private ControllerTester(ControllerDb db, AthensDbMock athensDb, ManualClock clock, - ConfigServerClientMock configServer, ZoneRegistryMock zoneRegistry, - GitHubMock gitHub, CuratorDb curator, MemoryNameService nameService) { - this.db = db; - this.athensDb = athensDb; - this.clock = clock; - this.configServer = configServer; - this.zoneRegistry = zoneRegistry; - this.gitHub = gitHub; - this.curator = curator; - this.nameService = nameService; - this.controller = createController(db, curator, configServer, clock, gitHub, zoneRegistry, - athensDb, nameService); + private final ControllerDb db = new MemoryControllerDb(); + private final AthensDbMock athensDb = new AthensDbMock(); + private final ManualClock clock = new ManualClock(); + private final ConfigServerClientMock configServerClientMock = new ConfigServerClientMock(); + private final ZoneRegistryMock zoneRegistryMock = new ZoneRegistryMock(); + private final GitHubMock gitHubMock = new GitHubMock(); + private final CuratorDb curator = new MockCuratorDb(); + private final MemoryNameService memoryNameService = new MemoryNameService(); + private Controller controller = createController(db, curator, configServerClientMock, clock, gitHubMock, + zoneRegistryMock, athensDb, memoryNameService); + + private static final Controller createController(ControllerDb db, CuratorDb curator, + ConfigServerClientMock configServerClientMock, ManualClock clock, + GitHubMock gitHubClientMock, ZoneRegistryMock zoneRegistryMock, + AthensDbMock athensDb, MemoryNameService nameService) { + Controller controller = new Controller(db, + curator, + new MemoryRotationRepository(), + gitHubClientMock, + new JiraMock(), + new MemoryEntityService(), + new MemoryGlobalRoutingService(), + zoneRegistryMock, + new CostMock(), + configServerClientMock, + new MockMetricsService(), + nameService, + new MockRoutingGenerator(), + new ChefMock(), + clock, + new AthensMock(athensDb)); + controller.updateVersionStatus(VersionStatus.compute(controller)); + return controller; } public Controller controller() { return controller; } - public CuratorDb curator() { return curator; } - public ManualClock clock() { return clock; } - public AthensDbMock athensDb() { return athensDb; } + public MemoryNameService nameService() { return memoryNameService; } - public MemoryNameService nameService() { return nameService; } + /** Create a new controller instance. Useful to verify that controller state is rebuilt from persistence */ + public final void createNewController() { + controller = createController(db, curator, configServerClientMock, clock, gitHubMock, zoneRegistryMock, + athensDb, memoryNameService); + } - public ZoneRegistryMock zoneRegistry() { return zoneRegistry; } + public ZoneRegistryMock getZoneRegistryMock() { return zoneRegistryMock; } - public ConfigServerClientMock configServer() { return configServer; } + public ConfigServerClientMock configServerClientMock() { return configServerClientMock; } - public GitHubMock gitHub() { return gitHub; } + public GitHubMock gitHubClientMock () { return gitHubMock; } - /** Create a new controller instance. Useful to verify that controller state is rebuilt from persistence */ - public final void createNewController() { - controller = createController(db, curator, configServer, clock, gitHub, zoneRegistry, athensDb, nameService); + /** Set the application with the given id to currently be in the progress of rolling out the given change */ + public void setDeploying(ApplicationId id, Optional<Change> change) { + try (Lock lock = controller.applications().lock(id)) { + controller.applications().store(controller.applications().require(id).withDeploying(change), lock); + } } - + /** Creates the given tenant and application and deploys it */ public Application createAndDeploy(String tenantName, String domainName, String applicationName, Environment environment, long projectId, Long propertyId) { return createAndDeploy(tenantName, domainName, applicationName, toZone(environment), projectId, propertyId); @@ -198,28 +202,4 @@ public final class ControllerTester { InstanceName.from(instance)); } - private static Controller createController(ControllerDb db, CuratorDb curator, - ConfigServerClientMock configServerClientMock, ManualClock clock, - GitHubMock gitHubClientMock, ZoneRegistryMock zoneRegistryMock, - AthensDbMock athensDb, MemoryNameService nameService) { - Controller controller = new Controller(db, - curator, - new MemoryRotationRepository(), - gitHubClientMock, - new JiraMock(), - new MemoryEntityService(), - new MemoryGlobalRoutingService(), - zoneRegistryMock, - new CostMock(new MockInsightBackend()), - configServerClientMock, - new MockMetricsService(), - nameService, - new MockRoutingGenerator(), - new ChefMock(), - clock, - new AthensMock(athensDb)); - controller.updateVersionStatus(VersionStatus.compute(controller)); - return controller; - } - } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/cost/CostMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/cost/CostMock.java index 0a5ddfb5efc..34503374acc 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/cost/CostMock.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/cost/CostMock.java @@ -1,44 +1,45 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.controller.cost; +import com.yahoo.component.AbstractComponent; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.RegionName; -import com.yahoo.vespa.hosted.controller.api.integration.cost.ApplicationCost; -import com.yahoo.vespa.hosted.controller.api.integration.cost.Backend; import com.yahoo.vespa.hosted.controller.api.integration.cost.Cost; -import com.yahoo.vespa.hosted.controller.common.NotFoundCheckedException; +import com.yahoo.vespa.hosted.controller.api.integration.cost.CostApplication; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * @author mpolden */ -public class CostMock implements Cost { +public class CostMock extends AbstractComponent implements Cost { - private final Backend backend; - - public CostMock(Backend backend) { - this.backend = backend; - } + private final Map<ApplicationId, CostApplication> applicationCost = new HashMap<>(); @Override - public List<ApplicationCost> getCPUAnalysis(int nofApplications) { - return null; + public List<CostApplication> getApplicationCost() { + return new ArrayList<>(applicationCost.values()); } + /** + * Get cost for a specific application in one zone or null if this application is not known. + * The zone information is ignored in the dummy backend. + */ @Override - public String getCsvForLocalAnalysis() { - return null; + public CostApplication getApplicationCost(Environment env, RegionName region, ApplicationId application) { + return applicationCost.get(application); } - @Override - public List<ApplicationCost> getApplicationCost() { - return backend.getApplicationCost(); + public void setApplicationCost(ApplicationId application, CostApplication cost) { + applicationCost.put(application, cost); } @Override - public ApplicationCost getApplicationCost(Environment env, RegionName region, ApplicationId app) throws NotFoundCheckedException { - return backend.getApplicationCost(env, region, app); + public String getCsvForLocalAnalysis() { + return null; } } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/cost/MockInsightBackend.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/cost/MockInsightBackend.java deleted file mode 100644 index c4ba5fa4fc5..00000000000 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/cost/MockInsightBackend.java +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.hosted.controller.cost; - -import com.yahoo.component.AbstractComponent; -import com.yahoo.config.provision.ApplicationId; -import com.yahoo.config.provision.Environment; -import com.yahoo.config.provision.RegionName; -import com.yahoo.vespa.hosted.controller.api.integration.cost.ApplicationCost; -import com.yahoo.vespa.hosted.controller.api.integration.cost.Backend; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @author bratseth - */ -public class MockInsightBackend extends AbstractComponent implements Backend { - - private final Map<ApplicationId, ApplicationCost> applicationCost = new HashMap<>(); - - @Override - public List<ApplicationCost> getApplicationCost() { - return new ArrayList<>(applicationCost.values()); - } - - /** - * Get cost for a specific application in one zone or null if this application is not known. - * The zone information is ignored in the dummy backend. - */ - @Override - public ApplicationCost getApplicationCost(Environment env, RegionName region, ApplicationId application) { - return applicationCost.get(application); - } - - public void setApplicationCost(ApplicationId application, ApplicationCost cost) { - applicationCost.put(application, cost); - } - -} 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 af05c7bbb58..b4146e9b6b7 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 @@ -4,6 +4,8 @@ package com.yahoo.vespa.hosted.controller.restapi.application; import com.yahoo.application.container.handler.Request; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.Environment; +import com.yahoo.config.provision.RegionName; +import com.yahoo.config.provision.Zone; import com.yahoo.vespa.hosted.controller.ConfigServerClientMock; import com.yahoo.vespa.hosted.controller.api.identifiers.AthensDomain; import com.yahoo.vespa.hosted.controller.api.identifiers.UserId; @@ -13,11 +15,11 @@ import com.yahoo.vespa.hosted.controller.api.integration.athens.mock.AthensDbMoc import com.yahoo.vespa.hosted.controller.api.integration.athens.mock.AthensMock; import com.yahoo.vespa.hosted.controller.api.integration.athens.mock.ZmsClientFactoryMock; import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServerException; -import com.yahoo.vespa.hosted.controller.api.integration.cost.ApplicationCost; -import com.yahoo.vespa.hosted.controller.api.integration.cost.ClusterCost; +import com.yahoo.vespa.hosted.controller.api.integration.cost.CostApplication; +import com.yahoo.vespa.hosted.controller.api.integration.cost.CostCluster; import com.yahoo.vespa.hosted.controller.application.ApplicationPackage; import com.yahoo.vespa.hosted.controller.application.DeploymentJobs; -import com.yahoo.vespa.hosted.controller.cost.MockInsightBackend; +import com.yahoo.vespa.hosted.controller.cost.CostMock; import com.yahoo.vespa.hosted.controller.deployment.ApplicationPackageBuilder; import com.yahoo.vespa.hosted.controller.restapi.ContainerControllerTester; import com.yahoo.vespa.hosted.controller.restapi.ContainerTester; @@ -691,9 +693,9 @@ public class ApplicationApiTest extends ControllerContainerTest { } private void addMockObservedApplicationCost(String tenant, String application, String instance) { - MockInsightBackend mock = (MockInsightBackend) container.components().getComponent("com.yahoo.vespa.hosted.controller.cost.MockInsightBackend"); + CostMock mock = (CostMock) container.components().getComponent("com.yahoo.vespa.hosted.controller.cost.MockInsightBackend"); - ClusterCost cost = new ClusterCost(); + CostCluster cost = new CostCluster(); cost.setCount(2); cost.setResource("cpu"); cost.setUtilization(1.0f); @@ -705,11 +707,11 @@ public class ApplicationApiTest extends ControllerContainerTest { hostnames.add("host1"); hostnames.add("host2"); cost.setHostnames(hostnames); - Map<String, ClusterCost> clusterCosts = new HashMap<>(); + Map<String, CostCluster> clusterCosts = new HashMap<>(); clusterCosts.put("cluster1", cost); mock.setApplicationCost(new ApplicationId.Builder().tenant(tenant).applicationName(application).instanceName(instance).build(), - new ApplicationCost("prod.us-west-1", tenant, application + "." + instance, 37, 1.0f, 0.0f, clusterCosts)); + new CostApplication(new Zone(Environment.prod, RegionName.from("prod.us-west-1")), tenant, application + "." + instance, 37, 1.0f, 0.0f, clusterCosts)); } private void startAndTestChange(ContainerControllerTester controllerTester, ApplicationId application, long projectId, |