summaryrefslogtreecommitdiffstats
path: root/config-model
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@oath.com>2021-04-22 14:39:14 +0200
committerGitHub <noreply@github.com>2021-04-22 14:39:14 +0200
commit5667d6d05eba7ecee06ff39228b92cc62984069d (patch)
tree83a4be8748f4f07742a077a60dbe36d3af28f133 /config-model
parent0e4ce4111091e045b90ff58e2e5bcbfff4395b2a (diff)
parent5cf23a290d37754b5125957d4df782eda6621e4c (diff)
Merge pull request #17544 from vespa-engine/bratseth/clustercontroller-cleanup-take-2
Bratseth/clustercontroller cleanup take 2
Diffstat (limited to 'config-model')
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java7
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java5
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java100
-rw-r--r--config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java131
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerTest.java4
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/QuotaValidatorTest.java14
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/ValidationTester.java4
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ClusterSizeReductionValidatorTest.java4
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ContentClusterRemovalValidatorTest.java2
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java36
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java8
12 files changed, 64 insertions, 253 deletions
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 3722876a53f..59930a77a21 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
@@ -37,7 +37,6 @@ 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 = true;
private boolean useThreePhaseUpdates = false;
private double defaultTermwiseLimit = 1.0;
private String jvmGCOptions = null;
@@ -78,7 +77,6 @@ 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 hostedVespa && dedicatedClusterControllerCluster; }
@Override public Optional<EndpointCertificateSecrets> endpointCertificateSecrets() { return endpointCertificateSecrets; }
@Override public double defaultTermwiseLimit() { return defaultTermwiseLimit; }
@Override public boolean useThreePhaseUpdates() { return useThreePhaseUpdates; }
@@ -170,11 +168,6 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea
return this;
}
- public TestProperties setDedicatedClusterControllerCluster(boolean dedicatedClusterControllerCluster) {
- this.dedicatedClusterControllerCluster = dedicatedClusterControllerCluster;
- return this;
- }
-
public TestProperties setEndpointCertificateSecrets(Optional<EndpointCertificateSecrets> endpointCertificateSecrets) {
this.endpointCertificateSecrets = endpointCertificateSecrets;
return this;
diff --git a/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java b/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java
index 0f824fcacf9..188504edd18 100644
--- a/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java
+++ b/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java
@@ -142,7 +142,6 @@ public class InMemoryProvisioner implements HostProvisioner {
public List<HostSpec> prepare(ClusterSpec cluster, ClusterResources requested, boolean required, boolean canFail) {
if (cluster.group().isPresent() && requested.groups() > 1)
throw new IllegalArgumentException("Cannot both be specifying a group and ask for groups to be created");
-
int capacity = failOnOutOfCapacity || required
? requested.nodes()
: Math.min(requested.nodes(), freeNodes.get(defaultResources).size() + totalAllocatedTo(cluster));
@@ -200,7 +199,9 @@ public class InMemoryProvisioner implements HostProvisioner {
for (int i = allocation.size() - 1; i >= 0; i--) {
NodeResources currentResources = allocation.get(0).advertisedResources();
if (currentResources.isUnspecified() || requestedResources.isUnspecified()) continue;
- if ( ! currentResources.compatibleWith(requestedResources)) {
+ if ( (! sharedHosts && ! currentResources.satisfies(requestedResources))
+ ||
+ (sharedHosts && ! currentResources.compatibleWith(requestedResources))) {
HostSpec removed = allocation.remove(i);
freeNodes.put(currentResources, new Host(removed.hostname())); // Return the node back to free pool
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java
index 3f346f20144..af99ee28e29 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java
@@ -78,7 +78,7 @@ public class Admin extends AbstractConfigProducer<Admin> implements Serializable
private final FileDistributionConfigProducer fileDistribution;
private final boolean multitenant;
- public Admin(AbstractConfigProducer parent,
+ public Admin(AbstractConfigProducer<?> parent,
Monitoring monitoring,
Metrics metrics,
boolean multitenant,
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 79ce9343560..c836209e8b3 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
@@ -291,28 +291,9 @@ public class ContentCluster extends AbstractConfigProducer implements
DeployState deployState) {
if (admin == null) return; // only in tests
if (contentCluster.getPersistence() == null) return;
-
ClusterControllerContainerCluster clusterControllers;
-
- ContentCluster overlappingCluster = findOverlappingCluster(context.getParentProducer().getRoot(), contentCluster);
-
- if (overlappingCluster != null && overlappingCluster.getClusterControllers() != null) {
- // Borrow the cluster controllers of the other cluster in this case.
- // This condition only occurs on non-hosted systems with a shared config server,
- // a combination which only exists in system tests.
- clusterControllers = overlappingCluster.getClusterControllers();
- }
- else if (admin.multitenant()) {
- if (context.properties().dedicatedClusterControllerCluster())
- clusterControllers = getDedicatedSharedControllers(contentElement, admin, context, deployState);
- else {
- clusterControllers = createClusterControllers(new ClusterControllerCluster(contentCluster, "standalone", deployState),
- drawControllerHosts(3, rootGroup),
- contentClusterName + "-controllers",
- true,
- context.getDeployState());
- contentCluster.clusterControllers = clusterControllers;
- }
+ if (context.properties().hostedVespa()) {
+ clusterControllers = getDedicatedSharedControllers(contentElement, admin, context, deployState);
}
else {
clusterControllers = admin.getClusterControllers();
@@ -322,7 +303,8 @@ public class ContentCluster extends AbstractConfigProducer implements
context.getDeployState().getDeployLogger().log(Level.INFO,
"When having content cluster(s) and more than 1 config server it is recommended to configure cluster controllers explicitly.");
}
- clusterControllers = createClusterControllers(admin, hosts, "cluster-controllers", false, context.getDeployState());
+ boolean runStandaloneZooKeeper = admin.multitenant(); // When multitenant we'll not run on config servers so we need to add a Zk instance
+ clusterControllers = createClusterControllers(admin, hosts, "cluster-controllers", runStandaloneZooKeeper, context.getDeployState());
admin.setClusterControllers(clusterControllers);
}
}
@@ -334,21 +316,6 @@ public class ContentCluster extends AbstractConfigProducer implements
}
}
- /** Returns any other content cluster which shares nodes with this, or null if none are built */
- private ContentCluster findOverlappingCluster(AbstractConfigProducerRoot root, ContentCluster contentCluster) {
- for (ContentCluster otherContentCluster : root.getChildrenByTypeRecursive(ContentCluster.class)) {
- if (otherContentCluster != contentCluster && overlaps(contentCluster, otherContentCluster))
- return otherContentCluster;
- }
- return null;
- }
-
- private boolean overlaps(ContentCluster c1, ContentCluster c2) {
- Set<HostResource> c1Hosts = c1.getRootGroup().recursiveGetNodes().stream().map(StorageNode::getHostResource).collect(Collectors.toSet());
- Set<HostResource> c2Hosts = c2.getRootGroup().recursiveGetNodes().stream().map(StorageNode::getHostResource).collect(Collectors.toSet());
- return ! Sets.intersection(c1Hosts, c2Hosts).isEmpty();
- }
-
public static final NodeResources clusterControllerResources = new NodeResources(0.5, 2, 10, 0.3, NodeResources.DiskSpeed.any, NodeResources.StorageType.any);
private ClusterControllerContainerCluster getDedicatedSharedControllers(ModelElement contentElement, Admin admin,
@@ -375,65 +342,19 @@ public class ContentCluster extends AbstractConfigProducer implements
return admin.getClusterControllers();
}
- private List<HostResource> drawControllerHosts(int count, StorageGroup rootGroup) {
- List<HostResource> hosts = drawControllerHosts(count, false, rootGroup);
- List<HostResource> retiredHosts = drawControllerHosts(count, true, rootGroup);
-
- // preserve the cluster state in case all pre-existing controllers are on retired nodes
- List<HostResource> all = new ArrayList<>(hosts);
- all.addAll(retiredHosts);
- return all;
- }
-
- private List<HostResource> drawControllerHosts(int count, boolean retired, StorageGroup rootGroup) {
- List<HostResource> hosts = drawContentHostsRecursively(count, retired, rootGroup);
- if (hosts.size() % 2 == 0 && ! hosts.isEmpty()) // ZK clusters of even sizes are less available (even in the size=2 case)
- hosts = hosts.subList(0, hosts.size()-1);
- return hosts;
- }
-
- /**
- * Draw <code>count</code> nodes from as many different content groups below this as possible.
- * This will only achieve maximum spread in the case where the groups are balanced and never on the same
- * physical node. It will not achieve maximum spread over all levels in a multilevel group hierarchy.
- */
- // Note: This method cannot be changed to draw different nodes without ensuring that it will draw nodes
- // which overlaps with previously drawn nodes as that will prevent rolling upgrade
- private List<HostResource> drawContentHostsRecursively(int count, boolean retired, StorageGroup group) {
- Set<HostResource> hosts = new HashSet<>();
- if (group.getNodes().isEmpty()) {
- int hostsPerSubgroup = (int)Math.ceil((double)count / group.getSubgroups().size());
- for (StorageGroup subgroup : group.getSubgroups())
- hosts.addAll(drawContentHostsRecursively(hostsPerSubgroup, retired, subgroup));
- }
- else {
- hosts.addAll(group.getNodes().stream()
- .filter(node -> node.isRetired() == retired)
- .map(StorageNode::getHostResource).collect(toList()));
- }
-
- List<HostResource> sortedHosts = new ArrayList<>(hosts);
- sortedHosts.sort(HostResource::comparePrimarilyByIndexTo);
- sortedHosts = sortedHosts.subList(0, Math.min(count, hosts.size()));
- return sortedHosts;
- }
-
private ClusterControllerContainerCluster createClusterControllers(AbstractConfigProducer<?> parent,
Collection<HostResource> hosts,
String name,
- boolean multitenant,
+ boolean runStandaloneZooKeeper,
DeployState deployState) {
var clusterControllers = new ClusterControllerContainerCluster(parent, name, name, deployState);
List<ClusterControllerContainer> containers = new ArrayList<>();
- // Add a cluster controller on each config server (there is always at least one).
if (clusterControllers.getContainers().isEmpty()) {
int index = 0;
for (HostResource host : hosts) {
- int ccIndex = deployState.getProperties().dedicatedClusterControllerCluster()
- ? host.spec().membership().map(ClusterMembership::index).orElse(index)
- : index;
+ int ccIndex = host.spec().membership().map(ClusterMembership::index).orElse(index);
boolean retired = host.spec().membership().map(ClusterMembership::retired).orElse(false);
- var clusterControllerContainer = new ClusterControllerContainer(clusterControllers, ccIndex, multitenant, deployState, retired);
+ var clusterControllerContainer = new ClusterControllerContainer(clusterControllers, ccIndex, runStandaloneZooKeeper, deployState, retired);
clusterControllerContainer.setHostResource(host);
clusterControllerContainer.initService(deployState.getDeployLogger());
clusterControllerContainer.setProp("clustertype", "admin");
@@ -511,11 +432,7 @@ public class ContentCluster extends AbstractConfigProducer implements
public PersistenceEngine.PersistenceFactory getPersistence() { return persistenceFactory; }
- /**
- * The list of documentdefinitions declared at the cluster level.
- *
- * @return the set of documenttype names
- */
+ /** Returns a list of th document types declared at the cluster level. */
public Map<String, NewDocumentType> getDocumentDefinitions() { return documentDefinitions; }
public boolean isGloballyDistributed(NewDocumentType docType) {
@@ -753,6 +670,7 @@ public class ContentCluster extends AbstractConfigProducer implements
* a previous generation of it only by restarting the consuming processes.
*/
public void setDeferChangesUntilRestart(boolean deferChangesUntilRestart) {
+ // TODO
}
}
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 c6ddc6b0c36..86668fe3098 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
@@ -264,8 +264,7 @@ public class ModelProvisioningTest {
" </content>" +
"</services>";
VespaModelTester tester = new VespaModelTester();
- tester.dedicatedClusterControllerCluster(false);
- tester.addHosts(2);
+ tester.addHosts(5);
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());
@@ -330,8 +329,7 @@ public class ModelProvisioningTest {
" </content>" +
"</services>";
VespaModelTester tester = new VespaModelTester();
- tester.dedicatedClusterControllerCluster(false);
- tester.addHosts(2);
+ tester.addHosts(5);
VespaModel model = tester.createModel(xmlWithNodes, true);
assertEquals("Nodes in content1", 2, model.getContentClusters().get("content1").getRootGroup().getNodes().size());
@@ -583,9 +581,8 @@ public class ModelProvisioningTest {
" </content>" +
"</services>";
- int numberOfHosts = 64;
+ int numberOfHosts = 67;
VespaModelTester tester = new VespaModelTester();
- tester.dedicatedClusterControllerCluster(false);
tester.addHosts(numberOfHosts);
VespaModel model = tester.createModel(services, true);
assertEquals(numberOfHosts, model.getRoot().hostSystem().getHosts().size());
@@ -604,23 +601,17 @@ public class ModelProvisioningTest {
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("No admin cluster controller when multitenant", null, admin.getClusterControllers());
+ assertEquals(3, admin.getClusterControllers().getContainers().size());
// Check content clusters
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-54", clusterControllers.getContainers().get(0).getHostName());
- assertEquals("node-1-3-10-51", clusterControllers.getContainers().get(1).getHostName());
- assertEquals("node-1-3-10-48", clusterControllers.getContainers().get(2).getHostName());
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-54", cluster.getRootGroup().getSubgroups().get(0).getNodes().get(0).getHostName());
+ 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));
@@ -629,13 +620,13 @@ public class ModelProvisioningTest {
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-51", cluster.getRootGroup().getSubgroups().get(1).getNodes().get(0).getHostName());
+ 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-48", cluster.getRootGroup().getSubgroups().get(2).getNodes().get(0).getHostName());
+ 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));
@@ -647,12 +638,6 @@ public class ModelProvisioningTest {
assertThat(cluster.getRootGroup().getSubgroups().get(8).getNodes().get(2).getConfigId(), is("bar/storage/26"));
cluster = model.getContentClusters().get("baz");
- clusterControllers = cluster.getClusterControllers();
- assertEquals(3, clusterControllers.getContainers().size());
- assertEquals("baz-controllers", clusterControllers.getName());
- assertEquals("node-1-3-10-27", clusterControllers.getContainers().get(0).getHostName());
- assertEquals("node-1-3-10-26", clusterControllers.getContainers().get(1).getHostName());
- assertEquals("node-1-3-10-25", clusterControllers.getContainers().get(2).getHostName());
assertEquals(0, cluster.getRootGroup().getNodes().size());
assertEquals(27, cluster.getRootGroup().getSubgroups().size());
assertThat(cluster.getRootGroup().getSubgroups().get(0).getIndex(), is("0"));
@@ -732,41 +717,6 @@ public class ModelProvisioningTest {
}
@Test
- public void testClusterControllersWithGroupSize2() {
- 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='8' groups='4'/>" +
- " </content>" +
- "</services>";
-
- 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));
-
- // Check content clusters
- ContentCluster cluster = model.getContentClusters().get("bar");
- ClusterControllerContainerCluster clusterControllers = cluster.getClusterControllers();
- assertEquals("We get the closest odd number", 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-06", clusterControllers.getContainers().get(1).getHostName());
- assertEquals("node-1-3-10-04", clusterControllers.getContainers().get(2).getHostName());
- }
-
- @Test
public void testSlobroksClustersAreExpandedToIncludeRetiredNodes() {
String services =
"<?xml version='1.0' encoding='utf-8' ?>\n" +
@@ -850,32 +800,6 @@ public class ModelProvisioningTest {
}
@Test
- public void test2ContentNodesProduces1ClusterController() {
- String services =
- "<?xml version='1.0' encoding='utf-8' ?>\n" +
- "<services>" +
- " <content version='1.0' id='bar'>" +
- " <redundancy>2</redundancy>" +
- " <documents>" +
- " <document type='type1' mode='index'/>" +
- " </documents>" +
- " <nodes count='2'/>" +
- " </content>" +
- "</services>";
-
- 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));
-
- ContentCluster cluster = model.getContentClusters().get("bar");
- ContainerCluster clusterControllers = cluster.getClusterControllers();
- assertEquals(1, clusterControllers.getContainers().size());
- }
-
- @Test
public void testDedicatedClusterControllers() {
String services =
"<?xml version='1.0' encoding='utf-8' ?>\n" +
@@ -1131,16 +1055,11 @@ 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));
ContentCluster cluster = model.getContentClusters().get("bar");
- ClusterControllerContainerCluster clusterControllers = cluster.getClusterControllers();
- assertEquals(1, clusterControllers.getContainers().size());
- assertEquals("bar-controllers", clusterControllers.getName());
- assertEquals("node-1-3-10-01", clusterControllers.getContainers().get(0).getHostName());
assertEquals(1, cluster.redundancy().effectiveInitialRedundancy()); // Reduced from 3*3
assertEquals(1, cluster.redundancy().effectiveFinalRedundancy()); // Reduced from 3*4
assertEquals(1, cluster.redundancy().effectiveReadyCopies()); // Reduced from 3*3
@@ -1295,14 +1214,14 @@ public class ModelProvisioningTest {
" </content>" +
"</services>";
- int totalHosts = 18;
+ int totalHosts = 21;
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
tester.addHosts(new NodeResources(8, 200, 1000000, 0.3), 5); // Content-foo
tester.addHosts(new NodeResources(10, 64, 200, 0.3), 6); // Content-bar
+ tester.addHosts(new NodeResources(0.5, 2, 10, 0.3), 6); // Cluster-controller
VespaModel model = tester.createModel(services, true, 0);
assertEquals(totalHosts, model.getRoot().hostSystem().getHosts().size());
}
@@ -1329,11 +1248,11 @@ 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);
+ tester.addHosts(new NodeResources(11.5, 10, 30, 0.3), 6);
+ tester.addHosts(new NodeResources(85, 200, 1000_000_000, 0.3), 20);
+ tester.addHosts(new NodeResources( 0.5, 2, 10, 0.3), 3);
VespaModel model = tester.createModel(services, true);
- assertEquals(totalHosts, model.getRoot().hostSystem().getHosts().size());
+ assertEquals(totalHosts + 3, model.getRoot().hostSystem().getHosts().size());
}
@Test
@@ -1356,11 +1275,11 @@ public class ModelProvisioningTest {
" </content>" +
"</services>";
- int totalHosts = 26;
+ int totalHosts = 29;
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);
+ tester.addHosts(new NodeResources(13.5, 100, 1000, 0.3), 6);
+ tester.addHosts(new NodeResources(85, 200, 1000_000_000, 0.3), 20);
+ tester.addHosts(new NodeResources( 0.5, 2, 10, 0.3), 3);
VespaModel model = tester.createModel(services, true, true);
assertEquals(totalHosts, model.getRoot().hostSystem().getHosts().size());
}
@@ -1581,10 +1500,9 @@ public class ModelProvisioningTest {
" </content>" +
"</services>";
VespaModelTester tester = new VespaModelTester();
- tester.dedicatedClusterControllerCluster(false);
- tester.addHosts(3);
+ tester.addHosts(6);
VespaModel model = tester.createModel(services, true);
- assertEquals(3, model.getRoot().hostSystem().getHosts().size());
+ assertEquals(6, model.getRoot().hostSystem().getHosts().size());
assertEquals(2, model.getAdmin().getSlobroks().size());
assertEquals(2, model.getContainerClusters().get("foo").getContainers().size());
assertEquals(1, model.getContentClusters().get("bar").getRootGroup().countNodes());
@@ -1699,7 +1617,7 @@ public class ModelProvisioningTest {
assertEquals(1, model.getRoot().hostSystem().getHosts().size());
ContentCluster content = model.getContentClusters().get("storage");
assertEquals(2, content.getRootGroup().getNodes().size());
- ContainerCluster controller = content.getClusterControllers();
+ ContainerCluster<?> controller = model.getAdmin().getClusterControllers();
assertEquals(1, controller.getContainers().size());
}
@@ -1745,7 +1663,7 @@ public class ModelProvisioningTest {
assertThat(model.getRoot().hostSystem().getHosts().size(), is(1));
ContentCluster content = model.getContentClusters().get("storage");
assertEquals(1, content.getRootGroup().getNodes().size());
- ContainerCluster controller = content.getClusterControllers();
+ ContainerCluster<?> controller = model.getAdmin().getClusterControllers();
assertEquals(1, controller.getContainers().size());
}
@@ -1854,10 +1772,10 @@ public class ModelProvisioningTest {
" </services>";
VespaModel model = createNonProvisionedMultitenantModel(services);
- assertThat(model.getRoot().hostSystem().getHosts().size(), is(1));
+ assertEquals(1, model.getRoot().hostSystem().getHosts().size());
ContentCluster content = model.getContentClusters().get("storage");
assertEquals(2, content.getRootGroup().getNodes().size());
- ContainerCluster controller = content.getClusterControllers();
+ ContainerCluster<?> controller = model.getAdmin().getClusterControllers();
assertEquals(1, controller.getContainers().size());
}
@@ -1882,8 +1800,7 @@ public class ModelProvisioningTest {
" </content>" +
"</services>";
VespaModelTester tester = new VespaModelTester();
- tester.dedicatedClusterControllerCluster(false);
- tester.addHosts(6);
+ tester.addHosts(9);
VespaModel model = tester.createModel(servicesXml, true);
Map<String, Boolean> tests = Map.of("qrs", false,
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 a11d23dbfbb..3f211a595b9 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
@@ -144,7 +144,7 @@ public class MetricsProxyContainerTest {
@Test
public void vespa_services_config_has_all_services() {
VespaServicesConfig vespaServicesConfig = getVespaServicesConfig(servicesWithContent());
- assertEquals(6, vespaServicesConfig.service().size());
+ assertEquals(7, vespaServicesConfig.service().size());
for (var service : vespaServicesConfig.service()) {
if (service.configId().equals("admin/cluster-controllers/0")) {
@@ -185,7 +185,7 @@ public class MetricsProxyContainerTest {
private static String servicesWithContent() {
return String.join("\n",
"<services>",
- " <admin version='4.0'>",
+ " <admin version='2.0'>",
" <adminserver hostalias='node1'/>",
" </admin>",
" <content version='1.0' id='my-content'>",
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/QuotaValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/QuotaValidatorTest.java
index 6ad74231cae..d92ace2939a 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/QuotaValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/QuotaValidatorTest.java
@@ -25,13 +25,13 @@ public class QuotaValidatorTest {
@Test
public void test_deploy_under_quota() {
- var tester = new ValidationTester(5, false, new TestProperties().setHostedVespa(true).setQuota(quota).setZone(publicZone));
+ var tester = new ValidationTester(8, false, new TestProperties().setHostedVespa(true).setQuota(quota).setZone(publicZone));
tester.deploy(null, getServices("testCluster", 5), Environment.prod, null);
}
@Test
public void test_deploy_above_quota_clustersize() {
- var tester = new ValidationTester(11, false, new TestProperties().setHostedVespa(true).setQuota(quota).setZone(publicZone));
+ var tester = new ValidationTester(14, false, new TestProperties().setHostedVespa(true).setQuota(quota).setZone(publicZone));
try {
tester.deploy(null, getServices("testCluster", 11), Environment.prod, null);
fail();
@@ -42,32 +42,32 @@ public class QuotaValidatorTest {
@Test
public void test_deploy_above_quota_budget() {
- var tester = new ValidationTester(10, false, new TestProperties().setHostedVespa(true).setQuota(quota).setZone(publicZone));
+ var tester = new ValidationTester(13, false, new TestProperties().setHostedVespa(true).setQuota(quota).setZone(publicZone));
try {
tester.deploy(null, getServices("testCluster", 10), Environment.prod, null);
fail();
} catch (RuntimeException e) {
assertEquals("Please free up some capacity! This deployment's quota use ($-.--) exceeds reserved quota ($-.--)!",
- ValidationTester.censorNumbers(e.getMessage()));
+ ValidationTester.censorNumbers(e.getMessage()));
}
}
@Test
public void test_deploy_above_quota_budget_in_publiccd() {
- var tester = new ValidationTester(10, false, new TestProperties().setHostedVespa(true).setQuota(quota).setZone(publicCdZone));
+ var tester = new ValidationTester(13, false, new TestProperties().setHostedVespa(true).setQuota(quota).setZone(publicCdZone));
try {
tester.deploy(null, getServices("testCluster", 10), Environment.prod, null);
fail();
} catch (RuntimeException e) {
assertEquals("publiccd: Please free up some capacity! This deployment's quota use ($-.--) exceeds reserved quota ($-.--)!",
- ValidationTester.censorNumbers(e.getMessage()));
+ ValidationTester.censorNumbers(e.getMessage()));
}
}
@Test
public void test_deploy_with_negative_budget() {
var quota = Quota.unlimited().withBudget(BigDecimal.valueOf(-1));
- var tester = new ValidationTester(10, false, new TestProperties().setHostedVespa(true).setQuota(quota).setZone(publicZone));
+ var tester = new ValidationTester(13, false, new TestProperties().setHostedVespa(true).setQuota(quota).setZone(publicZone));
try {
tester.deploy(null, getServices("testCluster", 10), Environment.prod, null);
fail();
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ValidationTester.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ValidationTester.java
index b7fa72d8a64..02f1195d50e 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ValidationTester.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ValidationTester.java
@@ -34,9 +34,9 @@ public class ValidationTester {
private final TestProperties properties;
private final InMemoryProvisioner hostProvisioner;
- /** Creates a validation tester with 1 node available */
+ /** Creates a validation tester with 1 node available (in addition to cluster controllers) */
public ValidationTester() {
- this(1);
+ this(4);
}
/** Creates a validation tester with number of nodes available and the given test properties */
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ClusterSizeReductionValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ClusterSizeReductionValidatorTest.java
index bade5a746f7..f90762e8fc0 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ClusterSizeReductionValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ClusterSizeReductionValidatorTest.java
@@ -19,7 +19,7 @@ public class ClusterSizeReductionValidatorTest {
@Test
public void testSizeReductionValidation() {
- ValidationTester tester = new ValidationTester(30);
+ ValidationTester tester = new ValidationTester(33);
VespaModel previous = tester.deploy(null, getServices(30), Environment.prod, null).getFirst();
try {
@@ -45,7 +45,7 @@ public class ClusterSizeReductionValidatorTest {
@Test
public void testOverridingSizereductionValidation() {
- ValidationTester tester = new ValidationTester(30);
+ ValidationTester tester = new ValidationTester(33);
VespaModel previous = tester.deploy(null, getServices(30), Environment.prod, null).getFirst();
tester.deploy(previous, getServices(14), Environment.prod, sizeReductionOverride); // Allowed due to override
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ContentClusterRemovalValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ContentClusterRemovalValidatorTest.java
index 392c37f50f3..30dab17635a 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ContentClusterRemovalValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ContentClusterRemovalValidatorTest.java
@@ -17,7 +17,7 @@ import static org.junit.Assert.fail;
*/
public class ContentClusterRemovalValidatorTest {
- private final ValidationTester tester = new ValidationTester(2);
+ private final ValidationTester tester = new ValidationTester(5);
@Test
public void testContentRemovalValidation() {
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 219afb14ea5..4aadc0e3f05 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
@@ -1021,26 +1021,17 @@ public class ContentClusterTest extends ContentBaseTest {
assertEquals(0.1, resolveMaxDeadBytesRatio(0.1), 1e-5);
}
- void assertZookeeperServerImplementation(String expectedClassName) {
- VespaModel model = createEnd2EndOneNode(new TestProperties().setMultitenant(true));
-
- ContentCluster cc = model.getContentClusters().get("storage");
- for (ClusterControllerContainer c : cc.getClusterControllers().getContainers()) {
+ void assertZookeeperServerImplementation(String expectedClassName,
+ ClusterControllerContainerCluster clusterControllerCluster) {
+ for (ClusterControllerContainer c : clusterControllerCluster.getContainers()) {
var builder = new ComponentsConfig.Builder();
c.getConfig(builder);
assertEquals(1, new ComponentsConfig(builder).components().stream()
- .filter(component -> component.classId().equals(expectedClassName))
- .count());
+ .filter(component -> component.classId().equals(expectedClassName))
+ .count());
}
}
- @Test
- public void reconfigurableZookeeperServerComponentsForClusterController() {
- assertZookeeperServerImplementation("com.yahoo.vespa.zookeeper.ReconfigurableVespaZooKeeperServer");
- assertZookeeperServerImplementation("com.yahoo.vespa.zookeeper.Reconfigurer");
- assertZookeeperServerImplementation("com.yahoo.vespa.zookeeper.VespaZooKeeperAdminImpl");
- }
-
private StorDistributormanagerConfig resolveStorDistributormanagerConfig(TestProperties props) {
VespaModel model = createEnd2EndOneNode(props);
@@ -1137,17 +1128,7 @@ public class ContentClusterTest extends ContentBaseTest {
assertNull("No own cluster controller for content", twoContentModel.getContentClusters().get("dev-null").getClusterControllers());
assertNotNull("Shared cluster controller with content", twoContentModel.getAdmin().getClusterControllers());
- Map<String, ContentCluster> clustersWithOwnCCC = createEnd2EndOneNode(new TestProperties().setMultitenant(true), twoContentServices).getContentClusters();
ClusterControllerContainerCluster clusterControllers = twoContentModel.getAdmin().getClusterControllers();
- assertEquals("Union of components in own clusters is equal to those in shared cluster",
- clusterControllers.getAllComponents().stream()
- .map(Component::getComponentId)
- .collect(toList()),
- clustersWithOwnCCC.values().stream()
- .flatMap(cluster -> Optional.ofNullable(cluster.getClusterControllers()).stream()
- .flatMap(c -> c.getAllComponents().stream()))
- .map(Component::getComponentId)
- .collect(toList()));
assertEquals(1, clusterControllers.reindexingContext().documentTypesForCluster("storage").size());
assertEquals(1, clusterControllers.reindexingContext().documentTypesForCluster("dev-null").size());
@@ -1157,6 +1138,13 @@ public class ContentClusterTest extends ContentBaseTest {
twoContentModel.getConfig(devNullBuilder, "admin/standalone/cluster-controllers/0/components/clustercontroller-dev-null-configurer");
assertEquals(0.618, storageBuilder.build().min_distributor_up_ratio(), 1e-9);
assertEquals(0.418, devNullBuilder.build().min_distributor_up_ratio(), 1e-9);
+
+ assertZookeeperServerImplementation("com.yahoo.vespa.zookeeper.ReconfigurableVespaZooKeeperServer",
+ clusterControllers);
+ assertZookeeperServerImplementation("com.yahoo.vespa.zookeeper.Reconfigurer",
+ clusterControllers);
+ assertZookeeperServerImplementation("com.yahoo.vespa.zookeeper.VespaZooKeeperAdminImpl",
+ clusterControllers);
}
}
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 eafbca09009..b72ae088484 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,6 @@ public class VespaModelTester {
private final Map<NodeResources, Collection<Host>> hostsByResources = new HashMap<>();
private ApplicationId applicationId = ApplicationId.defaultId();
private boolean useDedicatedNodeForLogserver = false;
- private boolean dedicatedClusterControllerCluster = true;
public VespaModelTester() {
this(new NullConfigModelRegistry());
@@ -102,10 +101,6 @@ public class VespaModelTester {
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);
@@ -175,8 +170,7 @@ public class VespaModelTester {
.setMultitenant(true)
.setHostedVespa(hosted)
.setApplicationId(applicationId)
- .setUseDedicatedNodeForLogserver(useDedicatedNodeForLogserver)
- .setDedicatedClusterControllerCluster(dedicatedClusterControllerCluster);
+ .setUseDedicatedNodeForLogserver(useDedicatedNodeForLogserver);
DeployState.Builder deployState = deployStatebuilder
.applicationPackage(appPkg)