summaryrefslogtreecommitdiffstats
path: root/config-model/src
diff options
context:
space:
mode:
Diffstat (limited to 'config-model/src')
-rw-r--r--config-model/src/main/Makefile8
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/ApplicationConfigProducerRoot.java1
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/producer/AbstractConfigProducer.java8
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java7
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/provision/SingleNodeProvisioner.java5
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java10
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/test/MockRoot.java2
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/Search.java1
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/derived/IndexInfo.java2
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/document/Stemming.java25
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/Client.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/ConfigProducer.java39
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/HostSystem.java16
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/PlainFormatter.java28
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/PortsMeta.java3
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java45
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java10
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java5
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/Configserver.java3
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/builder/VespaModelBuilder.java1
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomClientsBuilder.java1
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomV20ClientsBuilder.java229
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java15
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/clients/ContainerDocumentApi.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java6
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/DocumentApiOptionsBuilder.java4
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/content/ContentSearchCluster.java5
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/content/Redundancy.java12
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java4
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/filedistribution/FileDistributionConfigProducer.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/filedistribution/FileDistributor.java1
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/utils/FileSender.java5
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/utils/FreezableMap.java4
-rw-r--r--config-model/src/main/resources/schema/common.rnc1
-rw-r--r--config-model/src/main/resources/schema/containercluster.rnc3
-rw-r--r--config-model/src/main/resources/schema/content.rnc2
-rw-r--r--config-model/src/main/resources/schema/deployment.rnc26
-rw-r--r--config-model/src/main/resources/schema/schemas.xml1
-rw-r--r--config-model/src/test/cfg/application/app1/deployment.xml8
-rw-r--r--config-model/src/test/cfg/application/app_invalid_deployment_xml/deployment.xml8
-rw-r--r--config-model/src/test/cfg/application/app_invalid_deployment_xml/hosts.xml9
-rw-r--r--config-model/src/test/cfg/application/app_invalid_deployment_xml/services.xml15
-rw-r--r--config-model/src/test/cfg/application/empty_prod_region_in_deployment_xml/deployment.xml5
-rw-r--r--config-model/src/test/cfg/application/empty_prod_region_in_deployment_xml/hosts.xml9
-rw-r--r--config-model/src/test/cfg/application/empty_prod_region_in_deployment_xml/services.xml15
-rw-r--r--config-model/src/test/java/com/yahoo/config/model/ApplicationDeployTest.java23
-rw-r--r--config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java21
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ContainerRestartValidatorTest.java8
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/content/ClusterTest.java613
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/test/utils/VespaModelCreatorWithMockPkg.java9
50 files changed, 671 insertions, 616 deletions
diff --git a/config-model/src/main/Makefile b/config-model/src/main/Makefile
index 5e7024ccff9..c3dfd0c2e3e 100644
--- a/config-model/src/main/Makefile
+++ b/config-model/src/main/Makefile
@@ -3,7 +3,7 @@
trangjar=../../target/trang.jar
-all: resources/schema/services.rng resources/schema/hosts.rng resources/schema/container-include.rng resources/schema/services.xsd resources/schema/hosts.xsd resources/schema/container-include.xsd
+all: resources/schema/services.rng resources/schema/hosts.rng resources/schema/container-include.rng resources/schema/services.xsd resources/schema/hosts.xsd resources/schema/container-include.xsd resources/schema/deployment.xsd
resources/schema/services.rng: resources/schema/services.rnc resources/schema/common.rnc resources/schema/admin.rnc resources/schema/clients.rnc resources/schema/docproc.rnc resources/schema/routing.rnc resources/schema/clients-v2.rnc resources/schema/content.rnc resources/schema/genericmodule.rnc resources/schema/legacygenericcluster.rnc resources/schema/genericcluster.rnc resources/schema/legacygenericmodule.rnc resources/schema/containercluster.rnc
java -jar $(trangjar) -I rnc -O rng resources/schema/services.rnc resources/schema/services.rng
@@ -25,6 +25,12 @@ resources/schema/hosts.rng: resources/schema/hosts.rnc
resources/schema/hosts.xsd: resources/schema/hosts.rng
java -jar $(trangjar) -I rng -O xsd resources/schema/hosts.rng resources/schema/hosts.xsd
+resources/schema/deployment.rng: resources/schema/deployment.rnc
+ java -jar $(trangjar) -I rnc -O rng resources/schema/deployment.rnc resources/schema/deployment.rng
+
+resources/schema/deployment.xsd: resources/schema/deployment.rng
+ java -jar $(trangjar) -I rng -O xsd resources/schema/deployment.rng resources/schema/deployment.xsd
+
clean:
rm -f resources/schema/*.rng
rm -f resources/schema/*.xsd
diff --git a/config-model/src/main/java/com/yahoo/config/model/ApplicationConfigProducerRoot.java b/config-model/src/main/java/com/yahoo/config/model/ApplicationConfigProducerRoot.java
index e6df94c8855..0b0ac77443c 100644
--- a/config-model/src/main/java/com/yahoo/config/model/ApplicationConfigProducerRoot.java
+++ b/config-model/src/main/java/com/yahoo/config/model/ApplicationConfigProducerRoot.java
@@ -265,6 +265,7 @@ public class ApplicationConfigProducerRoot extends AbstractConfigProducer<Abstra
}
public FileDistributionConfigProducer getFileDistributionConfigProducer() {
+ if (admin == null) return null; // no admin if standalone
return admin.getFileDistributionConfigProducer();
}
diff --git a/config-model/src/main/java/com/yahoo/config/model/producer/AbstractConfigProducer.java b/config-model/src/main/java/com/yahoo/config/model/producer/AbstractConfigProducer.java
index 8e1097907f1..8778107cd8a 100644
--- a/config-model/src/main/java/com/yahoo/config/model/producer/AbstractConfigProducer.java
+++ b/config-model/src/main/java/com/yahoo/config/model/producer/AbstractConfigProducer.java
@@ -105,10 +105,10 @@ public abstract class AbstractConfigProducer<CHILD extends AbstractConfigProduce
child.setParent(this);
if (childrenBySubId.get(child.getSubId()) != null) {
throw new IllegalArgumentException("Multiple services/instances of the id '" + child.getSubId() + "' under the service/instance " +
- errorMsgClassName() + " '" + subId + "'. (This is commonly caused by service/node index " +
- "collisions in the config.)." +
- "\nExisting instance: " + childrenBySubId.get(child.getSubId()) +
- "\nAttempted to add: " + child);
+ errorMsgClassName() + " '" + subId + "'. (This is commonly caused by service/node index " +
+ "collisions in the config.)." +
+ "\nExisting instance: " + childrenBySubId.get(child.getSubId()) +
+ "\nAttempted to add: " + child);
}
childrenBySubId.put(child.getSubId(), child);
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 5c9d03b434f..c4ac4d91001 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
@@ -101,8 +101,9 @@ public class InMemoryProvisioner implements HostProvisioner {
throw new IllegalArgumentException("Requested " + requestedCapacity.nodeCount() + " nodes in " +
groups + " groups, but the node count is not divisible into this number of groups");
- int capacity = failOnOutOfCapacity ? requestedCapacity.nodeCount() :
- Math.min(requestedCapacity.nodeCount(), freeNodes.get("default").size() + totalAllocatedTo(cluster));
+ int capacity = failOnOutOfCapacity || requestedCapacity.isRequired()
+ ? requestedCapacity.nodeCount()
+ : Math.min(requestedCapacity.nodeCount(), freeNodes.get("default").size() + totalAllocatedTo(cluster));
if (groups > capacity)
groups = capacity;
@@ -138,7 +139,7 @@ public class InMemoryProvisioner implements HostProvisioner {
int nextIndex = nextIndexInCluster.getOrDefault(new Pair<>(clusterGroup.type(), clusterGroup.id()), startIndex);
while (allocation.size() < nodesInGroup) {
- if (freeNodes.get(flavor).isEmpty()) throw new IllegalArgumentException("No nodes of flavor '" + flavor + "' available");
+ if (freeNodes.get(flavor).isEmpty()) throw new IllegalArgumentException("Insufficient capacity of flavor '" + flavor + "'");
Host newHost = freeNodes.removeValue(flavor, 0);
ClusterMembership membership = ClusterMembership.from(clusterGroup, nextIndex++);
allocation.add(new HostSpec(newHost.hostname(), newHost.aliases(), membership));
diff --git a/config-model/src/main/java/com/yahoo/config/model/provision/SingleNodeProvisioner.java b/config-model/src/main/java/com/yahoo/config/model/provision/SingleNodeProvisioner.java
index 1d5544873d9..fe8b3935fcf 100644
--- a/config-model/src/main/java/com/yahoo/config/model/provision/SingleNodeProvisioner.java
+++ b/config-model/src/main/java/com/yahoo/config/model/provision/SingleNodeProvisioner.java
@@ -27,10 +27,11 @@ public class SingleNodeProvisioner implements HostProvisioner {
public SingleNodeProvisioner() {
try {
host = new Host(HostSystem.lookupCanonicalHostname(HostName.getLocalhost()));
- } catch (UnknownHostException e) {
+ this.hostSpec = new HostSpec(host.hostname(), host.aliases());
+ }
+ catch (UnknownHostException e) {
throw new RuntimeException(e);
}
- this.hostSpec = new HostSpec(host.hostname(), host.aliases());
}
@Override
diff --git a/config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java b/config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java
index 731410c9bf3..c30c62b44bc 100644
--- a/config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java
+++ b/config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java
@@ -232,6 +232,16 @@ public class MockApplicationPackage implements ApplicationPackage {
" </host>" +
"</hosts>";
+
+ @Override
+ public void validateXML() throws IOException {
+ if (failOnValidateXml) {
+ throw new IllegalArgumentException("Error in application package");
+ } else {
+ throw new UnsupportedOperationException("This application package cannot validate XML");
+ }
+ }
+
@Override
public void validateXML(DeployLogger logger) throws IOException {
if (failOnValidateXml) {
diff --git a/config-model/src/main/java/com/yahoo/config/model/test/MockRoot.java b/config-model/src/main/java/com/yahoo/config/model/test/MockRoot.java
index fa84cf1c7eb..314060e7543 100644
--- a/config-model/src/main/java/com/yahoo/config/model/test/MockRoot.java
+++ b/config-model/src/main/java/com/yahoo/config/model/test/MockRoot.java
@@ -35,7 +35,9 @@ import java.util.Set;
*
* @author gjoranv
*/
+// TODO: mockRoot instances can probably be replaced by VespaModel.createIncomplete
public class MockRoot extends AbstractConfigProducerRoot {
+
private static final long serialVersionUID = 1L;
public static final String MOCKHOST = "mockhost";
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/Search.java b/config-model/src/main/java/com/yahoo/searchdefinition/Search.java
index 2ab634801c2..9032f913d0b 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/Search.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/Search.java
@@ -51,6 +51,7 @@ public class Search implements Serializable {
private boolean documentsOnly = false;
// The stemming setting of this search definition. Default is SHORTEST.
+ // TODO: Change to Stemming.BEST on Vespa 7
private Stemming stemming = Stemming.SHORTEST;
// Documents contained in this definition.
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/derived/IndexInfo.java b/config-model/src/main/java/com/yahoo/searchdefinition/derived/IndexInfo.java
index e98ee662b3a..0d8d21400aa 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/derived/IndexInfo.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/derived/IndexInfo.java
@@ -420,7 +420,7 @@ public class IndexInfo extends Derived implements IndexInfoConfig.Producer {
if (active != null) {
return active;
}
- // assume default
+ // assume default: TODO: Change to Stemming.BEST on Vespa 7
return Stemming.SHORTEST;
}
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/document/Stemming.java b/config-model/src/main/java/com/yahoo/searchdefinition/document/Stemming.java
index f471201f55e..5b145051de5 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/document/Stemming.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/document/Stemming.java
@@ -17,13 +17,17 @@ public enum Stemming {
/** No stemming */
NONE("none"),
- /** Stem as much as possible */
+ /** @deprecated incorrectly don't stem at all */
+ @Deprecated
ALL("all"),
/** select shortest possible stem */
SHORTEST("shortest"),
- /** index (and query?) multiple stems */
+ /** select the "best" stem alternative */
+ BEST("best"),
+
+ /** index multiple stems */
MULTIPLE("multiple");
private static Logger log=Logger.getLogger(Stemming.class.getName());
@@ -36,6 +40,7 @@ public enum Stemming {
*
* @throws IllegalArgumentException if there is no stemming type with the given name
*/
+ @SuppressWarnings("deprecation")
public static Stemming get(String stemmingName) {
try {
Stemming stemming = Stemming.valueOf(stemmingName.toUpperCase());
@@ -49,7 +54,7 @@ public enum Stemming {
}
}
- private Stemming(String name) {
+ Stemming(String name) {
this.name = name;
}
@@ -59,14 +64,16 @@ public enum Stemming {
return "stemming " + name;
}
+ @SuppressWarnings("deprecation")
public StemMode toStemMode() {
- if (this == Stemming.SHORTEST) {
- return StemMode.SHORTEST;
- }
- if (this == Stemming.MULTIPLE) {
- return StemMode.ALL;
+ switch(this) {
+ case SHORTEST: return StemMode.SHORTEST;
+ case MULTIPLE: return StemMode.ALL;
+ case BEST : return StemMode.BEST;
+ case NONE: return StemMode.NONE;
+ case ALL: return StemMode.SHORTEST; // Intentional; preserve historic behavior
+ default: throw new IllegalStateException("Inconvertible stem mode " + this);
}
- return StemMode.NONE;
}
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/Client.java b/config-model/src/main/java/com/yahoo/vespa/model/Client.java
index 15685f5f669..2a2498cc310 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/Client.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/Client.java
@@ -8,7 +8,7 @@ import com.yahoo.config.model.producer.AbstractConfigProducer;
* This is a placeholder config producer that makes global configuration available through a single identifier. This
* is added directly to the {@link ApplicationConfigProducerRoot} producer, and so can be accessed by the simple "client" identifier.
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
+ * @author Simon Thoresen
*/
public class Client extends AbstractConfigProducer {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/ConfigProducer.java b/config-model/src/main/java/com/yahoo/vespa/model/ConfigProducer.java
index 852e4e73331..aaeedf10bc8 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/ConfigProducer.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/ConfigProducer.java
@@ -19,44 +19,38 @@ import com.yahoo.config.model.producer.UserConfigRepo;
*/
public interface ConfigProducer extends com.yahoo.config.ConfigInstance.Producer {
- /**
- * @return the configId of this ConfigProducer.
- */
- public String getConfigId();
+ /** Returns the configId of this ConfigProducer. */
+ String getConfigId();
- /**
- * @return The one and only HostSystem of the root node
- */
- public HostSystem getHostSystem();
+ /** Returns the one and only HostSystem of the root node */
+ HostSystem getHostSystem();
/** Returns the user configs of this */
- public UserConfigRepo getUserConfigs();
+ UserConfigRepo getUserConfigs();
- /**
- * @return this ConfigProducer's children (only 1st level)
- */
- public Map<String,? extends ConfigProducer> getChildren();
+ /** Returns this ConfigProducer's children (only 1st level) */
+ Map<String,? extends ConfigProducer> getChildren();
- /**
- * @return a List of all Services that are descendants to this ConfigProducer
- */
- public List<Service> getDescendantServices();
+ /** Returns a List of all Services that are descendants to this ConfigProducer */
+ List<Service> getDescendantServices();
/**
* Writes files that need to be written. The files will usually
* only be written when the Vespa model is generated through the
* deploy-application script.
- * gv: This is primarily intended for debugging.
+ * This is primarily intended for debugging.
+ *
* @param directory directory to write files to
* @throws java.io.IOException if writing fails
*/
- public void writeFiles(File directory) throws IOException;
+ void writeFiles(File directory) throws IOException;
/**
* Dump the three of config producers to the specified stream.
+ *
* @param out The stream to print to, e.g. System.out
*/
- public void dump(PrintStream out);
+ void dump(PrintStream out);
/**
* Build config from this and all parent ConfigProducers,
@@ -74,11 +68,12 @@ public interface ConfigProducer extends com.yahoo.config.ConfigInstance.Producer
* @param builder The ConfigBuilder to add user config overrides.
* @return true if overrides were added, false if not.
*/
- public boolean addUserConfig(ConfigInstance.Builder builder);
+ boolean addUserConfig(ConfigInstance.Builder builder);
/**
* check constraints depending on the state of the vespamodel graph.
* When overriding, you must invoke super.
*/
- public void validate() throws Exception;
+ void validate() throws Exception;
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/HostSystem.java b/config-model/src/main/java/com/yahoo/vespa/model/HostSystem.java
index d3e922c69dc..2d825e3332d 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/HostSystem.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/HostSystem.java
@@ -5,12 +5,21 @@ import com.yahoo.config.application.api.DeployLogger;
import com.yahoo.config.model.api.HostProvisioner;
import com.yahoo.config.model.producer.AbstractConfigProducer;
import com.yahoo.config.model.test.MockRoot;
-import com.yahoo.config.provision.*;
+import com.yahoo.config.provision.Capacity;
+import com.yahoo.config.provision.ClusterMembership;
+import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.HostSpec;
+import com.yahoo.config.provision.ProvisionLogger;
import com.yahoo.net.HostName;
import java.net.InetAddress;
import java.net.UnknownHostException;
-import java.util.*;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
import java.util.logging.Level;
import java.util.stream.Collectors;
@@ -73,6 +82,7 @@ public class HostSystem extends AbstractConfigProducer<Host> {
* @return The canonical hostname, or null if unable to resolve.
* @throws UnknownHostException if the hostname cannot be resolved
*/
+ // public - This is used by amenders outside this repo
public static String lookupCanonicalHostname(String hostname) throws UnknownHostException {
return java.net.InetAddress.getByName(hostname).getCanonicalHostName();
}
@@ -87,7 +97,7 @@ public class HostSystem extends AbstractConfigProducer<Host> {
if (ipAddresses.containsKey(hostname)) return ipAddresses.get(hostname);
String ipAddress;
- if (hostname.startsWith(MockRoot.MOCKHOST)) {
+ if (hostname.startsWith(MockRoot.MOCKHOST)) { // TODO: Remove
ipAddress = "0.0.0.0";
} else {
try {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/PlainFormatter.java b/config-model/src/main/java/com/yahoo/vespa/model/PlainFormatter.java
deleted file mode 100644
index d424f4fa31b..00000000000
--- a/config-model/src/main/java/com/yahoo/vespa/model/PlainFormatter.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.model;
-
-import java.util.logging.Formatter;
-import java.util.logging.LogRecord;
-
-/**
- * A log formatter that returns a plain log message only with level, not
- * including timestamp and method (as java.util.logging.SimpleFormatter).
- * See bug #1789867.
- *
- * @author gjoranv
- */
-public class PlainFormatter extends Formatter {
-
- public PlainFormatter() {
- super();
- }
-
- public String format(LogRecord record) {
- StringBuffer sb = new StringBuffer();
-
- sb.append(record.getLevel().getName()).append(": ");
- sb.append(formatMessage(record)).append("\n");
-
- return sb.toString();
- }
-}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/PortsMeta.java b/config-model/src/main/java/com/yahoo/vespa/model/PortsMeta.java
index ea2151f9976..a0b3cc7294b 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/PortsMeta.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/PortsMeta.java
@@ -7,11 +7,12 @@ import java.util.LinkedList;
import java.util.List;
/**
- * Track metainformation about the ports of a service.
+ * Track meta information about the ports of a service.
*
* @author Vidar Larsen
*/
public class PortsMeta implements Serializable {
+
/** A list of all ports. The list elements are lists of strings. */
private List<LinkedList<String>> ports;
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java b/config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java
index 9a23be1f5c5..bdba3549033 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/VespaModel.java
@@ -100,6 +100,8 @@ public final class VespaModel extends AbstractConfigProducerRoot implements Seri
/** The validation overrides of this. This is never null. */
private final ValidationOverrides validationOverrides;
+
+ private final FileDistributor fileDistributor;
/** Creates a Vespa Model from internal model types only */
public VespaModel(ApplicationPackage app) throws IOException, SAXException {
@@ -130,23 +132,38 @@ public final class VespaModel extends AbstractConfigProducerRoot implements Seri
* @param deployState the global deploy state to use for this model.
*/
public VespaModel(ConfigModelRegistry configModelRegistry, DeployState deployState) throws IOException, SAXException {
+ this(configModelRegistry, deployState, true, null);
+ }
+
+ private VespaModel(ConfigModelRegistry configModelRegistry, DeployState deployState, boolean complete, FileDistributor fileDistributor) throws IOException, SAXException {
super("vespamodel");
this.deployState = deployState;
this.validationOverrides = deployState.validationOverrides();
configModelRegistry = new VespaConfigModelRegistry(configModelRegistry);
VespaModelBuilder builder = new VespaDomBuilder();
root = builder.getRoot(VespaModel.ROOT_CONFIGID, deployState, this);
- configModelRepo.readConfigModels(deployState, builder, root, configModelRegistry);
- addServiceClusters(deployState.getApplicationPackage(), builder);
- setupRouting();
- log.log(LogLevel.DEBUG, "hostsystem=" + getHostSystem());
- this.info = Optional.of(createProvisionInfo());
- getAdmin().addPerHostServices(getHostSystem().getHosts(), deployState.getProperties());
- freezeModelTopology();
- root.prepare(configModelRepo);
- configModelRepo.prepareConfigModels();
- validateWrapExceptions();
- this.deployState = null;
+ if (complete) { // create a a completed, frozen model
+ configModelRepo.readConfigModels(deployState, builder, root, configModelRegistry);
+ addServiceClusters(deployState.getApplicationPackage(), builder);
+ this.info = Optional.of(createProvisionInfo()); // must happen after the two lines above
+ setupRouting();
+ this.fileDistributor = root.getFileDistributionConfigProducer().getFileDistributor();
+ getAdmin().addPerHostServices(getHostSystem().getHosts(), deployState.getProperties());
+ freezeModelTopology();
+ root.prepare(configModelRepo);
+ configModelRepo.prepareConfigModels();
+ validateWrapExceptions();
+ this.deployState = null;
+ }
+ else { // create a model with no services instantiated and the given file distributor
+ this.info = Optional.of(createProvisionInfo());
+ this.fileDistributor = fileDistributor;
+ }
+ }
+
+ /** Creates a mutable model with no services instantiated */
+ public static VespaModel createIncomplete(DeployState deployState) throws IOException, SAXException {
+ return new VespaModel(new NullConfigModelRegistry(), deployState, false, new FileDistributor(deployState.getFileRegistry()));
}
private ProvisionInfo createProvisionInfo() {
@@ -192,7 +209,8 @@ public final class VespaModel extends AbstractConfigProducerRoot implements Seri
}
public FileDistributor getFileDistributor() {
- return root.getFileDistributionConfigProducer().getFileDistributor();
+ // return root.getFileDistributionConfigProducer().getFileDistributor();
+ return fileDistributor;
}
/** Returns this models Vespa instance */
@@ -437,9 +455,8 @@ public final class VespaModel extends AbstractConfigProducerRoot implements Seri
@Override
public DeployState getDeployState() {
- if (deployState == null) {
+ if (deployState == null)
throw new IllegalStateException("Cannot call getDeployState() once model has been built");
- }
return deployState;
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java b/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java
index 9b234435ce2..adbd4d7bae1 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java
@@ -4,7 +4,6 @@ package com.yahoo.vespa.model;
import com.google.inject.Inject;
import com.yahoo.component.provider.ComponentRegistry;
import com.yahoo.config.application.api.ApplicationPackage;
-import com.yahoo.config.application.api.DeployLogger;
import com.yahoo.config.model.ConfigModelRegistry;
import com.yahoo.config.model.MapConfigModelRegistry;
import com.yahoo.config.model.NullConfigModelRegistry;
@@ -89,7 +88,6 @@ public class VespaModelFactory implements ModelFactory {
if (modelContext.appDir().isPresent()) {
ApplicationPackageXmlFilesValidator validator =
ApplicationPackageXmlFilesValidator.createDefaultXMLValidator(modelContext.appDir().get(),
- modelContext.deployLogger(),
modelContext.vespaVersion());
try {
validator.checkApplication();
@@ -101,7 +99,7 @@ public class VespaModelFactory implements ModelFactory {
}
} else {
- validateXML(modelContext.applicationPackage(), modelContext.deployLogger(), ignoreValidationErrors);
+ validateXML(modelContext.applicationPackage(), ignoreValidationErrors);
}
DeployState deployState = createDeployState(modelContext);
VespaModel model = buildModel(deployState);
@@ -173,9 +171,9 @@ public class VespaModelFactory implements ModelFactory {
return modelContext.properties().hostedVespa() && id.isHostedVespaRoutingApplication();
}
- private void validateXML(ApplicationPackage applicationPackage, DeployLogger deployLogger, boolean ignoreValidationErrors) {
+ private void validateXML(ApplicationPackage applicationPackage, boolean ignoreValidationErrors) {
try {
- applicationPackage.validateXML(deployLogger);
+ applicationPackage.validateXML();
} catch (IllegalArgumentException e) {
rethrowUnlessIgnoreErrors(e, ignoreValidationErrors);
} catch (Exception e) {
@@ -185,7 +183,7 @@ public class VespaModelFactory implements ModelFactory {
private List<ConfigChangeAction> validateModel(VespaModel model, DeployState deployState, boolean ignoreValidationErrors) {
try {
- deployState.getApplicationPackage().validateXML(deployState.getDeployLogger());
+ deployState.getApplicationPackage().validateXML();
return Validation.validate(model, ignoreValidationErrors, deployState);
} catch (IllegalArgumentException e) {
rethrowUnlessIgnoreErrors(e, ignoreValidationErrors);
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 38a1e59433f..67281b7816d 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
@@ -34,7 +34,7 @@ public class Admin extends AbstractConfigProducer implements Serializable {
private static final long serialVersionUID = 1L;
private final Yamas yamas;
- private final Map<String,MetricsConsumer> metricsConsumers;
+ private final Map<String, MetricsConsumer> metricsConsumers;
private final List<Configserver> configservers = new ArrayList<>();
private final List<Slobrok> slobroks = new ArrayList<>();
@@ -200,7 +200,7 @@ public class Admin extends AbstractConfigProducer implements Serializable {
HostResource deployHost = getHostSystem().getHostByHostname(fileDistributor.fileSourceHost());
if (deployHostIsMissing(deployHost)) {
throw new RuntimeException("Could not find host in the application's host system: '" +
- fileDistributor.fileSourceHost() + "'. Hostsystem=" + getHostSystem());
+ fileDistributor.fileSourceHost() + "'. Hostsystem=" + getHostSystem());
}
FileDistributorService fds = new FileDistributorService(fileDistribution, host.getHost().getHostName(),
@@ -245,4 +245,5 @@ public class Admin extends AbstractConfigProducer implements Serializable {
public boolean multitenant() {
return multitenant;
}
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/Configserver.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/Configserver.java
index 11508ba91ed..47332b064da 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/Configserver.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/Configserver.java
@@ -96,10 +96,12 @@ public class Configserver extends AbstractService {
// TODO: Remove this implementation when we are on Hosted Vespa.
public static class Spec implements ConfigServerSpec {
+
private final String hostName;
private final int configServerPort;
private final int httpPort;
private final int zooKeeperPort;
+
public String getHostName() {
return hostName;
}
@@ -142,4 +144,5 @@ public class Configserver extends AbstractService {
this.zooKeeperPort = zooKeeperPort;
}
}
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/VespaModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/VespaModelBuilder.java
index 75e9caefbd5..bcf523e1c99 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/builder/VespaModelBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/VespaModelBuilder.java
@@ -27,4 +27,5 @@ public abstract class VespaModelBuilder {
* @param configModelRepo a {@link com.yahoo.config.model.ConfigModelRepo instance}
*/
public abstract void postProc(AbstractConfigProducer producerRoot, ConfigModelRepo configModelRepo);
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomClientsBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomClientsBuilder.java
index 876017e16bc..f1829a1d718 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomClientsBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomClientsBuilder.java
@@ -35,4 +35,5 @@ public class DomClientsBuilder extends LegacyConfigModelBuilder<Clients> {
throw new IllegalArgumentException("Version '" + version + "' of 'clients' not supported.");
}
}
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomV20ClientsBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomV20ClientsBuilder.java
index cea325b785f..b4070c67ae1 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomV20ClientsBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomV20ClientsBuilder.java
@@ -1,40 +1,17 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.builder.xml.dom;
-import com.yahoo.component.ComponentId;
-import com.yahoo.component.ComponentSpecification;
-import com.yahoo.component.chain.Phase;
-import com.yahoo.component.chain.dependencies.Dependencies;
-import com.yahoo.component.chain.model.ChainSpecification;
-import com.yahoo.component.chain.model.ChainedComponentModel;
-import com.yahoo.config.model.ConfigModelUtils;
import com.yahoo.vespa.config.content.spooler.SpoolerConfig;
import com.yahoo.config.model.producer.AbstractConfigProducer;
-import com.yahoo.container.bundle.BundleInstantiationSpecification;
-import com.yahoo.osgi.provider.model.ComponentModel;
import com.yahoo.text.XML;
import com.yahoo.vespa.defaults.Defaults;
import com.yahoo.vespa.model.SimpleConfigProducer;
import com.yahoo.vespa.model.builder.xml.dom.VespaDomBuilder.DomConfigProducerBuilder;
-import com.yahoo.vespa.model.builder.xml.dom.chains.docproc.DomDocprocChainsBuilder;
import com.yahoo.vespa.model.clients.Clients;
-import com.yahoo.vespa.model.clients.HttpGatewayOwner;
import com.yahoo.vespa.model.clients.VespaSpoolMaster;
import com.yahoo.vespa.model.clients.VespaSpooler;
import com.yahoo.vespa.model.clients.VespaSpoolerProducer;
import com.yahoo.vespa.model.clients.VespaSpoolerService;
-import com.yahoo.vespa.model.container.Container;
-import com.yahoo.vespa.model.container.ContainerCluster;
-import com.yahoo.vespa.model.container.component.Handler;
-import com.yahoo.vespa.model.container.component.chain.ProcessingHandler;
-import com.yahoo.vespa.model.container.docproc.ContainerDocproc;
-import com.yahoo.vespa.model.container.docproc.DocprocChains;
-import com.yahoo.vespa.model.container.search.ContainerHttpGateway;
-import com.yahoo.vespa.model.container.search.ContainerSearch;
-import com.yahoo.vespa.model.container.search.searchchain.SearchChain;
-import com.yahoo.vespa.model.container.search.searchchain.SearchChains;
-import com.yahoo.vespa.model.container.search.searchchain.Searcher;
-import com.yahoo.vespa.model.container.xml.ContainerModelBuilder;
import com.yahoo.vespaclient.config.FeederConfig;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -43,9 +20,6 @@ import org.w3c.dom.NodeList;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.logging.Level;
/**
* Builds the Clients plugin
@@ -54,29 +28,17 @@ import java.util.logging.Level;
*/
public class DomV20ClientsBuilder {
- public static final String vespaClientBundleSpecification = "vespaclient-container-plugin";
-
// The parent docproc plugin to register data with.
private final Clients clients;
DomV20ClientsBuilder(Clients clients, String version) {
- this.clients = clients;
- if (!version.equals("2.0")) {
+ if ( ! version.equals("2.0"))
throw new IllegalArgumentException("Version '" + version + "' of 'clients' not supported.");
- }
+ this.clients = clients;
}
public void build(Element spec) {
- NodeList children = spec.getElementsByTagName("gateways");
- if (children.getLength() > 0 && clients.getConfigProducer()!=null)
- clients.getConfigProducer().deployLogger().log(Level.WARNING, "The 'gateways' element is deprecated, and will be disallowed in a " +
- "later version of Vespa. Use 'document-api' under 'jdisc' instead, see: " +
- ConfigModelUtils.createDocLink("reference/services-jdisc.html"));
- for (int i = 0; i < children.getLength(); i++) {
- createGateways(clients.getConfigProducer(), (Element) children.item(i), clients);
- }
-
- children = spec.getElementsByTagName("spoolers");
+ NodeList children = spec.getElementsByTagName("spoolers");
for (int i = 0; i < children.getLength(); i++) {
createSpoolers(clients.getConfigProducer(), (Element) children.item(i), clients);
}
@@ -87,29 +49,6 @@ public class DomV20ClientsBuilder {
}
}
- static Boolean getBooleanNodeValue(Node node) {
- return Boolean.valueOf(node.getFirstChild().getNodeValue());
- }
-
- static boolean getHttpFileServerEnabled(Element parentHttpFileServer, Element httpFileServer) {
- boolean ret=false;
- if (parentHttpFileServer != null) {
- for (Element child : XML.getChildren(parentHttpFileServer)) {
- if ("enabled".equals(child.getNodeName())) {
- ret = getBooleanNodeValue(child);
- }
- }
- }
- if (httpFileServer != null) {
- for (Element child : XML.getChildren(httpFileServer)) {
- if ("enabled".equals(child.getNodeName())) {
- ret = getBooleanNodeValue(child);
- }
- }
- }
- return ret;
- }
-
private void createLoadTypes(Element element, Clients clients) {
for (Element e : XML.getChildren(element, "type")) {
String priority = e.getAttribute("default-priority");
@@ -118,31 +57,6 @@ public class DomV20ClientsBuilder {
}
/**
- * Creates HttpGateway objects using the given xml Element.
- *
- * @param pcp AbstractConfigProducer
- * @param element The xml Element
- */
- private void createGateways(AbstractConfigProducer pcp, Element element, Clients clients) {
- String jvmArgs = null;
- if (element.hasAttribute(VespaDomBuilder.JVMARGS_ATTRIB_NAME)) jvmArgs=element.getAttribute(VespaDomBuilder.JVMARGS_ATTRIB_NAME);
-
- Element gatewaysFeederOptions = findFeederOptions(element);
-
- HttpGatewayOwner owner = new HttpGatewayOwner(pcp, getFeederConfig(null, gatewaysFeederOptions));
- ContainerCluster cluster = new ContainerHttpGatewayClusterBuilder().build(owner, element);
-
- int index = 0;
- for (Element e : XML.getChildren(element, "gateway")) {
- ContainerHttpGateway qrs = new ContainerHttpGatewayBuilder(cluster, index).build(cluster, e);
-
- if ("".equals(qrs.getJvmArgs()) && jvmArgs!=null) qrs.setJvmArgs(jvmArgs);
- index++;
- }
- clients.setContainerHttpGateways(cluster);
- }
-
- /**
* Creates VespaSpooler objects using the given xml Element.
*/
private void createSpoolers(AbstractConfigProducer pcp, Element element, Clients clients) {
@@ -170,13 +84,10 @@ public class DomV20ClientsBuilder {
}
}
- private void createSpoolMasters(SimpleConfigProducer producer,
- Element element) {
+ private void createSpoolMasters(SimpleConfigProducer producer, Element element) {
int i=0;
- for (Element e : XML.getChildren(element, "spoolmaster")) {
- VespaSpoolMaster master = new VespaSpoolMasterBuilder(i).build(producer, e);
- i++;
- }
+ for (Element e : XML.getChildren(element, "spoolmaster"))
+ new VespaSpoolMasterBuilder(i++).build(producer, e);
}
private SpoolerConfig.Builder getSpoolConfig(Element conf) {
@@ -313,133 +224,6 @@ public class DomV20ClientsBuilder {
}
}
- public static class ContainerHttpGatewayClusterBuilder extends DomConfigProducerBuilder<ContainerCluster> {
- @Override
- protected ContainerCluster doBuild(AbstractConfigProducer parent,
- Element spec) {
-
- ContainerCluster cluster = new ContainerCluster(parent, "gateway", "gateway");
-
- SearchChains searchChains = new SearchChains(cluster, "searchchain");
- Set<ComponentSpecification> inherited = new TreeSet<>();
- //inherited.add(new ComponentSpecification("vespa", null, null));
- {
- SearchChain mySearchChain = new SearchChain(new ChainSpecification(new ComponentId("vespaget"),
- new ChainSpecification.Inheritance(inherited, null), new ArrayList<>(), new TreeSet<>()));
- Searcher getComponent = newVespaClientSearcher("com.yahoo.storage.searcher.GetSearcher");
- mySearchChain.addInnerComponent(getComponent);
- searchChains.add(mySearchChain);
- }
- {
- SearchChain mySearchChain = new SearchChain(new ChainSpecification(new ComponentId("vespavisit"),
- new ChainSpecification.Inheritance(inherited, null), new ArrayList<>(), new TreeSet<>()));
- Searcher getComponent = newVespaClientSearcher("com.yahoo.storage.searcher.VisitSearcher");
- mySearchChain.addInnerComponent(getComponent);
- searchChains.add(mySearchChain);
- }
-
- ContainerSearch containerSearch = new ContainerSearch(cluster, searchChains, new ContainerSearch.Options());
- cluster.setSearch(containerSearch);
-
- cluster.addComponent(newVespaClientHandler("com.yahoo.feedhandler.VespaFeedHandler", "http://*/feed"));
- cluster.addComponent(newVespaClientHandler("com.yahoo.feedhandler.VespaFeedHandlerRemove", "http://*/remove"));
- cluster.addComponent(newVespaClientHandler("com.yahoo.feedhandler.VespaFeedHandlerRemoveLocation", "http://*/removelocation"));
- cluster.addComponent(newVespaClientHandler("com.yahoo.feedhandler.VespaFeedHandlerGet", "http://*/get"));
- cluster.addComponent(newVespaClientHandler("com.yahoo.feedhandler.VespaFeedHandlerVisit", "http://*/visit"));
- cluster.addComponent(newVespaClientHandler("com.yahoo.feedhandler.VespaFeedHandlerCompatibility", "http://*/document"));
- cluster.addComponent(newVespaClientHandler("com.yahoo.feedhandler.VespaFeedHandlerStatus", "http://*/feedstatus"));
- final ProcessingHandler<SearchChains> searchHandler = new ProcessingHandler<>(
- cluster.getSearch().getChains(), "com.yahoo.search.handler.SearchHandler");
- searchHandler.addServerBindings("http://*/search/*");
- cluster.addComponent(searchHandler);
-
- ContainerModelBuilder.addDefaultHandler_legacyBuilder(cluster);
-
- //BEGIN HACK for docproc chains:
- DocprocChains docprocChains = getDocprocChains(cluster, spec);
- if (docprocChains != null) {
- ContainerDocproc containerDocproc = new ContainerDocproc(cluster, docprocChains);
- cluster.setDocproc(containerDocproc);
- }
- //END HACK
-
- return cluster;
- }
-
- private Handler newVespaClientHandler(String componentId, String binding) {
- Handler<AbstractConfigProducer<?>> handler = new Handler<>(new ComponentModel(
- BundleInstantiationSpecification.getFromStrings(componentId, null, vespaClientBundleSpecification), ""));
- handler.addServerBindings(binding);
- handler.addServerBindings(binding + '/');
- return handler;
- }
-
- private Searcher newVespaClientSearcher(String componentSpec) {
- return new Searcher<>(new ChainedComponentModel(
- BundleInstantiationSpecification.getFromStrings(componentSpec, null, vespaClientBundleSpecification),
- new Dependencies(null, null, null)));
- }
-
- //BEGIN HACK for docproc chains:
- private DocprocChains getDocprocChains(AbstractConfigProducer qrs, Element gateways) {
- Element clients = (Element) gateways.getParentNode();
- Element services = (Element) clients.getParentNode();
- if (services == null) {
- return null;
- }
-
- Element docproc = XML.getChild(services, "docproc");
- if (docproc == null) {
- return null;
- }
-
- String version = docproc.getAttribute("version");
- if (version.startsWith("1.")) {
- return null;
- } else if (version.startsWith("2.")) {
- return null;
- } else if (version.startsWith("3.")) {
- return getDocprocChainsV3(qrs, docproc);
- } else {
- throw new IllegalArgumentException("Docproc version " + version + " unknown.");
- }
- }
-
- private DocprocChains getDocprocChainsV3(AbstractConfigProducer qrs, Element docproc) {
- Element docprocChainsElem = XML.getChild(docproc, "docprocchains");
- if (docprocChainsElem == null) {
- return null;
- }
- return new DomDocprocChainsBuilder(null, true).build(qrs, docprocChainsElem);
- }
- //END HACK
- }
-
- public static class ContainerHttpGatewayBuilder extends DomConfigProducerBuilder<ContainerHttpGateway> {
- int index;
- ContainerCluster cluster;
-
- public ContainerHttpGatewayBuilder(ContainerCluster cluster, int index) {
- this.index = index;
- this.cluster = cluster;
- }
-
- @Override
- protected ContainerHttpGateway doBuild(AbstractConfigProducer parent, Element spec) {
- // TODO: remove port handling
- int port = 19020;
- if (spec != null && spec.hasAttribute("baseport")) {
- port = Integer.parseInt(spec.getAttribute("baseport"));
- }
- ContainerHttpGateway httpGateway = new ContainerHttpGateway(cluster, "" + index, port, index);
- List<Container> containers = new ArrayList<>();
- containers.add(httpGateway);
-
- cluster.addContainers(containers);
- return httpGateway;
- }
- }
-
/**
* This class parses the feederoptions xml tag and produces Vespa config output.
*
@@ -553,4 +337,5 @@ public class DomV20ClientsBuilder {
return builder;
}
}
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java
index 7dabfdc600b..c83f6098a0f 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java
@@ -25,14 +25,22 @@ public class NodesSpecification {
private final int groups;
+ /**
+ * Whether the capacity amount specified is required or can it be relaxed
+ * at the discretion of the component fulfilling it
+ */
+ private final boolean required;
+
private final Optional<String> flavor;
private final Optional<String> dockerImage;
- private NodesSpecification(boolean dedicated, int count, int groups, Optional<String> flavor, Optional<String> dockerImage) {
+ private NodesSpecification(boolean dedicated, int count, int groups, boolean required,
+ Optional<String> flavor, Optional<String> dockerImage) {
this.dedicated = dedicated;
this.count = count;
this.groups = groups;
+ this.required = required;
this.flavor = flavor;
this.dockerImage = dockerImage;
}
@@ -41,6 +49,7 @@ public class NodesSpecification {
this(dedicated,
nodesElement.requiredIntegerAttribute("count"),
nodesElement.getIntegerAttribute("groups", 1),
+ nodesElement.getBooleanAttribute("required", false),
Optional.ofNullable(nodesElement.getStringAttribute("flavor")),
Optional.ofNullable(nodesElement.getStringAttribute("docker-image")));
}
@@ -78,7 +87,7 @@ public class NodesSpecification {
/** Returns a requirement from <code>count</code> nondedicated nodes in one group */
public static NodesSpecification nonDedicated(int count) {
- return new NodesSpecification(false, count, 1, Optional.empty(), Optional.empty());
+ return new NodesSpecification(false, count, 1, false, Optional.empty(), Optional.empty());
}
/**
@@ -95,7 +104,7 @@ public class NodesSpecification {
public Map<HostResource, ClusterMembership> provision(HostSystem hostSystem, ClusterSpec.Type clusterType, ClusterSpec.Id clusterId, DeployLogger logger) {
ClusterSpec cluster = ClusterSpec.request(clusterType, clusterId, dockerImage);
- return hostSystem.allocateHosts(cluster, Capacity.fromNodeCount(count, flavor), groups, logger);
+ return hostSystem.allocateHosts(cluster, Capacity.fromNodeCount(count, flavor, required), groups, logger);
}
@Override
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/clients/ContainerDocumentApi.java b/config-model/src/main/java/com/yahoo/vespa/model/clients/ContainerDocumentApi.java
index 55cfc8b2fba..c1ad6eead47 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/clients/ContainerDocumentApi.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/clients/ContainerDocumentApi.java
@@ -26,7 +26,7 @@ import java.util.Set;
import java.util.TreeSet;
/**
- * @author <a href="mailto:einarmr@yahoo-inc.com">Einar M R Rosenvinge</a>
+ * @author Einar M R Rosenvinge
* @since 5.1.11
*/
public class ContainerDocumentApi implements FeederConfig.Producer {
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 e92bffe2542..1351933fbc8 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
@@ -16,6 +16,7 @@ import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.ClusterMembership;
import com.yahoo.config.provision.NodeType;
import com.yahoo.container.jdisc.config.MetricDefaultsConfig;
+import com.yahoo.path.Path;
import com.yahoo.search.rendering.RendererRegistry;
import com.yahoo.text.XML;
import com.yahoo.vespa.defaults.Defaults;
@@ -104,7 +105,6 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
checkVersion(spec);
this.log = modelContext.getDeployLogger();
-
ContainerCluster cluster = createContainerCluster(spec, modelContext);
addClusterContent(cluster, spec, modelContext);
addBundlesForPlatformComponents(cluster);
@@ -587,9 +587,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
private ContainerDocumentApi buildDocumentApi(ContainerCluster cluster, Element spec) {
Element documentApiElement = XML.getChild(spec, "document-api");
- if (documentApiElement == null) {
- return null;
- }
+ if (documentApiElement == null) return null;
ContainerDocumentApi.Options documentApiOptions = DocumentApiOptionsBuilder.build(documentApiElement);
return new ContainerDocumentApi(cluster, documentApiOptions);
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/DocumentApiOptionsBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/DocumentApiOptionsBuilder.java
index df2090db166..b1ffd55b0f0 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/DocumentApiOptionsBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/DocumentApiOptionsBuilder.java
@@ -12,10 +12,11 @@ import java.util.List;
import java.util.logging.Logger;
/**
- * @author <a href="mailto:einarmr@yahoo-inc.com">Einar M R Rosenvinge</a>
+ * @author Einar M R Rosenvinge
* @since 5.1.11
*/
public class DocumentApiOptionsBuilder {
+
private static final Logger log = Logger.getLogger(DocumentApiOptionsBuilder.class.getName());
private static final String[] DEFAULT_BINDINGS = {"http://*/", "https://*/"};
@@ -116,4 +117,5 @@ public class DocumentApiOptionsBuilder {
String value = getCleanValue(spec, "abortondocumenterror");
return value == null ? null : Boolean.parseBoolean(value);
}
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/ContentSearchCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/content/ContentSearchCluster.java
index 56e275e74ac..7e24285c6fb 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/content/ContentSearchCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/content/ContentSearchCluster.java
@@ -31,6 +31,7 @@ public class ContentSearchCluster extends AbstractConfigProducer implements Prot
/** The single, indexed search cluster this sets up (supporting multiple document types), or null if none */
private IndexedSearchCluster indexedCluster;
+ private Redundancy redundancy;
private final String clusterName;
Map<String, NewDocumentType> documentDefinitions;
@@ -254,6 +255,7 @@ public class ContentSearchCluster extends AbstractConfigProducer implements Prot
if (usesHierarchicDistribution()) {
indexedCluster.setMaxNodesDownPerFixedRow((redundancy.effectiveFinalRedundancy() / groupToSpecMap.size()) - 1);
}
+ this.redundancy = redundancy;
}
@Override
@@ -287,6 +289,9 @@ public class ContentSearchCluster extends AbstractConfigProducer implements Prot
if (tuning != null) {
tuning.getConfig(builder);
}
+ if (redundancy != null) {
+ redundancy.getConfig(builder);
+ }
}
@Override
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/Redundancy.java b/config-model/src/main/java/com/yahoo/vespa/model/content/Redundancy.java
index 262c985e733..918bdcb8cb7 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/content/Redundancy.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/content/Redundancy.java
@@ -2,19 +2,21 @@
package com.yahoo.vespa.model.content;
import com.yahoo.vespa.config.content.StorDistributionConfig;
+import com.yahoo.vespa.config.search.core.ProtonConfig;
/**
* Configuration of the redundancy of a content cluster.
*
* @author bratseth
*/
-public class Redundancy implements StorDistributionConfig.Producer {
+public class Redundancy implements StorDistributionConfig.Producer, ProtonConfig.Producer {
private final int initialRedundancy ;
private final int finalRedundancy;
private final int readyCopies;
private int implicitGroups = 1;
+ private int explicitGroups = 1;
/** The total number of nodes available in this cluster (assigned when this becomes known) */
private int totalNodes = 0;
@@ -39,6 +41,7 @@ public class Redundancy implements StorDistributionConfig.Producer {
* values returned in the config.
*/
public void setImplicitGroups(int implicitGroups) { this.implicitGroups = implicitGroups; }
+ public void setExplicitGroups(int explicitGroups) { this.explicitGroups = explicitGroups; }
public int initialRedundancy() { return initialRedundancy; }
public int finalRedundancy() { return finalRedundancy; }
@@ -54,4 +57,11 @@ public class Redundancy implements StorDistributionConfig.Producer {
builder.redundancy(effectiveFinalRedundancy());
builder.ready_copies(effectiveReadyCopies());
}
+ @Override
+ public void getConfig(ProtonConfig.Builder builder) {
+ ProtonConfig.Distribution.Builder distBuilder = new ProtonConfig.Distribution.Builder();
+ distBuilder.redundancy(finalRedundancy/explicitGroups);
+ distBuilder.searchablecopies(readyCopies/(explicitGroups*implicitGroups));
+ builder.distribution(distBuilder);
+ }
}
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 fa417b34844..ef05a3d6ff5 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
@@ -104,8 +104,7 @@ public class ContentCluster extends AbstractConfigProducer implements StorDistri
String routingSelection = new DocumentSelectionBuilder().build(contentElement.getChild("documents"));
Redundancy redundancy = new RedundancyBuilder().build(contentElement);
- ContentCluster c = new ContentCluster(ancestor, getClusterName(contentElement), documentDefinitions,
- routingSelection, redundancy);
+ ContentCluster c = new ContentCluster(ancestor, getClusterName(contentElement), documentDefinitions, routingSelection, redundancy);
c.clusterControllerConfig = new ClusterControllerConfig.Builder(getClusterName(contentElement), contentElement).build(c, contentElement.getXml());
c.search = new ContentSearchCluster.Builder(documentDefinitions).build(c, contentElement.getXml());
c.persistenceFactory = new EngineFactoryBuilder().build(contentElement, c);
@@ -113,6 +112,7 @@ public class ContentCluster extends AbstractConfigProducer implements StorDistri
c.distributorNodes = new DistributorCluster.Builder(c).build(c, w3cContentElement);
c.rootGroup = new StorageGroup.Builder(contentElement, c, deployLogger).buildRootGroup();
validateThatGroupSiblingsAreUnique(c.clusterName, c.rootGroup);
+ redundancy.setExplicitGroups(c.getRootGroup().getNumberOfLeafGroups());
c.search.handleRedundancy(redundancy);
IndexedSearchCluster index = c.search.getIndexed();
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/filedistribution/FileDistributionConfigProducer.java b/config-model/src/main/java/com/yahoo/vespa/model/filedistribution/FileDistributionConfigProducer.java
index 630118cc60c..095a5e29450 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/filedistribution/FileDistributionConfigProducer.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/filedistribution/FileDistributionConfigProducer.java
@@ -13,6 +13,7 @@ import java.util.Map;
* @author tonytv
*/
public class FileDistributionConfigProducer extends AbstractConfigProducer {
+
private final Map<Host, FileDistributorService> fileDistributorServices = new IdentityHashMap<>();
private final FileDistributor fileDistributor;
private final FileDistributionOptions options;
@@ -56,4 +57,5 @@ public class FileDistributionConfigProducer extends AbstractConfigProducer {
return new FileDistributionConfigProducer(ancestor, fileDistributor, options);
}
}
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/filedistribution/FileDistributor.java b/config-model/src/main/java/com/yahoo/vespa/model/filedistribution/FileDistributor.java
index 4dc24618a61..df7b4f58ab5 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/filedistribution/FileDistributor.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/filedistribution/FileDistributor.java
@@ -117,4 +117,5 @@ public class FileDistributor {
result.addAll(asList(additionalHosts));
return result;
}
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/utils/FileSender.java b/config-model/src/main/java/com/yahoo/vespa/model/utils/FileSender.java
index 4ab9ed3af85..84685ecef3d 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/utils/FileSender.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/utils/FileSender.java
@@ -32,8 +32,8 @@ public class FileSender implements Serializable {
public static FileReference sendFileToServices(String relativePath,
Collection<? extends AbstractService> services) {
if (services.isEmpty()) {
- throw new IllegalStateException("'sendFileToServices called for empty services!" +
- " - This should never happen!");
+ throw new IllegalStateException("No service instances. Probably a standalone cluster setting up <nodes> " +
+ "using 'count' instead of <node> tags.");
}
FileReference fileref = null;
for (AbstractService service : services) {
@@ -146,4 +146,5 @@ public class FileSender implements Serializable {
}
builder.setValue(reference.value());
}
+
} \ No newline at end of file
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/utils/FreezableMap.java b/config-model/src/main/java/com/yahoo/vespa/model/utils/FreezableMap.java
index a05008cc9a0..211413f9bff 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/utils/FreezableMap.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/utils/FreezableMap.java
@@ -4,8 +4,9 @@ package com.yahoo.vespa.model.utils;
import java.util.*;
/**
- * Delegates to a map that can be froozen.
+ * Delegates to a map that can be frozen.
* Not thread safe.
+ *
* @author tonytv
*/
public class FreezableMap<K, V> implements Map<K, V> {
@@ -88,4 +89,5 @@ public class FreezableMap<K, V> implements Map<K, V> {
public boolean isFrozen() {
return frozen;
}
+
}
diff --git a/config-model/src/main/resources/schema/common.rnc b/config-model/src/main/resources/schema/common.rnc
index 06e7b945c18..b89fe0d7fcb 100644
--- a/config-model/src/main/resources/schema/common.rnc
+++ b/config-model/src/main/resources/schema/common.rnc
@@ -23,6 +23,7 @@ Nodes = element nodes {
OptionalDedicatedNodes = element nodes {
attribute count { xsd:positiveInteger } &
attribute flavor { xsd:string }? &
+ attribute required { xsd:boolean }? &
attribute docker-image { xsd:string }? &
attribute dedicated { xsd:boolean }?
}
diff --git a/config-model/src/main/resources/schema/containercluster.rnc b/config-model/src/main/resources/schema/containercluster.rnc
index 8f1ed0d874e..17e38883755 100644
--- a/config-model/src/main/resources/schema/containercluster.rnc
+++ b/config-model/src/main/resources/schema/containercluster.rnc
@@ -161,7 +161,7 @@ ProcessingInContainer = element processing {
-# DOCUMENT API/GATEWAY:
+# DOCUMENT API:
DocumentApi = element document-api {
ServerBindings &
@@ -194,6 +194,7 @@ NodesOfContainerCluster = element nodes {
(
attribute count { xsd:positiveInteger } &
attribute flavor { xsd:string }? &
+ attribute required { xsd:boolean }? &
attribute docker-image { xsd:string }?
)
|
diff --git a/config-model/src/main/resources/schema/content.rnc b/config-model/src/main/resources/schema/content.rnc
index 30b931053d5..c3a8386ac5e 100644
--- a/config-model/src/main/resources/schema/content.rnc
+++ b/config-model/src/main/resources/schema/content.rnc
@@ -216,6 +216,7 @@ ContentNodes = element nodes {
(
attribute count { xsd:positiveInteger } &
attribute flavor { xsd:string }? &
+ attribute required { xsd:boolean }? &
attribute docker-image { xsd:string }? &
attribute groups { xsd:positiveInteger }?
)
@@ -260,6 +261,7 @@ Group = element group {
element nodes {
attribute count { xsd:positiveInteger } &
attribute flavor { xsd:string }? &
+ attribute required { xsd:boolean }? &
attribute docker-image { xsd:string }? &
attribute groups { xsd:positiveInteger }?
}
diff --git a/config-model/src/main/resources/schema/deployment.rnc b/config-model/src/main/resources/schema/deployment.rnc
new file mode 100644
index 00000000000..22ceab4efa5
--- /dev/null
+++ b/config-model/src/main/resources/schema/deployment.rnc
@@ -0,0 +1,26 @@
+# RELAX NG Compact Syntax
+# Vespa Deployment file
+
+start = element deployment {
+ attribute version { "1.0" } &
+ Test? &
+ Staging? &
+ Prod*
+}
+
+Test = element test {
+ text
+}
+
+Staging = element staging {
+ text
+}
+
+Prod =
+ element prod {
+ attribute global-service-id { text }?,
+ element region {
+ attribute active { xsd:boolean },
+ text
+ }*
+ }
diff --git a/config-model/src/main/resources/schema/schemas.xml b/config-model/src/main/resources/schema/schemas.xml
index 728754e3a5f..ed39af3d490 100644
--- a/config-model/src/main/resources/schema/schemas.xml
+++ b/config-model/src/main/resources/schema/schemas.xml
@@ -3,4 +3,5 @@
<locatingRules xmlns="http://thaiopensource.com/ns/locating-rules/1.0">
<documentElement localName="hosts" uri="hosts.rnc"/>
<documentElement localName="services" uri="services.rnc"/>
+ <documentElement localName="deployment" uri="deployment.rnc"/>
</locatingRules>
diff --git a/config-model/src/test/cfg/application/app1/deployment.xml b/config-model/src/test/cfg/application/app1/deployment.xml
new file mode 100644
index 00000000000..34d2036c1a5
--- /dev/null
+++ b/config-model/src/test/cfg/application/app1/deployment.xml
@@ -0,0 +1,8 @@
+<deployment version="1.0">
+ <test/>
+ <staging/>
+ <prod global-service-id="query">
+ <region active="true">us-east-3</region>
+ <region active="false">us-west-1</region>
+ </prod>
+</deployment>
diff --git a/config-model/src/test/cfg/application/app_invalid_deployment_xml/deployment.xml b/config-model/src/test/cfg/application/app_invalid_deployment_xml/deployment.xml
new file mode 100644
index 00000000000..7a1089a6c1e
--- /dev/null
+++ b/config-model/src/test/cfg/application/app_invalid_deployment_xml/deployment.xml
@@ -0,0 +1,8 @@
+<deployment version="1.0">
+ <test/>
+ <staging/>
+ <prod global-service-id="query">
+ <region>us-east-3</region>
+ <region active="false">us-west-1</region>
+ </prod>
+</deployment>
diff --git a/config-model/src/test/cfg/application/app_invalid_deployment_xml/hosts.xml b/config-model/src/test/cfg/application/app_invalid_deployment_xml/hosts.xml
new file mode 100644
index 00000000000..132169097cf
--- /dev/null
+++ b/config-model/src/test/cfg/application/app_invalid_deployment_xml/hosts.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<hosts>
+ <host name="localhost">
+ <alias>node1</alias>
+ </host>
+ <host name="schmocalhost">
+ <alias>node2</alias>
+ </host>
+</hosts>
diff --git a/config-model/src/test/cfg/application/app_invalid_deployment_xml/services.xml b/config-model/src/test/cfg/application/app_invalid_deployment_xml/services.xml
new file mode 100644
index 00000000000..a1702af234f
--- /dev/null
+++ b/config-model/src/test/cfg/application/app_invalid_deployment_xml/services.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<services version="1.0">
+
+ <admin version="2.0">
+ <adminserver hostalias="node1"/>
+ </admin>
+
+ <container version="1.0">
+ <nodes>
+ <node hostalias="node1" />
+ </nodes>
+ <search/>
+ </container>
+
+</services>
diff --git a/config-model/src/test/cfg/application/empty_prod_region_in_deployment_xml/deployment.xml b/config-model/src/test/cfg/application/empty_prod_region_in_deployment_xml/deployment.xml
new file mode 100644
index 00000000000..d04cc5dfd65
--- /dev/null
+++ b/config-model/src/test/cfg/application/empty_prod_region_in_deployment_xml/deployment.xml
@@ -0,0 +1,5 @@
+<deployment version="1.0">
+ <test/>
+ <staging/>
+ <prod />
+</deployment>
diff --git a/config-model/src/test/cfg/application/empty_prod_region_in_deployment_xml/hosts.xml b/config-model/src/test/cfg/application/empty_prod_region_in_deployment_xml/hosts.xml
new file mode 100644
index 00000000000..132169097cf
--- /dev/null
+++ b/config-model/src/test/cfg/application/empty_prod_region_in_deployment_xml/hosts.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<hosts>
+ <host name="localhost">
+ <alias>node1</alias>
+ </host>
+ <host name="schmocalhost">
+ <alias>node2</alias>
+ </host>
+</hosts>
diff --git a/config-model/src/test/cfg/application/empty_prod_region_in_deployment_xml/services.xml b/config-model/src/test/cfg/application/empty_prod_region_in_deployment_xml/services.xml
new file mode 100644
index 00000000000..a1702af234f
--- /dev/null
+++ b/config-model/src/test/cfg/application/empty_prod_region_in_deployment_xml/services.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<services version="1.0">
+
+ <admin version="2.0">
+ <adminserver hostalias="node1"/>
+ </admin>
+
+ <container version="1.0">
+ <nodes>
+ <node hostalias="node1" />
+ </nodes>
+ <search/>
+ </container>
+
+</services>
diff --git a/config-model/src/test/java/com/yahoo/config/model/ApplicationDeployTest.java b/config-model/src/test/java/com/yahoo/config/model/ApplicationDeployTest.java
index d4e521ebd13..0334b3c867b 100644
--- a/config-model/src/test/java/com/yahoo/config/model/ApplicationDeployTest.java
+++ b/config-model/src/test/java/com/yahoo/config/model/ApplicationDeployTest.java
@@ -21,6 +21,7 @@ import com.yahoo.vespa.model.VespaModel;
import com.yahoo.vespa.model.search.SearchDefinition;
import org.json.JSONException;
import org.junit.After;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@@ -203,6 +204,28 @@ public class ApplicationDeployTest {
assertThat(getSearchDefinitions(app).size(), is(6));
}
+ @Test
+ public void testThatAppWithDeploymentXmlIsValid() throws IOException {
+ File tmpDir = Files.createTempDir();
+ IOUtils.copyDirectory(new File(TESTDIR, "app1"), tmpDir);
+ createAppPkg(tmpDir.getAbsolutePath());
+ }
+
+ @Ignore // TODO: Enable when code in ApplicationPackageXmlFilesValidator does validation of deployment.xml
+ @Test(expected = IllegalArgumentException.class)
+ public void testThatAppWithIllegalDeploymentXmlIsNotValid() throws IOException {
+ File tmpDir = Files.createTempDir();
+ IOUtils.copyDirectory(new File(TESTDIR, "app_invalid_deployment_xml"), tmpDir);
+ createAppPkg(tmpDir.getAbsolutePath());
+ }
+
+ @Test
+ public void testThatAppWithIllegalEmptyProdRegion() throws IOException {
+ File tmpDir = Files.createTempDir();
+ IOUtils.copyDirectory(new File(TESTDIR, "empty_prod_region_in_deployment_xml"), tmpDir);
+ createAppPkg(tmpDir.getAbsolutePath());
+ }
+
private List<SearchDefinition> getSearchDefinitions(FilesApplicationPackage app) {
return new DeployState.Builder().applicationPackage(app).build().getSearchDefinitions();
}
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 86fabdf26bc..8ed4539456a 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
@@ -522,6 +522,7 @@ public class ModelProvisioningTest {
assertEquals(1, clusterControllers.getContainers().size()); // TODO: Expected 5 with this feature reactivated
}
+ @Test
public void testClusterControllersAreNotPlacedOnRetiredNodes() {
String services =
"<?xml version='1.0' encoding='utf-8' ?>\n" +
@@ -907,6 +908,26 @@ public class ModelProvisioningTest {
assertThat(cluster.getRootGroup().getNodes().get(0).getConfigId(), is("bar/storage/0"));
}
+ @Test(expected = IllegalArgumentException.class)
+ public void testRequiringMoreNodesThanAreAvailable() throws ParseException {
+ String services =
+ "<?xml version='1.0' encoding='utf-8' ?>\n" +
+ "<services>" +
+ " <content version='1.0' id='bar'>" +
+ " <redundancy>1</redundancy>" +
+ " <documents>" +
+ " <document type='type1' mode='index'/>" +
+ " </documents>" +
+ " <nodes count='3' required='true'/>" +
+ " </content>" +
+ "</services>";
+
+ int numberOfHosts = 2;
+ VespaModelTester tester = new VespaModelTester();
+ tester.addHosts(numberOfHosts);
+ tester.createModel(services, false);
+ }
+
@Test
public void testUsingNodesCountAttributesAndGettingJustOneNode() {
String services =
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ContainerRestartValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ContainerRestartValidatorTest.java
index 88ba6d885b8..3bec45279d9 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ContainerRestartValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ContainerRestartValidatorTest.java
@@ -35,6 +35,14 @@ public class ContainerRestartValidatorTest {
assertTrue(result.isEmpty());
}
+ @Test
+ public void validator_returns_empty_list_for_containers_with_restart_on_deploy_disabled_where_previously_enabled() {
+ VespaModel current = createModel(true);
+ VespaModel next = createModel(false);
+ List<ConfigChangeAction> result = validateModel(current, next);
+ assertTrue(result.isEmpty());
+ }
+
private static List<ConfigChangeAction> validateModel(VespaModel current, VespaModel next) {
return new ContainerRestartValidator()
.validate(current, next, new ValidationOverrides(Collections.emptyList()));
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/content/ClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/content/ClusterTest.java
index bcb113687ec..126fcf7a583 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/content/ClusterTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/content/ClusterTest.java
@@ -9,6 +9,7 @@ import com.yahoo.vespa.config.content.core.StorServerConfig;
import com.yahoo.vespa.config.content.FleetcontrollerConfig;
import com.yahoo.vespa.config.content.StorDistributionConfig;
import com.yahoo.metrics.MetricsmanagerConfig;
+import com.yahoo.vespa.config.search.core.ProtonConfig;
import com.yahoo.vespa.model.VespaModel;
import com.yahoo.vespa.model.container.ContainerCluster;
import com.yahoo.vespa.model.content.cluster.ContentCluster;
@@ -34,44 +35,99 @@ public class ClusterTest extends ContentBaseTest {
}
@Test
- public void testRedundancy() {
- StorDistributionConfig.Builder builder = new StorDistributionConfig.Builder();
- parse("" +
- "<content version=\"1.0\" id=\"storage\">\n" +
- " <documents/>" +
- " <engine>" +
- " <proton>" +
- " <searchable-copies>3</searchable-copies>" +
- " </proton>" +
- " </engine>" +
- " <redundancy reply-after=\"4\">5</redundancy>\n" +
- " <group>" +
- " <node hostalias=\"mockhost\" distribution-key=\"0\"/>\"" +
- " <node hostalias=\"mockhost\" distribution-key=\"1\"/>\"" +
- " <node hostalias=\"mockhost\" distribution-key=\"2\"/>\"" +
- " <node hostalias=\"mockhost\" distribution-key=\"3\"/>\"" +
- " <node hostalias=\"mockhost\" distribution-key=\"4\"/>\"" +
- " </group>" +
- "</content>"
- ).getConfig(builder);
+ public void testHierarchicRedundancy() {
+ ContentCluster cc = parse("" +
+ "<content version=\"1.0\" id=\"storage\">\n" +
+ " <documents/>" +
+ " <engine>" +
+ " <proton>" +
+ " <searchable-copies>3</searchable-copies>" +
+ " </proton>" +
+ " </engine>" +
+ " <redundancy>15</redundancy>\n" +
+ " <group name='root' distribution-key='0'>" +
+ " <distribution partitions='1|1|*'/>" +
+ " <group name='g-1' distribution-key='0'>" +
+ " <node hostalias='mockhost' distribution-key='0'/>" +
+ " <node hostalias='mockhost' distribution-key='1'/>" +
+ " <node hostalias='mockhost' distribution-key='2'/>" +
+ " <node hostalias='mockhost' distribution-key='3'/>" +
+ " <node hostalias='mockhost' distribution-key='4'/>" +
+ " </group>" +
+ " <group name='g-2' distribution-key='1'>" +
+ " <node hostalias='mockhost' distribution-key='5'/>" +
+ " <node hostalias='mockhost' distribution-key='6'/>" +
+ " <node hostalias='mockhost' distribution-key='7'/>" +
+ " <node hostalias='mockhost' distribution-key='8'/>" +
+ " <node hostalias='mockhost' distribution-key='9'/>" +
+ " </group>" +
+ " <group name='g-3' distribution-key='1'>" +
+ " <node hostalias='mockhost' distribution-key='10'/>" +
+ " <node hostalias='mockhost' distribution-key='11'/>" +
+ " <node hostalias='mockhost' distribution-key='12'/>" +
+ " <node hostalias='mockhost' distribution-key='13'/>" +
+ " <node hostalias='mockhost' distribution-key='14'/>" +
+ " </group>" +
+ " </group>" +
+ "</content>"
+ );
+ StorDistributionConfig.Builder storBuilder = new StorDistributionConfig.Builder();
+ cc.getConfig(storBuilder);
+ StorDistributionConfig storConfig = new StorDistributionConfig(storBuilder);
+ assertEquals(15, storConfig.initial_redundancy());
+ assertEquals(15, storConfig.redundancy());
+ assertEquals(3, storConfig.ready_copies());
+ ProtonConfig.Builder protonBuilder = new ProtonConfig.Builder();
+ cc.getSearch().getConfig(protonBuilder);
+ ProtonConfig protonConfig = new ProtonConfig(protonBuilder);
+ assertEquals(1, protonConfig.distribution().searchablecopies());
+ assertEquals(5, protonConfig.distribution().redundancy());
+ }
- StorDistributionConfig config = new StorDistributionConfig(builder);
- assertEquals(4, config.initial_redundancy());
- assertEquals(5, config.redundancy());
- assertEquals(3, config.ready_copies());
+ @Test
+ public void testRedundancy() {
+ ContentCluster cc = parse("" +
+ "<content version=\"1.0\" id=\"storage\">\n" +
+ " <documents/>" +
+ " <engine>" +
+ " <proton>" +
+ " <searchable-copies>3</searchable-copies>" +
+ " </proton>" +
+ " </engine>" +
+ " <redundancy reply-after='4'>5</redundancy>\n" +
+ " <group>" +
+ " <node hostalias='mockhost' distribution-key='0'/>" +
+ " <node hostalias='mockhost' distribution-key='1'/>" +
+ " <node hostalias='mockhost' distribution-key='2'/>" +
+ " <node hostalias='mockhost' distribution-key='3'/>" +
+ " <node hostalias='mockhost' distribution-key='4'/>" +
+ " </group>" +
+ "</content>"
+ );
+ StorDistributionConfig.Builder storBuilder = new StorDistributionConfig.Builder();
+ cc.getConfig(storBuilder);
+ StorDistributionConfig storConfig = new StorDistributionConfig(storBuilder);
+ assertEquals(4, storConfig.initial_redundancy());
+ assertEquals(5, storConfig.redundancy());
+ assertEquals(3, storConfig.ready_copies());
+ ProtonConfig.Builder protonBuilder = new ProtonConfig.Builder();
+ cc.getSearch().getConfig(protonBuilder);
+ ProtonConfig protonConfig = new ProtonConfig(protonBuilder);
+ assertEquals(3, protonConfig.distribution().searchablecopies());
+ assertEquals(5, protonConfig.distribution().redundancy());
}
@Test
public void testNoId() {
ContentCluster c = parse(
- "<content version=\"1.0\">\n" +
- " <redundancy>1</redundancy>\n" +
- " <documents/>" +
- " <redundancy reply-after=\"4\">5</redundancy>\n" +
- " <group>" +
- " <node hostalias=\"mockhost\" distribution-key=\"0\"/>\"" +
- " </group>" +
- "</content>"
+ "<content version=\"1.0\">\n" +
+ " <redundancy>1</redundancy>\n" +
+ " <documents/>" +
+ " <redundancy reply-after=\"4\">5</redundancy>\n" +
+ " <group>" +
+ " <node hostalias=\"mockhost\" distribution-key=\"0\"/>\"" +
+ " </group>" +
+ "</content>"
);
assertEquals("content", c.getName());
@@ -81,14 +137,14 @@ public class ClusterTest extends ContentBaseTest {
public void testRedundancyDefaults() {
StorDistributionConfig.Builder builder = new StorDistributionConfig.Builder();
parse(
- "<content version=\"1.0\" id=\"storage\">\n" +
- " <documents/>" +
- " <group>" +
- " <node hostalias=\"mockhost\" distribution-key=\"0\"/>\"" +
- " <node hostalias=\"mockhost\" distribution-key=\"1\"/>\"" +
- " <node hostalias=\"mockhost\" distribution-key=\"2\"/>\"" +
- " </group>" +
- "</content>"
+ "<content version=\"1.0\" id=\"storage\">\n" +
+ " <documents/>" +
+ " <group>" +
+ " <node hostalias=\"mockhost\" distribution-key=\"0\"/>\"" +
+ " <node hostalias=\"mockhost\" distribution-key=\"1\"/>\"" +
+ " <node hostalias=\"mockhost\" distribution-key=\"2\"/>\"" +
+ " </group>" +
+ "</content>"
).getConfig(builder);
StorDistributionConfig config = new StorDistributionConfig(builder);
@@ -99,39 +155,40 @@ public class ClusterTest extends ContentBaseTest {
@Test
public void testEndToEnd() throws Exception {
- String xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
- "<services>\n" +
- "\n" +
- " <admin version=\"2.0\">\n" +
- " <adminserver hostalias=\"configserver\" />\n" +
- " <logserver hostalias=\"logserver\" />\n" +
- " <slobroks>\n" +
- " <slobrok hostalias=\"configserver\" />\n" +
- " <slobrok hostalias=\"logserver\" />\n" +
- " </slobroks>\n" +
- " <cluster-controllers>\n" +
- " <cluster-controller hostalias=\"configserver\"/>" +
- " <cluster-controller hostalias=\"configserver2\"/>" +
- " <cluster-controller hostalias=\"configserver3\"/>" +
- " </cluster-controllers>\n" +
- " </admin>\n" +
- " <content version='1.0' id='bar'>" +
- " <redundancy>1</redundancy>\n" +
- " <documents>" +
- " <document type=\"type1\" mode=\"index\"/>\n" +
- " <document type=\"type2\" mode=\"index\"/>\n" +
- " </documents>\n" +
- " <group>" +
- " <node hostalias='node0' distribution-key='0' />" +
- " </group>" +
- " <tuning>" +
- " <cluster-controller>\n" +
- " <init-progress-time>34567</init-progress-time>" +
- " </cluster-controller>" +
- " </tuning>" +
- " </content>" +
- "\n" +
- "</services>";
+ String xml =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
+ "<services>\n" +
+ "\n" +
+ " <admin version=\"2.0\">\n" +
+ " <adminserver hostalias=\"configserver\" />\n" +
+ " <logserver hostalias=\"logserver\" />\n" +
+ " <slobroks>\n" +
+ " <slobrok hostalias=\"configserver\" />\n" +
+ " <slobrok hostalias=\"logserver\" />\n" +
+ " </slobroks>\n" +
+ " <cluster-controllers>\n" +
+ " <cluster-controller hostalias=\"configserver\"/>" +
+ " <cluster-controller hostalias=\"configserver2\"/>" +
+ " <cluster-controller hostalias=\"configserver3\"/>" +
+ " </cluster-controllers>\n" +
+ " </admin>\n" +
+ " <content version='1.0' id='bar'>" +
+ " <redundancy>1</redundancy>\n" +
+ " <documents>" +
+ " <document type=\"type1\" mode=\"index\"/>\n" +
+ " <document type=\"type2\" mode=\"index\"/>\n" +
+ " </documents>\n" +
+ " <group>" +
+ " <node hostalias='node0' distribution-key='0' />" +
+ " </group>" +
+ " <tuning>" +
+ " <cluster-controller>\n" +
+ " <init-progress-time>34567</init-progress-time>" +
+ " </cluster-controller>" +
+ " </tuning>" +
+ " </content>" +
+ "\n" +
+ "</services>";
List<String> sds = ApplicationPackageUtils.generateSearchDefinitions("type1", "type2");
VespaModel model = (new VespaModelCreatorWithMockPkg(null, xml, sds)).create();
@@ -183,32 +240,33 @@ public class ClusterTest extends ContentBaseTest {
@Test
public void testSearchTuning() throws Exception {
- String xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
- "<services>\n" +
- "\n" +
- " <admin version=\"2.0\">\n" +
- " <adminserver hostalias=\"node0\" />\n" +
- " <cluster-controllers>\n" +
- " <cluster-controller hostalias=\"node0\"/>" +
- " </cluster-controllers>\n" +
- " </admin>\n" +
- " <content version='1.0' id='bar'>" +
- " <redundancy>1</redundancy>\n" +
- " <documents>" +
- " <document type=\"type1\" mode='index'/>\n" +
- " <document type=\"type2\" mode='index'/>\n" +
- " </documents>\n" +
- " <group>" +
- " <node hostalias='node0' distribution-key='0'/>" +
- " </group>" +
- " <tuning>\n" +
- " <cluster-controller>" +
- " <init-progress-time>34567</init-progress-time>" +
- " </cluster-controller>" +
- " </tuning>" +
- " </content>" +
- "\n" +
- "</services>";
+ String xml =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
+ "<services>\n" +
+ "\n" +
+ " <admin version=\"2.0\">\n" +
+ " <adminserver hostalias=\"node0\" />\n" +
+ " <cluster-controllers>\n" +
+ " <cluster-controller hostalias=\"node0\"/>" +
+ " </cluster-controllers>\n" +
+ " </admin>\n" +
+ " <content version='1.0' id='bar'>" +
+ " <redundancy>1</redundancy>\n" +
+ " <documents>" +
+ " <document type=\"type1\" mode='index'/>\n" +
+ " <document type=\"type2\" mode='index'/>\n" +
+ " </documents>\n" +
+ " <group>" +
+ " <node hostalias='node0' distribution-key='0'/>" +
+ " </group>" +
+ " <tuning>\n" +
+ " <cluster-controller>" +
+ " <init-progress-time>34567</init-progress-time>" +
+ " </cluster-controller>" +
+ " </tuning>" +
+ " </content>" +
+ "\n" +
+ "</services>";
List<String> sds = ApplicationPackageUtils.generateSearchDefinitions("type1", "type2");
VespaModel model = new VespaModelCreatorWithMockPkg(getHosts(), xml, sds).create();
@@ -232,21 +290,22 @@ public class ClusterTest extends ContentBaseTest {
@Test
public void testRedundancyRequired() throws Exception {
- String xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
- "<services>\n" +
- "\n" +
- " <admin version=\"2.0\">\n" +
- " <adminserver hostalias=\"node0\" />\n" +
- " </admin>\n" +
- " <content version='1.0' id='bar'>" +
- " <documents>" +
- " <document type=\"type1\" mode='index'/>\n" +
- " </documents>\n" +
- " <group>\n" +
- " <node hostalias='node0' distribution-key='0'/>\n" +
- " </group>\n" +
- " </content>\n" +
- "</services>\n";
+ String xml =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
+ "<services>\n" +
+ "\n" +
+ " <admin version=\"2.0\">\n" +
+ " <adminserver hostalias=\"node0\" />\n" +
+ " </admin>\n" +
+ " <content version='1.0' id='bar'>" +
+ " <documents>" +
+ " <document type=\"type1\" mode='index'/>\n" +
+ " </documents>\n" +
+ " <group>\n" +
+ " <node hostalias='node0' distribution-key='0'/>\n" +
+ " </group>\n" +
+ " </content>\n" +
+ "</services>\n";
List<String> sds = ApplicationPackageUtils.generateSearchDefinitions("type1", "type2");
try{
@@ -261,12 +320,12 @@ public class ClusterTest extends ContentBaseTest {
public void testRedundancyFinalLessThanInitial() {
try {
parse(
- "<content version=\"1.0\" id=\"storage\">\n" +
- " <redundancy reply-after=\"4\">2</redundancy>\n" +
- " <group>" +
- " <node hostalias='node0' distribution-key='0' />" +
- " </group>" +
- "</content>"
+ "<content version=\"1.0\" id=\"storage\">\n" +
+ " <redundancy reply-after=\"4\">2</redundancy>\n" +
+ " <group>" +
+ " <node hostalias='node0' distribution-key='0' />" +
+ " </group>" +
+ "</content>"
);
fail("no exception thrown");
} catch (Exception e) {
@@ -277,17 +336,17 @@ public class ClusterTest extends ContentBaseTest {
public void testReadyTooHigh() {
try {
parse(
- "<content version=\"1.0\" id=\"storage\">\n" +
- " <engine>" +
- " <proton>" +
- " <searchable-copies>3</searchable-copies>" +
- " </proton>" +
- " </engine>" +
- " <redundancy>2</redundancy>\n" +
- " <group>" +
- " <node hostalias='node0' distribution-key='0' />" +
- " </group>" +
- "</content>"
+ "<content version=\"1.0\" id=\"storage\">\n" +
+ " <engine>" +
+ " <proton>" +
+ " <searchable-copies>3</searchable-copies>" +
+ " </proton>" +
+ " </engine>" +
+ " <redundancy>2</redundancy>\n" +
+ " <group>" +
+ " <node hostalias='node0' distribution-key='0' />" +
+ " </group>" +
+ "</content>"
);
fail("no exception thrown");
} catch (Exception e) {
@@ -308,12 +367,12 @@ public class ClusterTest extends ContentBaseTest {
{
{
FleetcontrollerConfig config = getFleetControllerConfig(
- "<content version=\"1.0\" id=\"storage\">\n" +
- " <documents/>" +
- " <group>\n" +
- " <node distribution-key=\"0\" hostalias=\"mockhost\"/>\n" +
- " </group>\n" +
- "</content>"
+ "<content version=\"1.0\" id=\"storage\">\n" +
+ " <documents/>" +
+ " <group>\n" +
+ " <node distribution-key=\"0\" hostalias=\"mockhost\"/>\n" +
+ " </group>\n" +
+ "</content>"
);
assertEquals(0, config.min_storage_up_ratio(), 0.01);
@@ -324,17 +383,17 @@ public class ClusterTest extends ContentBaseTest {
{
FleetcontrollerConfig config = getFleetControllerConfig(
- "<content version=\"1.0\" id=\"storage\">\n" +
- " <documents/>" +
- " <group>\n" +
- " <node distribution-key=\"0\" hostalias=\"mockhost\"/>\n" +
- " <node distribution-key=\"1\" hostalias=\"mockhost\"/>\n" +
- " <node distribution-key=\"2\" hostalias=\"mockhost\"/>\n" +
- " <node distribution-key=\"3\" hostalias=\"mockhost\"/>\n" +
- " <node distribution-key=\"4\" hostalias=\"mockhost\"/>\n" +
- " <node distribution-key=\"5\" hostalias=\"mockhost\"/>\n" +
- " </group>\n" +
- "</content>"
+ "<content version=\"1.0\" id=\"storage\">\n" +
+ " <documents/>" +
+ " <group>\n" +
+ " <node distribution-key=\"0\" hostalias=\"mockhost\"/>\n" +
+ " <node distribution-key=\"1\" hostalias=\"mockhost\"/>\n" +
+ " <node distribution-key=\"2\" hostalias=\"mockhost\"/>\n" +
+ " <node distribution-key=\"3\" hostalias=\"mockhost\"/>\n" +
+ " <node distribution-key=\"4\" hostalias=\"mockhost\"/>\n" +
+ " <node distribution-key=\"5\" hostalias=\"mockhost\"/>\n" +
+ " </group>\n" +
+ "</content>"
);
assertNotSame(0, config.min_storage_up_ratio());
@@ -345,12 +404,12 @@ public class ClusterTest extends ContentBaseTest {
public void testImplicitDistributionBits()
{
ContentCluster cluster = parse(
- "<content version=\"1.0\" id=\"storage\">\n" +
- " <documents/>" +
- " <group>\n" +
- " <node distribution-key=\"0\" hostalias=\"mockhost\"/>\n" +
- " </group>\n" +
- "</content>"
+ "<content version=\"1.0\" id=\"storage\">\n" +
+ " <documents/>" +
+ " <group>\n" +
+ " <node distribution-key=\"0\" hostalias=\"mockhost\"/>\n" +
+ " </group>\n" +
+ "</content>"
);
{
@@ -368,15 +427,15 @@ public class ClusterTest extends ContentBaseTest {
assertEquals(8, config.minsplitcount());
}
cluster = parse(
- "<content version=\"1.0\" id=\"storage\">\n" +
- " <documents/>" +
- " <engine>" +
- " <vds/>" +
- " </engine>" +
- " <group>\n" +
- " <node distribution-key=\"0\" hostalias=\"mockhost\"/>\n" +
- " </group>\n" +
- "</content>"
+ "<content version=\"1.0\" id=\"storage\">\n" +
+ " <documents/>" +
+ " <engine>" +
+ " <vds/>" +
+ " </engine>" +
+ " <group>\n" +
+ " <node distribution-key=\"0\" hostalias=\"mockhost\"/>\n" +
+ " </group>\n" +
+ "</content>"
);
{
@@ -399,15 +458,15 @@ public class ClusterTest extends ContentBaseTest {
public void testExplicitDistributionBits()
{
ContentCluster cluster = parse(
- "<content version=\"1.0\" id=\"storage\">\n" +
- " <documents/>" +
- " <group>\n" +
- " <node distribution-key=\"0\" hostalias=\"mockhost\"/>\n" +
- " </group>\n" +
- " <tuning>\n" +
- " <distribution type=\"strict\"/>\n" +
- " </tuning>\n" +
- "</content>"
+ "<content version=\"1.0\" id=\"storage\">\n" +
+ " <documents/>" +
+ " <group>\n" +
+ " <node distribution-key=\"0\" hostalias=\"mockhost\"/>\n" +
+ " </group>\n" +
+ " <tuning>\n" +
+ " <distribution type=\"strict\"/>\n" +
+ " </tuning>\n" +
+ "</content>"
);
{
@@ -425,18 +484,18 @@ public class ClusterTest extends ContentBaseTest {
assertEquals(8, config.minsplitcount());
}
cluster = parse(
- "<content version=\"1.0\" id=\"storage\">\n" +
- " <documents/>" +
- " <engine>" +
- " <vds/>" +
- " </engine>" +
- " <group>\n" +
- " <node distribution-key=\"0\" hostalias=\"mockhost\"/>\n" +
- " </group>\n" +
- " <tuning>\n" +
- " <distribution type=\"loose\"/>\n" +
- " </tuning>\n" +
- "</content>"
+ "<content version=\"1.0\" id=\"storage\">\n" +
+ " <documents/>" +
+ " <engine>" +
+ " <vds/>" +
+ " </engine>" +
+ " <group>\n" +
+ " <node distribution-key=\"0\" hostalias=\"mockhost\"/>\n" +
+ " </group>\n" +
+ " <tuning>\n" +
+ " <distribution type=\"loose\"/>\n" +
+ " </tuning>\n" +
+ "</content>"
);
{
@@ -459,16 +518,16 @@ public class ClusterTest extends ContentBaseTest {
public void testGenerateSearchNodes()
{
ContentCluster cluster = parse(
- "<content version=\"1.0\" id=\"storage\">\n" +
- " <documents/>" +
- " <engine>" +
- " <proton/>" +
- " </engine>" +
- " <group>\n" +
- " <node distribution-key=\"0\" hostalias=\"mockhost\"/>\n" +
- " <node distribution-key=\"1\" hostalias=\"mockhost\"/>\n" +
- " </group>\n" +
- "</content>"
+ "<content version=\"1.0\" id=\"storage\">\n" +
+ " <documents/>" +
+ " <engine>" +
+ " <proton/>" +
+ " </engine>" +
+ " <group>\n" +
+ " <node distribution-key=\"0\" hostalias=\"mockhost\"/>\n" +
+ " <node distribution-key=\"1\" hostalias=\"mockhost\"/>\n" +
+ " </group>\n" +
+ "</content>"
);
{
@@ -492,16 +551,16 @@ public class ClusterTest extends ContentBaseTest {
public void testAlternativeNodeSyntax()
{
ContentCluster cluster = parse(
- "<content version=\"1.0\" id=\"test\">\n" +
- " <documents/>" +
- " <engine>" +
- " <proton/>" +
- " </engine>" +
- " <nodes>\n" +
- " <node distribution-key=\"0\" hostalias=\"mockhost\"/>\n" +
- " <node distribution-key=\"1\" hostalias=\"mockhost\"/>\n" +
- " </nodes>\n" +
- "</content>"
+ "<content version=\"1.0\" id=\"test\">\n" +
+ " <documents/>" +
+ " <engine>" +
+ " <proton/>" +
+ " </engine>" +
+ " <nodes>\n" +
+ " <node distribution-key=\"0\" hostalias=\"mockhost\"/>\n" +
+ " <node distribution-key=\"1\" hostalias=\"mockhost\"/>\n" +
+ " </nodes>\n" +
+ "</content>"
);
StorDistributionConfig.Builder builder = new StorDistributionConfig.Builder();
@@ -519,13 +578,13 @@ public class ClusterTest extends ContentBaseTest {
public void testReadyWhenInitialOne() {
StorDistributionConfig.Builder builder = new StorDistributionConfig.Builder();
parse(
- "<content version=\"1.0\" id=\"storage\">\n" +
- " <documents/>" +
- " <redundancy>1</redundancy>\n" +
- " <group>\n" +
- " <node distribution-key=\"0\" hostalias=\"mockhost\"/>" +
- " </group>" +
- "</content>"
+ "<content version=\"1.0\" id=\"storage\">\n" +
+ " <documents/>" +
+ " <redundancy>1</redundancy>\n" +
+ " <group>\n" +
+ " <node distribution-key=\"0\" hostalias=\"mockhost\"/>" +
+ " </group>" +
+ "</content>"
).getConfig(builder);
StorDistributionConfig config = new StorDistributionConfig(builder);
@@ -536,16 +595,16 @@ public class ClusterTest extends ContentBaseTest {
public void testProvider(String tagName, StorServerConfig.Persistence_provider.Type.Enum type) {
ContentCluster cluster = parse(
- "<content version=\"1.0\" id=\"storage\">\n" +
- " <documents/>" +
- " <redundancy>3</redundancy>" +
- " <engine>\n" +
- " <" + tagName + "/>\n" +
- " </engine>\n" +
- " <group>\n" +
- " <node distribution-key=\"0\" hostalias=\"mockhost\"/>" +
- " </group>" +
- "</content>"
+ "<content version=\"1.0\" id=\"storage\">\n" +
+ " <documents/>" +
+ " <redundancy>3</redundancy>" +
+ " <engine>\n" +
+ " <" + tagName + "/>\n" +
+ " </engine>\n" +
+ " <group>\n" +
+ " <node distribution-key=\"0\" hostalias=\"mockhost\"/>" +
+ " </group>" +
+ "</content>"
);
{
@@ -582,11 +641,11 @@ public class ClusterTest extends ContentBaseTest {
MetricsmanagerConfig.Builder builder = new MetricsmanagerConfig.Builder();
ContentCluster cluster = parse("<content version=\"1.0\" id=\"storage\">\n" +
- " <documents/>" +
- " <group>\n" +
- " <node distribution-key=\"0\" hostalias=\"mockhost\"/>\n" +
- " </group>\n" +
- "</content>"
+ " <documents/>" +
+ " <group>\n" +
+ " <node distribution-key=\"0\" hostalias=\"mockhost\"/>\n" +
+ " </group>\n" +
+ "</content>"
);
cluster.getConfig(builder);
@@ -642,34 +701,34 @@ public class ClusterTest extends ContentBaseTest {
@Test
public void testConfiguredMetrics() throws Exception {
String xml = "" +
- "<services>" +
- "<content version=\"1.0\" id=\"storage\">\n" +
- " <redundancy>1</redundancy>\n" +
- " <documents>" +
- " <document type=\"type1\" mode='index'/>\n" +
- " <document type=\"type2\" mode='index'/>\n" +
- " </documents>" +
- " <group>\n" +
- " <node distribution-key=\"0\" hostalias=\"node0\"/>\n" +
- " </group>\n" +
- "</content>" +
- "<admin version=\"2.0\">" +
- " <logserver hostalias=\"node0\"/>" +
- " <adminserver hostalias=\"node0\"/>" +
- " <metric-consumers>" +
- " <consumer name=\"foobar\">" +
- " <metric name=\"storage.foo.bar\"/>" +
- " </consumer>" +
- " <consumer name=\"log\">" +
- " <metric name=\"extralogmetric\"/>" +
- " <metric name=\"extralogmetric3\"/>" +
- " </consumer>" +
- " <consumer name=\"fleetcontroller\">" +
- " <metric name=\"extraextra\"/>" +
- " </consumer>" +
- " </metric-consumers>" +
- "</admin>" +
- "</services>";
+ "<services>" +
+ "<content version=\"1.0\" id=\"storage\">\n" +
+ " <redundancy>1</redundancy>\n" +
+ " <documents>" +
+ " <document type=\"type1\" mode='index'/>\n" +
+ " <document type=\"type2\" mode='index'/>\n" +
+ " </documents>" +
+ " <group>\n" +
+ " <node distribution-key=\"0\" hostalias=\"node0\"/>\n" +
+ " </group>\n" +
+ "</content>" +
+ "<admin version=\"2.0\">" +
+ " <logserver hostalias=\"node0\"/>" +
+ " <adminserver hostalias=\"node0\"/>" +
+ " <metric-consumers>" +
+ " <consumer name=\"foobar\">" +
+ " <metric name=\"storage.foo.bar\"/>" +
+ " </consumer>" +
+ " <consumer name=\"log\">" +
+ " <metric name=\"extralogmetric\"/>" +
+ " <metric name=\"extralogmetric3\"/>" +
+ " </consumer>" +
+ " <consumer name=\"fleetcontroller\">" +
+ " <metric name=\"extraextra\"/>" +
+ " </consumer>" +
+ " </metric-consumers>" +
+ "</admin>" +
+ "</services>";
List<String> sds = ApplicationPackageUtils.generateSearchDefinitions("type1", "type2");
@@ -729,33 +788,33 @@ public class ClusterTest extends ContentBaseTest {
@Test
public void requireThatPreShutdownCommandIsSet() {
ContentCluster cluster = parse(
- "<content version=\"1.0\" id=\"storage\">" +
- " <documents/>" +
- " <engine>" +
- " <proton>" +
- " <flush-on-shutdown>true</flush-on-shutdown>" +
- " </proton>" +
- " </engine>" +
- " <group>" +
- " <node distribution-key=\"0\" hostalias=\"mockhost\"/>" +
- " </group>" +
- "</content>");
+ "<content version=\"1.0\" id=\"storage\">" +
+ " <documents/>" +
+ " <engine>" +
+ " <proton>" +
+ " <flush-on-shutdown>true</flush-on-shutdown>" +
+ " </proton>" +
+ " </engine>" +
+ " <group>" +
+ " <node distribution-key=\"0\" hostalias=\"mockhost\"/>" +
+ " </group>" +
+ "</content>");
assertThat(cluster.getSearch().getSearchNodes().size(), is(1));
assertTrue(cluster.getSearch().getSearchNodes().get(0).getPreShutdownCommand().isPresent());
cluster = parse(
- "<content version=\"1.0\" id=\"storage\">" +
- " <documents/>" +
- " <engine>" +
- " <proton>" +
- " <flush-on-shutdown> \n " +
- " true </flush-on-shutdown>" +
- " </proton>" +
- " </engine>" +
- " <group>" +
- " <node distribution-key=\"0\" hostalias=\"mockhost\"/>" +
- " </group>" +
- "</content>");
+ "<content version=\"1.0\" id=\"storage\">" +
+ " <documents/>" +
+ " <engine>" +
+ " <proton>" +
+ " <flush-on-shutdown> \n " +
+ " true </flush-on-shutdown>" +
+ " </proton>" +
+ " </engine>" +
+ " <group>" +
+ " <node distribution-key=\"0\" hostalias=\"mockhost\"/>" +
+ " </group>" +
+ "</content>");
assertThat(cluster.getSearch().getSearchNodes().size(), is(1));
assertTrue(cluster.getSearch().getSearchNodes().get(0).getPreShutdownCommand().isPresent());
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/test/utils/VespaModelCreatorWithMockPkg.java b/config-model/src/test/java/com/yahoo/vespa/model/test/utils/VespaModelCreatorWithMockPkg.java
index 6f4effe0319..2f83d3bc394 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/test/utils/VespaModelCreatorWithMockPkg.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/test/utils/VespaModelCreatorWithMockPkg.java
@@ -55,12 +55,13 @@ public class VespaModelCreatorWithMockPkg {
VespaModel model = new VespaModel(configModelRegistry, deployState);
if (validate) {
try {
- SchemaValidator validator = SchemaValidator.createTestValidatorHosts();
if (appPkg.getHosts() != null) {
- validator.validate(appPkg.getHosts());
+ SchemaValidator.createTestValidatorHosts().validate(appPkg.getHosts());
}
- validator = SchemaValidator.createTestValidatorServices();
- validator.validate(appPkg.getServices());
+ if (appPkg.getDeployment().isPresent()) {
+ SchemaValidator.createTestValidatorDeployment().validate(appPkg.getDeployment().get());
+ }
+ SchemaValidator.createTestValidatorServices().validate(appPkg.getServices());
} catch (Exception e) {
System.err.println(e.getClass());
throw e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e);