diff options
author | Harald Musum <musum@verizonmedia.com> | 2021-03-10 15:48:19 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-10 15:48:19 +0100 |
commit | 34868d7ae17aac147c9652983d31080797c9bca3 (patch) | |
tree | 85419a176d2df3e9db19542220864a809812d0eb | |
parent | ce58e0548f27f3084b63c6d0b00e539099ce59d4 (diff) | |
parent | 949df298d5a012aa5900e8c23f92e6e78a25b120 (diff) |
Merge pull request #16818 from vespa-engine/jonmv/cluster-controller-migration-cleanup
Always use dedicated cluster controllers when hosted (except in some …
21 files changed, 159 insertions, 345 deletions
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java index abd1c7bc7f2..c4eeb41a663 100644 --- a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java +++ b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java @@ -123,7 +123,7 @@ public interface ModelContext { // Note: Used in unit tests (set to false in TestProperties) to avoid needing to deal with implicitly created node for logserver default boolean useDedicatedNodeForLogserver() { return true; } - default boolean dedicatedClusterControllerCluster() { return false; } + default boolean dedicatedClusterControllerCluster() { return hostedVespa(); } } diff --git a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java index 77e5e98cd99..c1d45c213fb 100644 --- a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java +++ b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java @@ -36,7 +36,7 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea private Zone zone; private final Set<ContainerEndpoint> endpoints = Collections.emptySet(); private boolean useDedicatedNodeForLogserver = false; - private boolean dedicatedClusterControllerCluster = false; + private boolean dedicatedClusterControllerCluster = true; private boolean useThreePhaseUpdates = false; private double defaultTermwiseLimit = 1.0; private String jvmGCOptions = null; @@ -74,7 +74,7 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea @Override public boolean isBootstrap() { return false; } @Override public boolean isFirstTimeDeployment() { return false; } @Override public boolean useDedicatedNodeForLogserver() { return useDedicatedNodeForLogserver; } - @Override public boolean dedicatedClusterControllerCluster() { return dedicatedClusterControllerCluster; } + @Override public boolean dedicatedClusterControllerCluster() { return hostedVespa && dedicatedClusterControllerCluster; } @Override public Optional<EndpointCertificateSecrets> endpointCertificateSecrets() { return endpointCertificateSecrets; } @Override public double defaultTermwiseLimit() { return defaultTermwiseLimit; } @Override public boolean useThreePhaseUpdates() { return useThreePhaseUpdates; } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java index c909aeec022..79ce9343560 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java @@ -413,7 +413,7 @@ public class ContentCluster extends AbstractConfigProducer implements } List<HostResource> sortedHosts = new ArrayList<>(hosts); - sortedHosts.sort((a, b) -> (a.comparePrimarilyByIndexTo(b))); + sortedHosts.sort(HostResource::comparePrimarilyByIndexTo); sortedHosts = sortedHosts.subList(0, Math.min(count, hosts.size())); return sortedHosts; } diff --git a/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java b/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java index 711e153e2bb..5a06379a1c2 100644 --- a/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java +++ b/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java @@ -171,7 +171,7 @@ public class ModelProvisioningTest { " </content>" + "</services>"; VespaModelTester tester = new VespaModelTester(); - int numberOfHosts = 2; + int numberOfHosts = 5; tester.addHosts(numberOfHosts); int numberOfContentNodes = 2; VespaModel model = tester.createModel(xmlWithNodes, true); @@ -209,7 +209,7 @@ public class ModelProvisioningTest { " </content>" + "</services>"; VespaModelTester tester = new VespaModelTester(); - tester.addHosts(5); + tester.addHosts(8); VespaModel model = tester.createModel(xmlWithNodes, true); assertEquals("Nodes in content1", 2, model.getContentClusters().get("content1").getRootGroup().getNodes().size()); @@ -264,6 +264,7 @@ public class ModelProvisioningTest { " </content>" + "</services>"; VespaModelTester tester = new VespaModelTester(); + tester.dedicatedClusterControllerCluster(false); tester.addHosts(2); VespaModel model = tester.createModel(xmlWithNodes, true); assertEquals("Nodes in content1", 2, model.getContentClusters().get("content1").getRootGroup().getNodes().size()); @@ -300,7 +301,7 @@ public class ModelProvisioningTest { " </content>" + "</services>"; VespaModelTester tester = new VespaModelTester(); - tester.addHosts(4); + tester.addHosts(7); VespaModel model = tester.createModel(xmlWithNodes, true); assertEquals("Nodes in content1", 2, model.getContentClusters().get("content1").getRootGroup().getNodes().size()); assertEquals("Nodes in container1", 2, model.getContainerClusters().get("container1").getContainers().size()); @@ -329,6 +330,7 @@ public class ModelProvisioningTest { " </content>" + "</services>"; VespaModelTester tester = new VespaModelTester(); + tester.dedicatedClusterControllerCluster(false); tester.addHosts(2); VespaModel model = tester.createModel(xmlWithNodes, true); @@ -365,7 +367,7 @@ public class ModelProvisioningTest { " </content>" + "</services>"; VespaModelTester tester = new VespaModelTester(); - tester.addHosts(5); + tester.addHosts(8); VespaModel model = tester.createModel(xmlWithNodes, true); assertEquals("Nodes in content1", 2, model.getContentClusters().get("content1").getRootGroup().getNodes().size()); @@ -455,7 +457,112 @@ public class ModelProvisioningTest { public void testUsingNodesAndGroupCountAttributes() { String services = "<?xml version='1.0' encoding='utf-8' ?>\n" + - "<services>" + + "<services>" + + " <admin version='4.0'/>" + + " <container version='1.0' id='foo'>" + + " <nodes count='10'/>" + + " </container>" + + " <content version='1.0' id='bar'>" + + " <redundancy>2</redundancy>" + + " <documents>" + + " <document type='type1' mode='index'/>" + + " </documents>" + + " <nodes count='27' groups='9'/>" + + " </content>" + + " <content version='1.0' id='baz'>" + + " <redundancy>1</redundancy>" + + " <documents>" + + " <document type='type1' mode='index'/>" + + " </documents>" + + " <nodes count='27' groups='27'/>" + + " </content>" + + "</services>"; + + int numberOfHosts = 67; + VespaModelTester tester = new VespaModelTester(); + tester.addHosts(numberOfHosts); + VespaModel model = tester.createModel(services, true); + assertEquals(numberOfHosts, model.getRoot().hostSystem().getHosts().size()); + + // Check container cluster + assertEquals(1, model.getContainerClusters().size()); + Set<HostResource> containerHosts = model.getContainerClusters().get("foo").getContainers().stream() + .map(Container::getHost) + .collect(Collectors.toSet()); + assertEquals(10, containerHosts.size()); + + // Check admin clusters + Admin admin = model.getAdmin(); + Set<HostResource> slobrokHosts = admin.getSlobroks().stream().map(Slobrok::getHost).collect(Collectors.toSet()); + assertEquals(3, slobrokHosts.size()); + assertTrue("Slobroks are assigned from container nodes", containerHosts.containsAll(slobrokHosts)); + assertTrue("Logserver is assigned from container nodes", containerHosts.contains(admin.getLogserver().getHost())); + assertEquals("No in-cluster config servers in a hosted environment", 0, admin.getConfigservers().size()); + assertEquals("Dedicated admin cluster controllers when hosted", 3, admin.getClusterControllers().getContainers().size()); + + // Check content clusters + ContentCluster cluster = model.getContentClusters().get("bar"); + assertNull("No own cluster controllers when hosted", cluster.getClusterControllers()); + assertEquals(0, cluster.getRootGroup().getNodes().size()); + assertEquals(9, cluster.getRootGroup().getSubgroups().size()); + assertEquals("0", cluster.getRootGroup().getSubgroups().get(0).getIndex()); + assertEquals(3, cluster.getRootGroup().getSubgroups().get(0).getNodes().size()); + assertEquals(0, cluster.getRootGroup().getSubgroups().get(0).getNodes().get(0).getDistributionKey()); + assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().get(0).getConfigId(), is("bar/storage/0")); + assertEquals("node-1-3-10-57", cluster.getRootGroup().getSubgroups().get(0).getNodes().get(0).getHostName()); + assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().get(1).getDistributionKey(), is(1)); + assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().get(1).getConfigId(), is("bar/storage/1")); + assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().get(2).getDistributionKey(), is(2)); + assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().get(2).getConfigId(), is("bar/storage/2")); + assertThat(cluster.getRootGroup().getSubgroups().get(1).getIndex(), is("1")); + assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().size(), is(3)); + assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().get(0).getDistributionKey(), is(3)); + assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().get(0).getConfigId(), is("bar/storage/3")); + assertEquals("node-1-3-10-54", cluster.getRootGroup().getSubgroups().get(1).getNodes().get(0).getHostName()); + assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().get(1).getDistributionKey(), is(4)); + assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().get(1).getConfigId(), is("bar/storage/4")); + assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().get(2).getDistributionKey(), is(5)); + assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().get(2).getConfigId(), is("bar/storage/5")); + // ... + assertEquals("node-1-3-10-51", cluster.getRootGroup().getSubgroups().get(2).getNodes().get(0).getHostName()); + // ... + assertThat(cluster.getRootGroup().getSubgroups().get(8).getIndex(), is("8")); + assertThat(cluster.getRootGroup().getSubgroups().get(8).getNodes().size(), is(3)); + assertThat(cluster.getRootGroup().getSubgroups().get(8).getNodes().get(0).getDistributionKey(), is(24)); + assertThat(cluster.getRootGroup().getSubgroups().get(8).getNodes().get(0).getConfigId(), is("bar/storage/24")); + assertThat(cluster.getRootGroup().getSubgroups().get(8).getNodes().get(1).getDistributionKey(), is(25)); + assertThat(cluster.getRootGroup().getSubgroups().get(8).getNodes().get(1).getConfigId(), is("bar/storage/25")); + assertThat(cluster.getRootGroup().getSubgroups().get(8).getNodes().get(2).getDistributionKey(), is(26)); + assertThat(cluster.getRootGroup().getSubgroups().get(8).getNodes().get(2).getConfigId(), is("bar/storage/26")); + + cluster = model.getContentClusters().get("baz"); + assertNull("No own cluster controllers when hosted", cluster.getClusterControllers()); + assertEquals(0, cluster.getRootGroup().getNodes().size()); + assertEquals(27, cluster.getRootGroup().getSubgroups().size()); + assertThat(cluster.getRootGroup().getSubgroups().get(0).getIndex(), is("0")); + assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().size(), is(1)); + assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().get(0).getDistributionKey(), is(0)); + assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().get(0).getConfigId(), is("baz/storage/0")); + assertEquals("node-1-3-10-27", cluster.getRootGroup().getSubgroups().get(0).getNodes().get(0).getHostName()); + assertThat(cluster.getRootGroup().getSubgroups().get(1).getIndex(), is("1")); + assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().size(), is(1)); + assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().get(0).getDistributionKey(), is(1)); + assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().get(0).getConfigId(), is("baz/storage/1")); + assertEquals("node-1-3-10-26", cluster.getRootGroup().getSubgroups().get(1).getNodes().get(0).getHostName()); + // ... + assertEquals("node-1-3-10-25", cluster.getRootGroup().getSubgroups().get(2).getNodes().get(0).getHostName()); + // ... + assertThat(cluster.getRootGroup().getSubgroups().get(26).getIndex(), is("26")); + assertThat(cluster.getRootGroup().getSubgroups().get(26).getNodes().size(), is(1)); + assertThat(cluster.getRootGroup().getSubgroups().get(26).getNodes().get(0).getDistributionKey(), is(26)); + assertThat(cluster.getRootGroup().getSubgroups().get(26).getNodes().get(0).getConfigId(), is("baz/storage/26")); + } + + @Test + public void testUsingNodesAndGroupCountAttributesWithoutDedicatedClusterControllers() { + String services = + "<?xml version='1.0' encoding='utf-8' ?>\n" + + "<services>" + " <admin version='4.0'/>" + " <container version='1.0' id='foo'>" + " <nodes count='10'/>" + @@ -478,6 +585,7 @@ public class ModelProvisioningTest { int numberOfHosts = 64; VespaModelTester tester = new VespaModelTester(); + tester.dedicatedClusterControllerCluster(false); tester.addHosts(numberOfHosts); VespaModel model = tester.createModel(services, true); assertEquals(numberOfHosts, model.getRoot().hostSystem().getHosts().size()); @@ -584,20 +692,22 @@ public class ModelProvisioningTest { " </content>" + "</services>"; - int numberOfHosts = 18; + int numberOfHosts = 21; VespaModelTester tester = new VespaModelTester(); tester.addHosts(numberOfHosts); VespaModel model = tester.createModel(services, true); assertThat(model.getRoot().hostSystem().getHosts().size(), is(numberOfHosts)); + ClusterControllerContainerCluster clusterControllers = model.getAdmin().getClusterControllers(); + assertEquals(3, clusterControllers.getContainers().size()); + assertEquals("cluster-controllers", clusterControllers.getName()); + assertEquals("node-1-3-10-03", clusterControllers.getContainers().get(0).getHostName()); + assertEquals("node-1-3-10-02", clusterControllers.getContainers().get(1).getHostName()); + assertEquals("node-1-3-10-01", clusterControllers.getContainers().get(2).getHostName()); + // Check content cluster ContentCluster cluster = model.getContentClusters().get("bar"); - ClusterControllerContainerCluster clusterControllers = cluster.getClusterControllers(); - assertEquals(3, clusterControllers.getContainers().size()); - assertEquals("bar-controllers", clusterControllers.getName()); - assertEquals("node-1-3-10-08", clusterControllers.getContainers().get(0).getHostName()); - assertEquals("node-1-3-10-07", clusterControllers.getContainers().get(1).getHostName()); - assertEquals("node-1-3-10-06", clusterControllers.getContainers().get(2).getHostName()); + assertNull(cluster.getClusterControllers()); assertEquals(0, cluster.getRootGroup().getNodes().size()); assertEquals(8, cluster.getRootGroup().getSubgroups().size()); assertEquals(8, cluster.distributionBits()); @@ -606,19 +716,19 @@ public class ModelProvisioningTest { assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().size(), is(1)); assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().get(0).getDistributionKey(), is(0)); assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().get(0).getConfigId(), is("bar/storage/0")); - assertEquals("node-1-3-10-08", cluster.getRootGroup().getSubgroups().get(0).getNodes().get(0).getHostName()); + assertEquals("node-1-3-10-11", cluster.getRootGroup().getSubgroups().get(0).getNodes().get(0).getHostName()); // second group assertThat(cluster.getRootGroup().getSubgroups().get(1).getIndex(), is("1")); assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().size(), is(1)); assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().get(0).getDistributionKey(), is(1)); assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().get(0).getConfigId(), is("bar/storage/1")); - assertEquals("node-1-3-10-07", cluster.getRootGroup().getSubgroups().get(1).getNodes().get(0).getHostName()); + assertEquals("node-1-3-10-10", cluster.getRootGroup().getSubgroups().get(1).getNodes().get(0).getHostName()); // ... last group assertThat(cluster.getRootGroup().getSubgroups().get(7).getIndex(), is("7")); assertThat(cluster.getRootGroup().getSubgroups().get(7).getNodes().size(), is(1)); assertThat(cluster.getRootGroup().getSubgroups().get(7).getNodes().get(0).getDistributionKey(), is(7)); assertThat(cluster.getRootGroup().getSubgroups().get(7).getNodes().get(0).getConfigId(), is("bar/storage/7")); - assertEquals("node-1-3-10-01", cluster.getRootGroup().getSubgroups().get(7).getNodes().get(0).getHostName()); + assertEquals("node-1-3-10-04", cluster.getRootGroup().getSubgroups().get(7).getNodes().get(0).getHostName()); } @Test @@ -641,6 +751,7 @@ public class ModelProvisioningTest { int numberOfHosts = 18; VespaModelTester tester = new VespaModelTester(); + tester.dedicatedClusterControllerCluster(false); tester.addHosts(numberOfHosts); VespaModel model = tester.createModel(services, true); assertThat(model.getRoot().hostSystem().getHosts().size(), is(numberOfHosts)); @@ -656,43 +767,6 @@ public class ModelProvisioningTest { } @Test - public void testClusterControllersIncludeNonRetiredNodes() { - String services = - "<?xml version='1.0' encoding='utf-8' ?>\n" + - "<services>" + - " <admin version='4.0'/>" + - " <container version='1.0' id='foo'>" + - " <nodes count='10'/>" + - " </container>" + - " <content version='1.0' id='bar'>" + - " <redundancy>2</redundancy>" + - " <documents>" + - " <document type='type1' mode='index'/>" + - " </documents>" + - " <nodes count='9' groups='3'/>" + - " </content>" + - "</services>"; - - int numberOfHosts = 19; - VespaModelTester tester = new VespaModelTester(); - tester.addHosts(numberOfHosts); - VespaModel model = tester.createModel(services, true, "node-1-3-10-09", "node-1-3-10-06", "node-1-3-10-03"); - assertThat(model.getRoot().hostSystem().getHosts().size(), is(numberOfHosts)); - - // Check content clusters - ContentCluster cluster = model.getContentClusters().get("bar"); - ClusterControllerContainerCluster clusterControllers = cluster.getClusterControllers(); - assertEquals(3 + 3, clusterControllers.getContainers().size()); // 3 new + 3 retired - assertEquals("bar-controllers", clusterControllers.getName()); - assertEquals("Non-retired", "node-1-3-10-08", clusterControllers.getContainers().get(0).getHostName()); - assertEquals("Non-retired", "node-1-3-10-05", clusterControllers.getContainers().get(1).getHostName()); - assertEquals("Non-retired", "node-1-3-10-02", clusterControllers.getContainers().get(2).getHostName()); - assertEquals("Retired", "node-1-3-10-09", clusterControllers.getContainers().get(3).getHostName()); - assertEquals("Retired", "node-1-3-10-06", clusterControllers.getContainers().get(4).getHostName()); - assertEquals("Retired", "node-1-3-10-03", clusterControllers.getContainers().get(5).getHostName()); - } - - @Test public void testSlobroksClustersAreExpandedToIncludeRetiredNodes() { String services = "<?xml version='1.0' encoding='utf-8' ?>\n" + @@ -791,6 +865,7 @@ public class ModelProvisioningTest { int numberOfHosts = 2; VespaModelTester tester = new VespaModelTester(); + tester.dedicatedClusterControllerCluster(false); tester.addHosts(numberOfHosts); VespaModel model = tester.createModel(services, true); assertThat(model.getRoot().hostSystem().getHosts().size(), is(numberOfHosts)); @@ -824,7 +899,6 @@ public class ModelProvisioningTest { int numberOfHosts = 7; VespaModelTester tester = new VespaModelTester(); tester.addHosts(numberOfHosts); - tester.dedicatedClusterControllerCluster(true); VespaModel model = tester.createModel(services); assertEquals(7, model.getRoot().hostSystem().getHosts().size()); @@ -991,6 +1065,7 @@ public class ModelProvisioningTest { int numberOfHosts = 1; // We only have 1 content node -> 1 groups with redundancy 1 VespaModelTester tester = new VespaModelTester(); + tester.dedicatedClusterControllerCluster(false); tester.addHosts(numberOfHosts); VespaModel model = tester.createModel(services, false); assertThat(model.getRoot().hostSystem().getHosts().size(), is(numberOfHosts)); @@ -1048,7 +1123,6 @@ public class ModelProvisioningTest { int numberOfHosts = 4; // needs 2 for foo and 3 for cluster controllers. VespaModelTester tester = new VespaModelTester(); tester.addHosts(numberOfHosts); - tester.dedicatedClusterControllerCluster(true); tester.createModel(services, false); } @@ -1157,6 +1231,7 @@ public class ModelProvisioningTest { int totalHosts = 18; VespaModelTester tester = new VespaModelTester(); + tester.dedicatedClusterControllerCluster(false); tester.addHosts(new NodeResources(0.1, 0.2, 300, 0.3, NodeResources.DiskSpeed.slow), 1);// Logserver tester.addHosts(new NodeResources(0.1, 0.3, 1, 0.5), 2); // Slobrok tester.addHosts(new NodeResources(12, 10, 30, 0.3), 4); // Container @@ -1188,6 +1263,7 @@ public class ModelProvisioningTest { int totalHosts = 10; VespaModelTester tester = new VespaModelTester(); + tester.dedicatedClusterControllerCluster(false); tester.addHosts(new NodeResources(11.5, 10, 30, 0.3), 6); tester.addHosts(new NodeResources(85, 200, 1000_000_000, 0.3), 20); VespaModel model = tester.createModel(services, true); @@ -1216,6 +1292,7 @@ public class ModelProvisioningTest { int totalHosts = 26; VespaModelTester tester = new VespaModelTester(); + tester.dedicatedClusterControllerCluster(false); tester.addHosts(new NodeResources(13.5, 100, 1000, 0.3), 6); tester.addHosts(new NodeResources(85, 200, 1000_000_000, 0.3), 20); VespaModel model = tester.createModel(services, true, true); @@ -1387,10 +1464,11 @@ public class ModelProvisioningTest { tester.setHosted(true); tester.addHosts(4); VespaModel model = tester.createModel(new Zone(Environment.dev, RegionName.from("us-central-1")), services, true); - assertEquals("We get 1 node per cluster and no admin node", 2, model.getHosts().size()); + assertEquals("We get 1 node per cluster and no admin node apart from the dedicated cluster controller", 3, model.getHosts().size()); assertEquals(1, model.getContainerClusters().size()); assertEquals(1, model.getContainerClusters().get("foo").getContainers().size()); assertEquals(1, model.getContentClusters().get("bar").getRootGroup().countNodes()); + assertEquals(1, model.getAdmin().getClusterControllers().getContainers().size()); } /** Deploying an application with "nodes count" standalone should give a single-node deployment */ @@ -1437,6 +1515,7 @@ public class ModelProvisioningTest { " </content>" + "</services>"; VespaModelTester tester = new VespaModelTester(); + tester.dedicatedClusterControllerCluster(false); tester.addHosts(3); VespaModel model = tester.createModel(services, true); assertEquals(3, model.getRoot().hostSystem().getHosts().size()); @@ -1737,6 +1816,7 @@ public class ModelProvisioningTest { " </content>" + "</services>"; VespaModelTester tester = new VespaModelTester(); + tester.dedicatedClusterControllerCluster(false); tester.addHosts(6); VespaModel model = tester.createModel(servicesXml, true); @@ -1851,7 +1931,7 @@ public class ModelProvisioningTest { "</services>"); VespaModelTester tester = new VespaModelTester(); - tester.addHosts(new NodeResources(1, 3, 9, 5, NodeResources.DiskSpeed.slow), 2); + tester.addHosts(new NodeResources(1, 3, 10, 5, NodeResources.DiskSpeed.slow), 5); VespaModel model = tester.createModel(services, true, 0); ContentSearchCluster cluster = model.getContentClusters().get("test").getSearch(); assertEquals(2, cluster.getSearchNodes().size()); @@ -1903,7 +1983,7 @@ public class ModelProvisioningTest { "</services>"); VespaModelTester tester = new VespaModelTester(); - tester.addHosts(new NodeResources(1, 3, 9, 1), 1); + tester.addHosts(new NodeResources(1, 3, 10, 1), 4); tester.addHosts(new NodeResources(1, 128, 100, 0.3), 1); VespaModel model = tester.createModel(services, true, 0); ContentSearchCluster cluster = model.getContentClusters().get("test").getSearch(); diff --git a/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerTest.java b/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerTest.java index 87db274d4f5..a11d23dbfbb 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerTest.java @@ -33,7 +33,7 @@ public class MetricsProxyContainerTest { @Test public void one_metrics_proxy_container_is_added_to_every_node() { - var numberOfHosts = 4; + var numberOfHosts = 7; var tester = new VespaModelTester(); tester.addHosts(numberOfHosts); @@ -55,7 +55,6 @@ public class MetricsProxyContainerTest { var numberOfHosts = 7; var tester = new VespaModelTester(); tester.addHosts(numberOfHosts); - tester.dedicatedClusterControllerCluster(true); VespaModel model = tester.createModel(servicesWithManyNodes(), true); assertThat(model.getRoot().hostSystem().getHosts().size(), is(numberOfHosts)); @@ -118,7 +117,7 @@ public class MetricsProxyContainerTest { public void hosted_application_propagates_node_dimensions() { String services = servicesWithContent(); VespaModel hostedModel = getModel(services, hosted); - assertEquals(1, hostedModel.getHosts().size()); + assertEquals(4, hostedModel.getHosts().size()); String configId = containerConfigId(hostedModel, hosted); NodeDimensionsConfig config = getNodeDimensionsConfig(hostedModel, configId); diff --git a/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyModelTester.java b/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyModelTester.java index 7fcd5c14a0f..7c31802fb4d 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyModelTester.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyModelTester.java @@ -44,7 +44,7 @@ class MetricsProxyModelTester { } static VespaModel getModel(String servicesXml, TestMode testMode, DeployState.Builder builder) { - var numberOfHosts = testMode == hosted ? 2 : 1; + var numberOfHosts = testMode == hosted ? 4 : 1; var tester = new VespaModelTester(); tester.addHosts(numberOfHosts); tester.setHosted(testMode == hosted); diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/search/ImplicitIndexingClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/search/ImplicitIndexingClusterTest.java index 2d48f55d3d5..5525f00c381 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/search/ImplicitIndexingClusterTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/search/ImplicitIndexingClusterTest.java @@ -50,7 +50,7 @@ public class ImplicitIndexingClusterTest { ModelContext.Properties properties = new TestProperties().setMultitenant(true).setHostedVespa(true); DeployState.Builder deployStateBuilder = new DeployState.Builder() .properties(properties) - .modelHostProvisioner(new InMemoryProvisioner(true, false, "host1.yahoo.com", "host2.yahoo.com", "host3.yahoo.com")); + .modelHostProvisioner(new InMemoryProvisioner(6, false)); return new VespaModelCreatorWithMockPkg(new MockApplicationPackage.Builder() .withServices("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + servicesXml) diff --git a/config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java index ea76578ef04..811e789752e 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java @@ -1059,7 +1059,7 @@ public class ContentClusterTest extends ContentBaseTest { @Test public void testDedicatedClusterControllers() { - VespaModel noContentModel = createEnd2EndOneNode(new TestProperties().setDedicatedClusterControllerCluster(true) + VespaModel noContentModel = createEnd2EndOneNode(new TestProperties().setHostedVespa(true) .setMultitenant(true), "<?xml version='1.0' encoding='UTF-8' ?>" + "<services version='1.0'>" + @@ -1068,7 +1068,7 @@ public class ContentClusterTest extends ContentBaseTest { assertEquals(Map.of(), noContentModel.getContentClusters()); assertNull("No cluster controller without content", noContentModel.getAdmin().getClusterControllers()); - VespaModel oneContentModel = createEnd2EndOneNode(new TestProperties().setDedicatedClusterControllerCluster(true) + VespaModel oneContentModel = createEnd2EndOneNode(new TestProperties().setHostedVespa(true) .setMultitenant(true), "<?xml version='1.0' encoding='UTF-8' ?>" + "<services version='1.0'>" + @@ -1109,7 +1109,7 @@ public class ContentClusterTest extends ContentBaseTest { " </tuning>" + " </content>" + " </services>"; - VespaModel twoContentModel = createEnd2EndOneNode(new TestProperties().setDedicatedClusterControllerCluster(true) + VespaModel twoContentModel = createEnd2EndOneNode(new TestProperties().setHostedVespa(true) .setMultitenant(true), twoContentServices); assertNull("No own cluster controller for content", twoContentModel.getContentClusters().get("storage").getClusterControllers()); diff --git a/config-model/src/test/java/com/yahoo/vespa/model/test/ModelAmendingTestCase.java b/config-model/src/test/java/com/yahoo/vespa/model/test/ModelAmendingTestCase.java index 001773abb92..4a388025399 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/test/ModelAmendingTestCase.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/test/ModelAmendingTestCase.java @@ -74,7 +74,7 @@ public class ModelAmendingTestCase { " </content>" + "</services>"; VespaModelTester tester = new VespaModelTester(amendingModelRepo); - tester.addHosts(9); + tester.addHosts(12); VespaModel model = tester.createModel(services); // Check that all hosts are amended @@ -121,7 +121,6 @@ public class ModelAmendingTestCase { " </content>" + "</services>"; VespaModelTester tester = new VespaModelTester(amendingModelRepo); - tester.dedicatedClusterControllerCluster(true); tester.addHosts(12); VespaModel model = tester.createModel(services); diff --git a/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java b/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java index 220f87001aa..eafbca09009 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java @@ -52,7 +52,7 @@ public class VespaModelTester { private final Map<NodeResources, Collection<Host>> hostsByResources = new HashMap<>(); private ApplicationId applicationId = ApplicationId.defaultId(); private boolean useDedicatedNodeForLogserver = false; - private boolean dedicatedClusterControllerCluster = false; + private boolean dedicatedClusterControllerCluster = true; public VespaModelTester() { this(new NullConfigModelRegistry()); @@ -98,14 +98,14 @@ public class VespaModelTester { applicationId = ApplicationId.from(tenant, applicationName, instanceName); } - public void dedicatedClusterControllerCluster(boolean dedicatedClusterControllerCluster) { - this.dedicatedClusterControllerCluster = dedicatedClusterControllerCluster; - } - public void useDedicatedNodeForLogserver(boolean useDedicatedNodeForLogserver) { this.useDedicatedNodeForLogserver = useDedicatedNodeForLogserver; } + public void dedicatedClusterControllerCluster(boolean dedicatedClusterControllerCluster) { + this.dedicatedClusterControllerCluster = dedicatedClusterControllerCluster; + } + /** Creates a model which uses 0 as start index and fails on out of capacity */ public VespaModel createModel(String services, String ... retiredHostNames) { return createModel(Zone.defaultZone(), services, true, retiredHostNames); diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/Deployer.java b/config-provisioning/src/main/java/com/yahoo/config/provision/Deployer.java index 24dc2022e3c..20e23edddce 100644 --- a/config-provisioning/src/main/java/com/yahoo/config/provision/Deployer.java +++ b/config-provisioning/src/main/java/com/yahoo/config/provision/Deployer.java @@ -71,10 +71,4 @@ public interface Deployer { /** Timeout in server, clients can use this to set correct client timeout */ default Duration serverDeployTimeout() { return Duration.ofMinutes(30); } - /** Turn on dedicated cluster controllers for the given application. */ - default void setDedicatedClusterControllerCluster(ApplicationId id) { } - - /** Get whether the given application uses dedicated cluster controllers. */ - default boolean getDedicatedClusterControllerCluster(ApplicationId id) { return false; } - } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java index b46231d7070..5d46f3dc240 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java @@ -1064,16 +1064,6 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye @Override public Duration serverDeployTimeout() { return Duration.ofSeconds(configserverConfig.zookeeper().barrierTimeout()); } - @Override - public void setDedicatedClusterControllerCluster(ApplicationId id) { - requireDatabase(id).setDedicatedClusterControllerCluster(id); - } - - @Override - public boolean getDedicatedClusterControllerCluster(ApplicationId id) { - return requireDatabase(id).getDedicatedClusterControllerCluster(id); - } - private static void logConfigChangeActions(ConfigChangeActions actions, DeployLogger logger) { RestartActions restartActions = actions.getRestartActions(); if ( ! restartActions.isEmpty()) { diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationCuratorDatabase.java b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationCuratorDatabase.java index 078c60c1446..4704c5fcf26 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationCuratorDatabase.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationCuratorDatabase.java @@ -113,10 +113,6 @@ public class ApplicationCuratorDatabase { : data.map(bytes -> Long.parseLong(Utf8.toString(bytes))); } - public boolean getDedicatedClusterControllerCluster(ApplicationId id) { - return curator.exists(dedicatedClusterControllerClusterPath(id)); - } - public void setDedicatedClusterControllerCluster(ApplicationId id) { curator.create(dedicatedClusterControllerClusterPath(id)); } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java index 8e6d51a55df..5f89903bf07 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java @@ -260,7 +260,6 @@ public class ModelContextImpl implements ModelContext { private final Quota quota; private final List<TenantSecretStore> tenantSecretStores; private final SecretStore secretStore; - private final boolean dedicatedClusterControllerCluster; private final String jvmGcOptions; @@ -276,8 +275,7 @@ public class ModelContextImpl implements ModelContext { Optional<ApplicationRoles> applicationRoles, Optional<Quota> maybeQuota, List<TenantSecretStore> tenantSecretStores, - SecretStore secretStore, - boolean dedicatedClusterControllerCluster) { + SecretStore secretStore) { this.featureFlags = new FeatureFlags(flagSource, applicationId); this.applicationId = applicationId; this.multitenant = configserverConfig.multitenant() || configserverConfig.hostedVespa() || Boolean.getBoolean("multitenant"); @@ -294,7 +292,6 @@ public class ModelContextImpl implements ModelContext { this.athenzDomain = athenzDomain; this.applicationRoles = applicationRoles; this.quota = maybeQuota.orElseGet(Quota::unlimited); - this.dedicatedClusterControllerCluster = dedicatedClusterControllerCluster; this.tenantSecretStores = tenantSecretStores; this.secretStore = secretStore; @@ -360,8 +357,6 @@ public class ModelContextImpl implements ModelContext { @Override public String jvmGCOptions() { return jvmGcOptions; } - @Override public boolean dedicatedClusterControllerCluster() { return hostedVespa && dedicatedClusterControllerCluster; } - private static <V> V flagValue(FlagSource source, ApplicationId appId, UnboundFlag<? extends V, ?, ?> flag) { return flag.bindTo(source) .with(FetchVector.Dimension.APPLICATION_ID, appId.serializedForm()) diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java b/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java index fd04d4b58fc..cfc47223b11 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java @@ -164,8 +164,7 @@ public class ActivatedModelsBuilder extends ModelsBuilder<Application> { .readApplicationRoles(applicationId), zkClient.readQuota(), zkClient.readTenantSecretStores(), - secretStore, - zkClient.readDedicatedClusterControllerCluster()); + secretStore); } } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java index d245e0a3e25..62052e935f1 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java @@ -116,12 +116,9 @@ public class SessionPreparer { Optional<ApplicationSet> activeApplicationSet, Instant now, File serverDbSessionDir, ApplicationPackage applicationPackage, SessionZooKeeperClient sessionZooKeeperClient) { ApplicationId applicationId = params.getApplicationId(); - boolean dedicatedClusterControllerCluster = new ApplicationCuratorDatabase(applicationId.tenant(), curator).getDedicatedClusterControllerCluster(applicationId); - Preparation preparation = new Preparation(hostValidator, logger, params, activeApplicationSet, TenantRepository.getTenantPath(applicationId.tenant()), - serverDbSessionDir, applicationPackage, sessionZooKeeperClient, - dedicatedClusterControllerCluster); + serverDbSessionDir, applicationPackage, sessionZooKeeperClient, true); preparation.preprocess(); try { AllocatedHosts allocatedHosts = preparation.buildModels(now); @@ -207,8 +204,7 @@ public class SessionPreparer { applicationRoles, params.quota(), params.tenantSecretStores(), - secretStore, - dedicatedClusterControllerCluster); + secretStore); this.fileDistributionProvider = fileDistributionFactory.createProvider(serverDbSessionDir); this.preparedModelsBuilder = new PreparedModelsBuilder(modelFactoryRegistry, permanentApplicationPackage, diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java index 0d066f748c8..7b9420b6b9e 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java @@ -74,8 +74,7 @@ public class ModelContextImplTest { Optional.empty(), Optional.empty(), List.of(), - new SecretStoreProvider().get(), - false), + new SecretStoreProvider().get()), Optional.empty(), Optional.empty(), new Version(7), diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/DedicatedClusterControllerClusterMigrator.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/DedicatedClusterControllerClusterMigrator.java deleted file mode 100644 index 4588fc13875..00000000000 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/DedicatedClusterControllerClusterMigrator.java +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.hosted.provision.maintenance; - -import com.yahoo.config.provision.ApplicationId; -import com.yahoo.config.provision.Deployer; -import com.yahoo.config.provision.Environment; -import com.yahoo.jdisc.Metric; -import com.yahoo.vespa.flags.BooleanFlag; -import com.yahoo.vespa.flags.FetchVector; -import com.yahoo.vespa.flags.FlagSource; -import com.yahoo.vespa.flags.Flags; -import com.yahoo.vespa.hosted.provision.NodeRepository; -import com.yahoo.vespa.orchestrator.Orchestrator; - -import java.time.Duration; -import java.time.ZonedDateTime; -import java.util.List; -import java.util.Set; -import java.util.logging.Level; - -import static java.time.DayOfWeek.SATURDAY; -import static java.time.DayOfWeek.SUNDAY; -import static java.util.stream.Collectors.toUnmodifiableSet; - -/** - * @author jonmv - */ -public class DedicatedClusterControllerClusterMigrator extends ApplicationMaintainer { - - private final BooleanFlag flag; - private final Orchestrator orchestrator; - - protected DedicatedClusterControllerClusterMigrator(Deployer deployer, Metric metric, NodeRepository nodeRepository, - Duration interval, FlagSource flags, Orchestrator orchestrator) { - super(deployer, metric, nodeRepository, interval); - this.flag = Flags.DEDICATED_CLUSTER_CONTROLLER_CLUSTER.bindTo(flags); - this.orchestrator = orchestrator; - } - - @Override - protected Set<ApplicationId> applicationsNeedingMaintenance() { - if (deployer().bootstrapping()) return Set.of(); - - ZonedDateTime date = ZonedDateTime.ofInstant(clock().instant(), java.time.ZoneId.of("Europe/Oslo")); - if ( ! nodeRepository().zone().system().isCd() - && nodeRepository().zone().environment() != Environment.staging - && (List.of(SATURDAY, SUNDAY).contains(date.getDayOfWeek()) || date.getHour() < 8 || 13 < date.getHour())) - return Set.of(); - - return nodeRepository().applications().ids().stream() - .sorted() - .filter(id -> ! id.instance().isTester()) - .filter(this::isEligible) - .filter(this::hasNotSwitched) - .filter(this::isQuiescent) - .limit(1) - .collect(toUnmodifiableSet()); - } - - @Override - protected void deploy(ApplicationId id) { - migrate(id); - super.deploy(id); - } - - private boolean isEligible(ApplicationId id) { - return deployer().lastDeployTime(id).map(at -> at.isBefore(clock().instant().minus(Duration.ofMinutes(10)))).orElse(false) - && flag.with(FetchVector.Dimension.APPLICATION_ID, id.serializedForm()).value(); - } - - private boolean hasNotSwitched(ApplicationId id) { - return ! deployer().getDedicatedClusterControllerCluster(id); - } - - private boolean isQuiescent(ApplicationId id) { - return orchestrator.isQuiescent(id); // Check all content nodes are UP, have wanted state UP, and can be moved to MAINTENANCE. - } - - private void migrate(ApplicationId id) { - log.log(Level.INFO, "Migrating " + id + " to dedicated cluster controller cluster"); - deployer().setDedicatedClusterControllerCluster(id); - } - -} diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java index 08106a94205..7f41f89f664 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java @@ -68,7 +68,6 @@ public class NodeRepositoryMaintenance extends AbstractComponent { maintainers.add(new AutoscalingMaintainer(nodeRepository, metricsDb, deployer, metric, defaults.autoscalingInterval)); maintainers.add(new ScalingSuggestionsMaintainer(nodeRepository, metricsDb, defaults.scalingSuggestionsInterval, metric)); maintainers.add(new SwitchRebalancer(nodeRepository, defaults.switchRebalancerInterval, metric, deployer)); - maintainers.add(new DedicatedClusterControllerClusterMigrator(deployer, metric, nodeRepository, defaults.dedicatedClusterControllerMigratorInterval, flagSource, orchestrator)); provisionServiceProvider.getLoadBalancerService(nodeRepository) .map(lbService -> new LoadBalancerExpirer(nodeRepository, defaults.loadBalancerExpirerInterval, lbService, metric)) @@ -120,7 +119,6 @@ public class NodeRepositoryMaintenance extends AbstractComponent { private final Duration autoscalingInterval; private final Duration scalingSuggestionsInterval; private final Duration switchRebalancerInterval; - private final Duration dedicatedClusterControllerMigratorInterval; private final NodeFailer.ThrottlePolicy throttlePolicy; @@ -149,8 +147,6 @@ public class NodeRepositoryMaintenance extends AbstractComponent { switchRebalancerInterval = Duration.ofHours(1); throttlePolicy = NodeFailer.ThrottlePolicy.hosted; retiredExpiry = Duration.ofDays(4); // give up migrating data after 4 days - dedicatedClusterControllerMigratorInterval = zone.environment() == Environment.staging || zone.system().isCd() ? Duration.ofMinutes(3) - : Duration.ofHours(2); inactiveConfigServerExpiry = Duration.ofMinutes(5); inactiveControllerExpiry = Duration.ofMinutes(5); diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DedicatedClusterControllerClusterMigratorTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DedicatedClusterControllerClusterMigratorTest.java deleted file mode 100644 index 22db730d69f..00000000000 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DedicatedClusterControllerClusterMigratorTest.java +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.hosted.provision.maintenance; - -import com.yahoo.config.provision.ApplicationId; -import com.yahoo.config.provision.Capacity; -import com.yahoo.config.provision.ClusterResources; -import com.yahoo.config.provision.Deployer; -import com.yahoo.config.provision.Deployment; -import com.yahoo.config.provision.HostFilter; -import com.yahoo.config.provision.NodeResources; -import com.yahoo.jdisc.test.MockMetric; -import com.yahoo.vespa.flags.Flags; -import com.yahoo.vespa.flags.InMemoryFlagSource; -import com.yahoo.vespa.hosted.provision.applications.Application; -import com.yahoo.vespa.hosted.provision.provisioning.ProvisioningTester; -import com.yahoo.vespa.hosted.provision.testutils.OrchestratorMock; -import org.junit.Test; - -import java.time.Duration; -import java.time.Instant; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.ConcurrentSkipListSet; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Phaser; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -/** - * @author jonmv - */ -public class DedicatedClusterControllerClusterMigratorTest { - - @Test - public void testMigration() throws InterruptedException, TimeoutException { - ApplicationId id1 = ApplicationId.from("t", "a", "i1"), id2 = ApplicationId.from("t", "a", "i2"); - ProvisioningTester tester = new ProvisioningTester.Builder().build(); - tester.clock().setInstant(Instant.EPOCH); // EPOCH was a week-day. - tester.makeReadyNodes(4, new NodeResources(1.5, 8, 50, 0.3)); - tester.makeReadyHosts(1, NodeResources.unspecified()); - tester.deploy(id1, Capacity.from(new ClusterResources(2, 1, NodeResources.unspecified()))); - tester.deploy(id2, Capacity.from(new ClusterResources(2, 1, NodeResources.unspecified()))); - MockDeployer deployer = new MockDeployer(); - InMemoryFlagSource flags = new InMemoryFlagSource(); - AtomicBoolean isQuiescent = new AtomicBoolean(); - OrchestratorMock orchestrator = new OrchestratorMock() { - @Override public boolean isQuiescent(ApplicationId id) { return isQuiescent.get(); } - }; - - DedicatedClusterControllerClusterMigrator migrator = new DedicatedClusterControllerClusterMigrator(deployer, - new MockMetric(), - tester.nodeRepository(), - Duration.ofDays(365), - flags, - orchestrator); - assertFalse(deployer.getDedicatedClusterControllerCluster(id1)); - - // Set all conditions true except time window. - flags.withBooleanFlag(Flags.DEDICATED_CLUSTER_CONTROLLER_CLUSTER.id(), true); - isQuiescent.set(true); - deployer.deployedAt.set(tester.clock().instant().minus(Duration.ofMinutes(15))); - migrator.maintain(); - assertFalse(deployer.getDedicatedClusterControllerCluster(id1)); - - // Enter time window, but no longer quiescent. - tester.clock().advance(Duration.ofHours(8)); - isQuiescent.set(false); - migrator.maintain(); - assertFalse(deployer.getDedicatedClusterControllerCluster(id1)); - - // Quiescent, but no longer flagged. - isQuiescent.set(true); - flags.withBooleanFlag(Flags.DEDICATED_CLUSTER_CONTROLLER_CLUSTER.id(), false); - migrator.maintain(); - assertFalse(deployer.getDedicatedClusterControllerCluster(id1)); - - // Flagged, but recently deployed. - flags.withBooleanFlag(Flags.DEDICATED_CLUSTER_CONTROLLER_CLUSTER.id(), true); - deployer.deployedAt.set(tester.clock().instant().minus(Duration.ofMinutes(5))); - migrator.maintain(); - assertFalse(deployer.getDedicatedClusterControllerCluster(id1)); - - // Finally, all stars align. - deployer.deployedAt.set(tester.clock().instant().minus(Duration.ofMinutes(15))); - migrator.maintain(); - assertTrue(deployer.getDedicatedClusterControllerCluster(id1)); // Lex sorting, t.a.i1 before t.a.i2. - assertFalse(deployer.getDedicatedClusterControllerCluster(id2)); - assertEquals(1, deployer.phaser.awaitAdvanceInterruptibly(deployer.phaser.arrive(), 10, TimeUnit.SECONDS)); - - migrator.maintain(); - assertTrue(deployer.getDedicatedClusterControllerCluster(id2)); - assertEquals(2, deployer.phaser.awaitAdvanceInterruptibly(deployer.phaser.arrive(), 10, TimeUnit.SECONDS)); - - assertEquals(Set.of(), migrator.applicationsNeedingMaintenance()); - } - - - private static class MockDeployer implements Deployer { - - final Phaser phaser = new Phaser(2); // Test thread and deployer. - final Set<ApplicationId> dedicatedCCC = new ConcurrentSkipListSet<>(); - final AtomicReference<Instant> deployedAt = new AtomicReference<>(); - - @Override - public Optional<Deployment> deployFromLocalActive(ApplicationId application, boolean bootstrap) { - return Optional.of(new Deployment() { - @Override public void prepare() { fail("Shouldn't run"); } - @Override public long activate() { return phaser.arriveAndAwaitAdvance(); } - @Override public void restart(HostFilter filter) { fail("Shouldn't run"); } - }); - } - - @Override - public Optional<Deployment> deployFromLocalActive(ApplicationId application, Duration timeout, boolean bootstrap) { - return deployFromLocalActive(application, bootstrap); - } - - @Override - public Optional<Instant> lastDeployTime(ApplicationId application) { - return Optional.ofNullable(deployedAt.get()); - } - - @Override - public void setDedicatedClusterControllerCluster(ApplicationId id) { - dedicatedCCC.add(id); - } - - @Override - public boolean getDedicatedClusterControllerCluster(ApplicationId id) { - return dedicatedCCC.contains(id); - } - - } - -} diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/maintenance.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/maintenance.json index bd4029ec0c0..b31c597e2b0 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/maintenance.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/maintenance.json @@ -4,9 +4,6 @@ "name": "AutoscalingMaintainer" }, { - "name": "DedicatedClusterControllerClusterMigrator" - }, - { "name": "DirtyExpirer" }, { |