summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@oath.com>2018-09-25 15:51:15 -0700
committerGitHub <noreply@github.com>2018-09-25 15:51:15 -0700
commitb20c3bb6ef5a722ba879353eed2cc0d8da93ae9a (patch)
treeb60704a2560a4499a79d6f5de17bf3233b499fdb
parent0246064bbfb9657515f516e2fea12d593cd13016 (diff)
parent22b480874b1ca6400b8cd2640f678c210da07fa3 (diff)
Merge pull request #7095 from vespa-engine/bratseth/support-multiple-envs-and-regions
Allow multiple regions and environments in a single attribute
-rw-r--r--config-application-package/src/main/java/com/yahoo/config/application/OverrideProcessor.java100
-rw-r--r--config-application-package/src/main/java/com/yahoo/config/application/PreProcessor.java7
-rw-r--r--config-application-package/src/main/java/com/yahoo/config/application/PropertiesProcessor.java5
-rw-r--r--config-application-package/src/main/java/com/yahoo/config/application/XmlPreProcessor.java3
-rw-r--r--config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationPackage.java1
-rw-r--r--config-application-package/src/test/java/com/yahoo/config/application/IncludeProcessorTest.java28
-rw-r--r--config-application-package/src/test/java/com/yahoo/config/application/XmlPreprocessorTest.java66
-rw-r--r--config-application-package/src/test/resources/multienvapp/services.xml11
8 files changed, 133 insertions, 88 deletions
diff --git a/config-application-package/src/main/java/com/yahoo/config/application/OverrideProcessor.java b/config-application-package/src/main/java/com/yahoo/config/application/OverrideProcessor.java
index d68b36e063c..16accb368fd 100644
--- a/config-application-package/src/main/java/com/yahoo/config/application/OverrideProcessor.java
+++ b/config-application-package/src/main/java/com/yahoo/config/application/OverrideProcessor.java
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.config.application;
+import com.google.common.collect.ImmutableSet;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.RegionName;
import com.yahoo.log.LogLevel;
@@ -10,8 +11,16 @@ import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import javax.xml.transform.TransformerException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
import java.util.logging.Logger;
+import java.util.stream.Collectors;
/**
* Handles overrides in a XML document according to the rules defined for multi environment application packages.
@@ -23,8 +32,7 @@ import java.util.logging.Logger;
* 3. When multiple XML elements with the same name is specified (i.e. when specifying search or docproc chains),
* the id attribute of the element is used together with the element name when applying directives
*
- * @author lulf
- * @since 5.22
+ * @author Ulf Lilleengen
*/
class OverrideProcessor implements PreProcessor {
@@ -71,15 +79,13 @@ class OverrideProcessor implements PreProcessor {
}
private Context getParentContext(Element parent, Context context) {
- Optional<Environment> environment = context.environment;
- RegionName region = context.region;
- if ( ! environment.isPresent()) {
- environment = getEnvironment(parent);
- }
- if (region.isDefault()) {
- region = getRegion(parent);
- }
- return Context.create(environment, region);
+ Set<Environment> environments = context.environments;
+ Set<RegionName> regions = context.regions;
+ if (environments.isEmpty())
+ environments = getEnvironments(parent);
+ if (regions.isEmpty())
+ regions = getRegions(parent);
+ return Context.create(environments, regions);
}
/**
@@ -100,13 +106,13 @@ class OverrideProcessor implements PreProcessor {
*/
private void checkConsistentInheritance(List<Element> children, Context context) {
for (Element child : children) {
- Optional<Environment> env = getEnvironment(child);
- RegionName reg = getRegion(child);
- if (env.isPresent() && context.environment.isPresent() && !env.equals(context.environment)) {
- throw new IllegalArgumentException("Environment in child (" + env.get() + ") differs from that inherited from parent (" + context.environment + ") at " + child);
+ Set<Environment> environments = getEnvironments(child);
+ Set<RegionName> regions = getRegions(child);
+ if ( ! environments.isEmpty() && ! context.environments.isEmpty() && !environments.equals(context.environments)) {
+ throw new IllegalArgumentException("Environments in child (" + environments + ") differs from that inherited from parent (" + context.environments + ") at " + child);
}
- if (!reg.isDefault() && !context.region.isDefault() && !reg.equals(context.region)) {
- throw new IllegalArgumentException("Region in child (" + reg + ") differs from that inherited from parent (" + context.region + ") at " + child);
+ if ( ! regions.isEmpty() && ! context.regions.isEmpty() && ! regions.equals(context.regions)) {
+ throw new IllegalArgumentException("Regions in child (" + regions + ") differs from that inherited from parent (" + context.regions + ") at " + child);
}
}
}
@@ -118,22 +124,24 @@ class OverrideProcessor implements PreProcessor {
Iterator<Element> elemIt = children.iterator();
while (elemIt.hasNext()) {
Element child = elemIt.next();
- if ( ! matches(getEnvironment(child), getRegion(child))) {
+ if ( ! matches(getEnvironments(child), getRegions(child))) {
parent.removeChild(child);
elemIt.remove();
}
}
}
- private boolean matches(Optional<Environment> elementEnvironment, RegionName elementRegion) {
- if (elementEnvironment.isPresent()) { // match environment
- if (! environment.equals(elementEnvironment.get())) return false;
+ private boolean matches(Set<Environment> elementEnvironments, Set<RegionName> elementRegions) {
+ if ( ! elementEnvironments.isEmpty()) { // match environment
+ if ( ! elementEnvironments.contains(environment)) return false;
}
- if ( ! elementRegion.isDefault()) { // match region
- if ( ! region.equals(elementRegion)) return false;
- // match region but no environment in prod only to avoid a region attribute overriding capacity policies outside prod
- if ( ! elementEnvironment.isPresent() && ! environment.equals(Environment.prod)) return false;
+ if ( ! elementRegions.isEmpty()) { // match region
+ // match region in prod only
+ if ( environment.equals(Environment.prod) && ! elementRegions.contains(region)) return false;
+
+ // explicit region implies prod
+ if ( ! environment.equals(Environment.prod) && elementEnvironments.isEmpty() ) return false;
}
return true;
@@ -174,11 +182,11 @@ class OverrideProcessor implements PreProcessor {
private int getNumberOfOverrides(Element child, Context context) {
int currentMatch = 0;
- Optional<Environment> elementEnvironment = hasEnvironment(child) ? getEnvironment(child) : context.environment;
- RegionName elementRegion = hasRegion(child) ? getRegion(child) : context.region;
- if (elementEnvironment.isPresent() && elementEnvironment.get().equals(environment))
+ Set<Environment> elementEnvironments = hasEnvironment(child) ? getEnvironments(child) : context.environments;
+ Set<RegionName> elementRegions = hasRegion(child) ? getRegions(child) : context.regions;
+ if ( ! elementEnvironments.isEmpty() && elementEnvironments.contains(environment))
currentMatch++;
- if ( ! elementRegion.isDefault() && elementRegion.equals(region))
+ if ( ! elementRegions.isEmpty() && elementRegions.contains(region))
currentMatch++;
return currentMatch;
}
@@ -220,20 +228,16 @@ class OverrideProcessor implements PreProcessor {
return element.hasAttributeNS(XmlPreProcessor.deployNamespaceUri, ATTR_ENV);
}
- private Optional<Environment> getEnvironment(Element element) {
+ private Set<Environment> getEnvironments(Element element) {
String env = element.getAttributeNS(XmlPreProcessor.deployNamespaceUri, ATTR_ENV);
- if (env == null || env.isEmpty()) {
- return Optional.empty();
- }
- return Optional.of(Environment.from(env));
+ if (env == null || env.isEmpty()) return Collections.emptySet();
+ return Arrays.stream(env.split(" ")).map(Environment::from).collect(Collectors.toSet());
}
- private RegionName getRegion(Element element) {
+ private Set<RegionName> getRegions(Element element) {
String reg = element.getAttributeNS(XmlPreProcessor.deployNamespaceUri, ATTR_REG);
- if (reg == null || reg.isEmpty()) {
- return RegionName.defaultName();
- }
- return RegionName.from(reg);
+ if (reg == null || reg.isEmpty()) return Collections.emptySet();
+ return Arrays.stream(reg.split(" ")).map(RegionName::from).collect(Collectors.toSet());
}
private Map<String, List<Element>> elementsByTagNameAndId(List<Element> children) {
@@ -287,21 +291,21 @@ class OverrideProcessor implements PreProcessor {
*/
private static final class Context {
- final Optional<Environment> environment;
+ final ImmutableSet<Environment> environments;
- final RegionName region;
+ final ImmutableSet<RegionName> regions;
- private Context(Optional<Environment> environment, RegionName region) {
- this.environment = environment;
- this.region = region;
+ private Context(Set<Environment> environments, Set<RegionName> regions) {
+ this.environments = ImmutableSet.copyOf(environments);
+ this.regions = ImmutableSet.copyOf(regions);
}
static Context empty() {
- return new Context(Optional.empty(), RegionName.defaultName());
+ return new Context(ImmutableSet.of(), ImmutableSet.of());
}
- public static Context create(Optional<Environment> environment, RegionName region) {
- return new Context(environment, region);
+ public static Context create(Set<Environment> environments, Set<RegionName> regions) {
+ return new Context(environments, regions);
}
}
diff --git a/config-application-package/src/main/java/com/yahoo/config/application/PreProcessor.java b/config-application-package/src/main/java/com/yahoo/config/application/PreProcessor.java
index d331c4432bc..f207a07d3be 100644
--- a/config-application-package/src/main/java/com/yahoo/config/application/PreProcessor.java
+++ b/config-application-package/src/main/java/com/yahoo/config/application/PreProcessor.java
@@ -9,9 +9,10 @@ import java.io.IOException;
/**
* Performs pre-processing of XML document and returns new document that has been processed.
*
- * @author lulf
- * @since 5.21
+ * @author Ulf Lilleengen
*/
public interface PreProcessor {
- public Document process(Document input) throws IOException, TransformerException;
+
+ Document process(Document input) throws IOException, TransformerException;
+
}
diff --git a/config-application-package/src/main/java/com/yahoo/config/application/PropertiesProcessor.java b/config-application-package/src/main/java/com/yahoo/config/application/PropertiesProcessor.java
index 6e45460a4c4..65120c3677c 100644
--- a/config-application-package/src/main/java/com/yahoo/config/application/PropertiesProcessor.java
+++ b/config-application-package/src/main/java/com/yahoo/config/application/PropertiesProcessor.java
@@ -16,7 +16,6 @@ import java.util.logging.Logger;
* Handles getting properties from services.xml and replacing references to properties with their real values
*
* @author hmusum
- * @since 5.22
*/
class PropertiesProcessor implements PreProcessor {
private final static Logger log = Logger.getLogger(PropertiesProcessor.class.getName());
@@ -82,8 +81,8 @@ class PropertiesProcessor implements PreProcessor {
}
private String replaceValue(String propertyValue) {
- /* Use a list with keys sorted by length (longest key first)
- Needed for replacing values where you have overlapping keys */
+ // Use a list with keys sorted by length (longest key first)
+ // Needed for replacing values where you have overlapping keys
ArrayList<String> keys = new ArrayList<>(properties.keySet());
Collections.sort(keys, Collections.reverseOrder(Comparator.comparing(String::length)));
diff --git a/config-application-package/src/main/java/com/yahoo/config/application/XmlPreProcessor.java b/config-application-package/src/main/java/com/yahoo/config/application/XmlPreProcessor.java
index ceef0a6730e..0bb160319c0 100644
--- a/config-application-package/src/main/java/com/yahoo/config/application/XmlPreProcessor.java
+++ b/config-application-package/src/main/java/com/yahoo/config/application/XmlPreProcessor.java
@@ -22,7 +22,6 @@ import java.util.List;
* and create a new Document which is based on the supplied environment and region
*
* @author hmusum
- * @since 5.22
*/
public class XmlPreProcessor {
@@ -51,7 +50,7 @@ public class XmlPreProcessor {
public Document run() throws ParserConfigurationException, IOException, SAXException, TransformerException {
DocumentBuilder docBuilder = Xml.getPreprocessDocumentBuilder();
- final Document document = docBuilder.parse(new InputSource(xmlInput));
+ Document document = docBuilder.parse(new InputSource(xmlInput));
return execute(document);
}
diff --git a/config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationPackage.java b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationPackage.java
index 7ca9bcf48f3..1724bad765f 100644
--- a/config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationPackage.java
+++ b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationPackage.java
@@ -305,6 +305,7 @@ public class FilesApplicationPackage implements ApplicationPackage {
/**
* Verify that two sets of search definitions are disjoint (TODO: everything except error message is very generic).
+ *
* @param fileSds Set of search definitions from file
* @param bundleSds Set of search definitions from bundles
*/
diff --git a/config-application-package/src/test/java/com/yahoo/config/application/IncludeProcessorTest.java b/config-application-package/src/test/java/com/yahoo/config/application/IncludeProcessorTest.java
index d3c2b672ee5..a456924673d 100644
--- a/config-application-package/src/test/java/com/yahoo/config/application/IncludeProcessorTest.java
+++ b/config-application-package/src/test/java/com/yahoo/config/application/IncludeProcessorTest.java
@@ -13,44 +13,48 @@ import java.io.*;
import java.nio.file.NoSuchFileException;
/**
- * @author lulf
- * @since 5.22
+ * @author Ulf Lilleengen
*/
public class IncludeProcessorTest {
@Test
- public void testInclude() throws IOException, SAXException, XMLStreamException, ParserConfigurationException, TransformerException {
+ public void testInclude() throws IOException, SAXException, ParserConfigurationException, TransformerException {
File app = new File("src/test/resources/multienvapp");
DocumentBuilder docBuilder = Xml.getPreprocessDocumentBuilder();
- String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><services xmlns:deploy=\"vespa\" xmlns:preprocess=\"properties\" version=\"1.0\">\n" +
+ String expected =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" +
+ "<services xmlns:deploy=\"vespa\" xmlns:preprocess=\"properties\" version=\"1.0\">\n" +
" <preprocess:properties>\n" +
" <qrs.port>4099</qrs.port>\n" +
" <qrs.port>5000</qrs.port>\n" +
" </preprocess:properties>\n" +
" <preprocess:properties deploy:environment='prod'>\n" +
" <qrs.port deploy:region='us-west'>5001</qrs.port>" +
- " <qrs.port deploy:region='us-east'>5002</qrs.port>" +
+ " <qrs.port deploy:region='us-east us-central'>5002</qrs.port>" +
" </preprocess:properties>\n" +
" <admin version=\"2.0\">\n" +
" <adminserver hostalias=\"node0\"/>\n" +
" </admin>\n" +
- " <admin deploy:environment=\"prod\" version=\"2.0\">\n" +
+ " <admin deploy:environment=\"staging prod\" deploy:region=\"us-east us-central\" version=\"2.0\">\n" +
" <adminserver hostalias=\"node1\"/>\n" +
" </admin>\n" +
" <content id=\"foo\" version=\"1.0\">\n" +
" <redundancy>1</redundancy><documents>\n" +
" <document mode=\"index\" type=\"music.sd\"/>\n" +
- "</documents><nodes>\n" +
+ " </documents><nodes>\n" +
" <node distribution-key=\"0\" hostalias=\"node0\"/>\n" +
- "</nodes><nodes deploy:environment=\"prod\">\n" +
+ " </nodes>" +
+ " <nodes deploy:environment=\"prod\">\n" +
" <node distribution-key=\"0\" hostalias=\"node0\"/>\n" +
" <node distribution-key=\"1\" hostalias=\"node1\"/>\n" +
- "</nodes><nodes deploy:environment=\"prod\" deploy:region=\"us-west\">\n" +
+ " </nodes>" +
+ " <nodes deploy:environment=\"prod\" deploy:region=\"us-west\">\n" +
" <node distribution-key=\"0\" hostalias=\"node0\"/>\n" +
" <node distribution-key=\"1\" hostalias=\"node1\"/>\n" +
" <node distribution-key=\"2\" hostalias=\"node2\"/>\n" +
- "</nodes></content>\n" +
+ " </nodes>" +
+ "</content>\n" +
"<jdisc id=\"stateless\" version=\"1.0\">\n" +
" <search deploy:environment=\"prod\">\n" +
" <chain id=\"common\">\n" +
@@ -68,7 +72,7 @@ public class IncludeProcessorTest {
" </nodes>\n" +
"</jdisc></services>";
- Document doc = (new IncludeProcessor(app)).process(docBuilder.parse(Xml.getServices(app)));
+ Document doc = new IncludeProcessor(app).process(docBuilder.parse(Xml.getServices(app)));
// System.out.println(Xml.documentAsString(doc));
TestBase.assertDocument(expected, doc);
}
@@ -77,7 +81,7 @@ public class IncludeProcessorTest {
public void testRequiredIncludeIsDefault() throws ParserConfigurationException, IOException, SAXException, TransformerException {
File app = new File("src/test/resources/multienvapp_failrequired");
DocumentBuilder docBuilder = Xml.getPreprocessDocumentBuilder();
- (new IncludeProcessor(app)).process(docBuilder.parse(Xml.getServices(app)));
+ new IncludeProcessor(app).process(docBuilder.parse(Xml.getServices(app)));
}
}
diff --git a/config-application-package/src/test/java/com/yahoo/config/application/XmlPreprocessorTest.java b/config-application-package/src/test/java/com/yahoo/config/application/XmlPreprocessorTest.java
index b20437bc259..3827fe2ad42 100644
--- a/config-application-package/src/test/java/com/yahoo/config/application/XmlPreprocessorTest.java
+++ b/config-application-package/src/test/java/com/yahoo/config/application/XmlPreprocessorTest.java
@@ -23,8 +23,10 @@ public class XmlPreprocessorTest {
private static final File services = new File(appDir, "services.xml");
@Test
- public void testPreProcessing() throws IOException, SAXException, XMLStreamException, ParserConfigurationException, TransformerException {
- String expectedDev = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><services xmlns:deploy=\"vespa\" xmlns:preprocess=\"properties\" version=\"1.0\">\n" +
+ public void testPreProcessing() throws IOException, SAXException, ParserConfigurationException, TransformerException {
+ String expectedDev =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" +
+ "<services xmlns:deploy=\"vespa\" xmlns:preprocess=\"properties\" version=\"1.0\">\n" +
" <admin version=\"2.0\">\n" +
" <adminserver hostalias=\"node0\"/>\n" +
" </admin>\n" +
@@ -46,14 +48,40 @@ public class XmlPreprocessorTest {
" </nodes>\n" +
" </jdisc>\n" +
"</services>";
+ TestBase.assertDocument(expectedDev, new XmlPreProcessor(appDir, services, Environment.dev, RegionName.from("default")).run());
- Document docDev = (new XmlPreProcessor(appDir, services, Environment.dev, RegionName.from("default")).run());
- TestBase.assertDocument(expectedDev, docDev);
-
+ String expectedStaging =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" +
+ "<services xmlns:deploy=\"vespa\" xmlns:preprocess=\"properties\" version=\"1.0\">\n" +
+ " <admin version=\"2.0\">\n" +
+ " <adminserver hostalias=\"node1\"/>\n" + // Difference from dev: node1
+ " </admin>\n" +
+ " <content id=\"foo\" version=\"1.0\">\n" +
+ " <redundancy>1</redundancy>\n" +
+ " <documents>\n" +
+ " <document mode=\"index\" type=\"music.sd\"/>\n" +
+ " </documents>\n" +
+ " <nodes>\n" +
+ " <node distribution-key=\"0\" hostalias=\"node0\"/>\n" +
+ " </nodes>\n" +
+ " </content>\n" +
+ " <jdisc id=\"stateless\" version=\"1.0\">\n" +
+ " <search/>\n" +
+ " <component bundle=\"foobundle\" class=\"MyFoo\" id=\"foo\"/>\n" +
+ "" + // Difference from dev: no TestBar
+ " <nodes>\n" +
+ " <node hostalias=\"node0\" baseport=\"5000\"/>\n" +
+ " </nodes>\n" +
+ " </jdisc>\n" +
+ "</services>";
+ // System.out.println(Xml.documentAsString(new XmlPreProcessor(appDir, services, Environment.staging, RegionName.from("default")).run()));
+ TestBase.assertDocument(expectedStaging, new XmlPreProcessor(appDir, services, Environment.staging, RegionName.from("default")).run());
- String expectedUsWest = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><services xmlns:deploy=\"vespa\" xmlns:preprocess=\"properties\" version=\"1.0\">\n" +
+ String expectedUsWest =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" +
+ "<services xmlns:deploy=\"vespa\" xmlns:preprocess=\"properties\" version=\"1.0\">\n" +
" <admin version=\"2.0\">\n" +
- " <adminserver hostalias=\"node1\"/>\n" +
+ " <adminserver hostalias=\"node0\"/>\n" +
" </admin>\n" +
" <content id=\"foo\" version=\"1.0\">\n" +
" <redundancy>1</redundancy>\n" +
@@ -81,12 +109,11 @@ public class XmlPreprocessorTest {
" </nodes>\n" +
" </jdisc>\n" +
"</services>";
+ TestBase.assertDocument(expectedUsWest, new XmlPreProcessor(appDir, services, Environment.prod, RegionName.from("us-west")).run());
- Document docUsWest = (new XmlPreProcessor(appDir, services, Environment.prod, RegionName.from("us-west"))).run();
- // System.out.println(Xml.documentAsString(docUsWest));
- TestBase.assertDocument(expectedUsWest, docUsWest);
-
- String expectedUsEast = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><services xmlns:deploy=\"vespa\" xmlns:preprocess=\"properties\" version=\"1.0\">\n" +
+ String expectedUsEastAndCentral =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" +
+ "<services xmlns:deploy=\"vespa\" xmlns:preprocess=\"properties\" version=\"1.0\">\n" +
" <admin version=\"2.0\">\n" +
" <adminserver hostalias=\"node1\"/>\n" +
" </admin>\n" +
@@ -115,14 +142,16 @@ public class XmlPreprocessorTest {
" </nodes>\n" +
" </jdisc>\n" +
"</services>";
-
- Document docUsEast = (new XmlPreProcessor(appDir, services, Environment.prod, RegionName.from("us-east"))).run();
- TestBase.assertDocument(expectedUsEast, docUsEast);
+ TestBase.assertDocument(expectedUsEastAndCentral,
+ new XmlPreProcessor(appDir, services, Environment.prod, RegionName.from("us-east")).run());
+ TestBase.assertDocument(expectedUsEastAndCentral,
+ new XmlPreProcessor(appDir, services, Environment.prod, RegionName.from("us-central")).run());
}
@Test
- public void testPropertiesWithOverlappingNames() throws IOException, SAXException, XMLStreamException, ParserConfigurationException, TransformerException {
- String input = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" +
+ public void testPropertiesWithOverlappingNames() throws IOException, SAXException, ParserConfigurationException, TransformerException {
+ String input =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" +
"<services xmlns:deploy=\"vespa\" xmlns:preprocess=\"properties\" version=\"1.0\">" +
" <preprocess:properties>" +
" <sherpa.host>gamma-usnc1.dht.yahoo.com</sherpa.host>" +
@@ -146,7 +175,8 @@ public class XmlPreprocessorTest {
" </admin>" +
"</services>";
- String expectedProd = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" +
+ String expectedProd =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" +
"<services xmlns:deploy=\"vespa\" xmlns:preprocess=\"properties\" version=\"1.0\">" +
" <config name='a'>" +
" <a>36000</a>" +
diff --git a/config-application-package/src/test/resources/multienvapp/services.xml b/config-application-package/src/test/resources/multienvapp/services.xml
index 3d4a2087c57..d0f43f0b025 100644
--- a/config-application-package/src/test/resources/multienvapp/services.xml
+++ b/config-application-package/src/test/resources/multienvapp/services.xml
@@ -1,5 +1,6 @@
<!-- Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
<services version='1.0' xmlns:deploy="vespa" xmlns:preprocess="properties">
+
<preprocess:properties>
<qrs.port>4099</qrs.port>
<qrs.port>5000</qrs.port>
@@ -7,17 +8,23 @@
<preprocess:properties deploy:environment='prod'>
<qrs.port deploy:region='us-west'>5001</qrs.port>
- <qrs.port deploy:region='us-east'>5002</qrs.port>
+ <qrs.port deploy:region='us-east us-central'>5002</qrs.port>
</preprocess:properties>
+
<admin version='2.0'>
<adminserver hostalias='node0'/>
</admin>
- <admin version='2.0' deploy:environment='prod'>
+
+ <admin version='2.0' deploy:environment='staging prod' deploy:region='us-east us-central'>
<adminserver hostalias='node1'/>
</admin>
+
<preprocess:include file='jdisc.xml'/>
+
<content version='1.0' id='foo'>
<preprocess:include file='content/content_foo.xml'/>
</content>
+
<preprocess:include file='doesnotexist.xml' required='false' />
+
</services>