aboutsummaryrefslogtreecommitdiffstats
path: root/config-model
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-08-09 09:11:40 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-08-09 09:11:40 +0200
commit7ab8fbed3c33d32f76946562b4e2a833db988d96 (patch)
tree256501e6630208d0b1356f700354f842e96cad26 /config-model
parent811cb1a5f7763820d1c92ce728d46e67cc31e3f6 (diff)
Cluster node references
Diffstat (limited to 'config-model')
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/Affinity.java2
-rwxr-xr-xconfig-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java97
-rw-r--r--config-model/src/main/resources/schema/container.rnc2
-rw-r--r--config-model/src/main/resources/schema/containercluster.rnc2
-rw-r--r--config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java60
-rw-r--r--config-model/src/test/schema-test-files/services-hosted.xml6
7 files changed, 124 insertions, 47 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/Affinity.java b/config-model/src/main/java/com/yahoo/vespa/model/Affinity.java
index d621c299a5d..cadaf4b6246 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/Affinity.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/Affinity.java
@@ -9,6 +9,7 @@ package com.yahoo.vespa.model;
* @since 5.12
*/
public class Affinity {
+
private final int cpuSocket;
private Affinity(int cpuSocket) {
@@ -34,4 +35,5 @@ public class Affinity {
return new Affinity(cpuSocket);
}
}
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
index ae158567587..0a6384e18f4 100755
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
@@ -350,7 +350,7 @@ public final class ContainerCluster
for (Container container : containers) {
container.setClusterName(name);
container.setProp("clustername", name)
- .setProp("index", index++);
+ .setProp("index", index++);
setRotations(container, getRotations(), getGlobalServiceId(), name);
container.setProp("activeRotation", Boolean.toString(getActiveRotation()));
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
index 4240ea40ebb..f549e535418 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
@@ -51,6 +51,7 @@ import com.yahoo.vespa.model.container.search.SemanticRules;
import com.yahoo.vespa.model.container.search.searchchain.SearchChains;
import com.yahoo.vespa.model.container.xml.document.DocumentFactoryBuilder;
+import com.yahoo.vespa.model.content.cluster.ContentCluster;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -383,30 +384,25 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
cluster.addContainers(Collections.singleton(container));
}
else {
- String defaultJvmArgs = nodesElement.getAttribute(VespaDomBuilder.JVMARGS_ATTRIB_NAME);
- String defaultPreLoad = null;
- if (nodesElement.hasAttribute(VespaDomBuilder.PRELOAD_ATTRIB_NAME)) {
- defaultPreLoad = nodesElement.getAttribute(VespaDomBuilder.PRELOAD_ATTRIB_NAME);
- }
- boolean useCpuSocketAffinity = false;
- if (nodesElement.hasAttribute(VespaDomBuilder.CPU_SOCKET_AFFINITY_ATTRIB_NAME)) {
- useCpuSocketAffinity = Boolean.parseBoolean(nodesElement.getAttribute(VespaDomBuilder.CPU_SOCKET_AFFINITY_ATTRIB_NAME));
- }
- List<Container> result = new ArrayList<>();
- result.addAll(createNodesFromXmlNodeCount(cluster, nodesElement));
- addNodesFromXmlNodeList(cluster, spec, nodesElement, result);
- applyDefaultJvmArgs(result, defaultJvmArgs);
- applyRoutingAliasProperties(result, cluster);
- if (defaultPreLoad != null) {
- applyDefaultPreload(result, defaultPreLoad);
- }
- if (useCpuSocketAffinity) {
- AbstractService.distributeCpuSocketAffinity(result);
- }
+ List<Container> nodes = createNodes(cluster, nodesElement);
+ applyDefaultJvmArgs(nodes, nodesElement.getAttribute(VespaDomBuilder.JVMARGS_ATTRIB_NAME));
+ applyRoutingAliasProperties(nodes, cluster);
+ applyDefaultPreload(nodes, nodesElement);
+ if (useCpuSocketAffinity(nodesElement))
+ AbstractService.distributeCpuSocketAffinity(nodes);
- cluster.addContainers(result);
+ cluster.addContainers(nodes);
}
}
+
+ private List<Container> createNodes(ContainerCluster cluster, Element nodesElement) {
+ if (nodesElement.hasAttribute("count"))
+ return createNodesFromNodeCount(cluster, nodesElement);
+ else if (nodesElement.hasAttribute("of"))
+ return createNodesFromClusterReference(cluster, nodesElement);
+ else // the non-hosted option
+ return createNodesFromNodeList(cluster, nodesElement);
+ }
private void applyRoutingAliasProperties(List<Container> result, ContainerCluster cluster) {
if (!cluster.serviceAliases().isEmpty()) {
@@ -430,30 +426,43 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
}
}
- private void addNodesFromXmlNodeList(ContainerCluster cluster,
- Element spec, Element nodesElement, List<Container> result) {
+ private List<Container> createNodesFromNodeCount(ContainerCluster cluster, Element nodesElement) {
+ List<Container> nodes = new ArrayList<>();
+ NodesSpecification nodesSpecification = NodesSpecification.from(new ModelElement(nodesElement));
+ Map<HostResource, ClusterMembership> hosts = nodesSpecification.provision(cluster.getRoot().getHostSystem(), ClusterSpec.Type.container, ClusterSpec.Id.from(cluster.getName()), Optional.empty(), log);
+ for (Map.Entry<HostResource, ClusterMembership> entry : hosts.entrySet()) {
+ String id = "container." + entry.getValue().index();
+ Container container = new Container(cluster, id, entry.getValue().retired(), entry.getValue().index());
+ container.setHostResource(entry.getKey());
+ container.initService();
+ nodes.add(container);
+ }
+ return nodes;
+ }
+
+ private List<Container> createNodesFromClusterReference(ContainerCluster cluster, Element nodesElement) {
+ List<Container> nodes = new ArrayList<>();
+ String clusterReferenceId = nodesElement.getAttribute("of");
+ // TODO
+ return nodes;
+ }
+
+ private List<Container> createNodesFromNodeList(ContainerCluster cluster, Element nodesElement) {
+ List<Container> nodes = new ArrayList<>();
int nodeCount = 0;
for (Element nodeElem: XML.getChildren(nodesElement, "node")) {
Container container = new ContainerServiceBuilder("container." + nodeCount, nodeCount).build(cluster, nodeElem);
- result.add(container);
- ++nodeCount;
+ nodes.add(container);
+ nodeCount++;
}
+ return nodes;
}
-
- private List<Container> createNodesFromXmlNodeCount(ContainerCluster cluster, Element nodesElement) {
- List<Container> result = new ArrayList<>();
- if (nodesElement.hasAttribute("count")) {
- NodesSpecification nodesSpecification = NodesSpecification.from(new ModelElement(nodesElement));
- Map<HostResource, ClusterMembership> hosts = nodesSpecification.provision(cluster.getRoot().getHostSystem(), ClusterSpec.Type.container, ClusterSpec.Id.from(cluster.getName()), Optional.empty(), log);
- for (Map.Entry<HostResource, ClusterMembership> entry : hosts.entrySet()) {
- String id = "container." + entry.getValue().index();
- Container container = new Container(cluster, id, entry.getValue().retired(), entry.getValue().index());
- container.setHostResource(entry.getKey());
- container.initService();
- result.add(container);
- }
- }
- return result;
+
+ private boolean useCpuSocketAffinity(Element nodesElement) {
+ if (nodesElement.hasAttribute(VespaDomBuilder.CPU_SOCKET_AFFINITY_ATTRIB_NAME))
+ return Boolean.parseBoolean(nodesElement.getAttribute(VespaDomBuilder.CPU_SOCKET_AFFINITY_ATTRIB_NAME));
+ else
+ return false;
}
private void applyDefaultJvmArgs(List<Container> containers, String defaultJvmArgs) {
@@ -463,10 +472,10 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
}
}
- private void applyDefaultPreload(List<Container> containers, String defaultPreLoad) {
- for (Container container: containers) {
- container.setPreLoad(defaultPreLoad);
- }
+ private void applyDefaultPreload(List<Container> containers, Element nodesElement) {
+ if (! nodesElement.hasAttribute(VespaDomBuilder.PRELOAD_ATTRIB_NAME)) return;
+ for (Container container: containers)
+ container.setPreLoad(nodesElement.getAttribute(VespaDomBuilder.PRELOAD_ATTRIB_NAME));
}
private void addSearchHandler(ContainerCluster cluster, Element searchElement) {
diff --git a/config-model/src/main/resources/schema/container.rnc b/config-model/src/main/resources/schema/container.rnc
index 7168e05ba0b..b5ee1d0b834 100644
--- a/config-model/src/main/resources/schema/container.rnc
+++ b/config-model/src/main/resources/schema/container.rnc
@@ -1,5 +1,5 @@
# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#Schema for common container options
+# Schema for common container options
include "processing.rnc"
diff --git a/config-model/src/main/resources/schema/containercluster.rnc b/config-model/src/main/resources/schema/containercluster.rnc
index c9dd2c0239d..287fd9f459e 100644
--- a/config-model/src/main/resources/schema/containercluster.rnc
+++ b/config-model/src/main/resources/schema/containercluster.rnc
@@ -186,6 +186,8 @@ NodesOfContainerCluster = element nodes {
attribute preload { text }? &
attribute cpu-socket-affinity { xsd:boolean }? &
(
+ attribute of { xsd:string }
+ |
(
attribute count { xsd:positiveInteger } &
attribute flavor { xsd:string }? &
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 b66cb25e18a..09e2fcebd60 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
@@ -147,6 +147,66 @@ public class ModelProvisioningTest {
}
@Test
+ public void testCombinedCluster() {
+ String xmlWithNodes =
+ "<?xml version='1.0' encoding='utf-8' ?>" +
+ "<services>" +
+ " <container version='1.0' id='container1'>" +
+ " <nodes of='content1'/>" +
+ " </container>" +
+ " <content version='1.0' id='content1'>" +
+ " <redundancy>2</redundancy>" +
+ " <documents>" +
+ " <document type='type1' mode='index'/>" +
+ " </documents>" +
+ " <nodes count='2'/>" +
+ " </content>" +
+ "</services>";
+ VespaModelTester tester = new VespaModelTester();
+ tester.addHosts(2);
+ 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());
+ }
+
+ @Test
+ public void testMultipleCombinedClusters() {
+ String xmlWithNodes =
+ "<?xml version='1.0' encoding='utf-8' ?>" +
+ "<services>" +
+ " <container version='1.0' id='container1'>" +
+ " <nodes of='content1'/>" +
+ " </container>" +
+ " <container version='1.0' id='container2'>" +
+ " <nodes of='content2'/>" +
+ " </container>" +
+ " <content version='1.0' id='content1'>" +
+ " <redundancy>2</redundancy>" +
+ " <documents>" +
+ " <document type='type1' mode='index'/>" +
+ " </documents>" +
+ " <nodes count='2'/>" +
+ " </content>" +
+ " <content version='1.0' id='content2'>" +
+ " <redundancy>2</redundancy>" +
+ " <documents>" +
+ " <document type='type1' mode='index'/>" +
+ " </documents>" +
+ " <nodes count='3'/>" +
+ " </content>" +
+ "</services>";
+ VespaModelTester tester = new VespaModelTester();
+ 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());
+ assertEquals("Nodes in content2", 3, model.getContentClusters().get("content2").getRootGroup().getNodes().size());
+ assertEquals("Nodes in container2", 3, model.getContainerClusters().get("container2").getContainers().size());
+ }
+
+ @Test
public void testNodeCountForContentGroupHierarchy() {
String services =
"<?xml version='1.0' encoding='utf-8' ?>\n" +
diff --git a/config-model/src/test/schema-test-files/services-hosted.xml b/config-model/src/test/schema-test-files/services-hosted.xml
index 1b3dad46462..f85a5352d23 100644
--- a/config-model/src/test/schema-test-files/services-hosted.xml
+++ b/config-model/src/test/schema-test-files/services-hosted.xml
@@ -6,9 +6,13 @@
<nodes count="3" flavor="small"/>
</admin>
- <jdisc id="container" version="1.0">
+ <jdisc id="container1" version="1.0">
<nodes count="5" flavor="medium"/>
</jdisc>
+
+ <container id="container2" version="1.0">
+ <nodes of="search"/>
+ </container>
<content id="search" version="1.0">
<redundancy>2</redundancy>