summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@verizonmedia.com>2019-10-03 15:27:26 +0200
committerJon Bratseth <bratseth@verizonmedia.com>2019-10-03 15:27:26 +0200
commitdef6fe944d8717802b2ab67246b1cbb78b5afab9 (patch)
tree13f0bd97210e56dcc52626d34c23acd8b91d8b0a
parent27411b5dc5fa85ba259948b205397097042febe7 (diff)
Basic support for explicit instance
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstancesSpec.java32
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java60
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java182
-rw-r--r--config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java118
4 files changed, 231 insertions, 161 deletions
diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstancesSpec.java b/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstancesSpec.java
index 13e7ba91049..344f3438804 100644
--- a/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstancesSpec.java
+++ b/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstancesSpec.java
@@ -25,7 +25,7 @@ import java.util.stream.Collectors;
public class DeploymentInstancesSpec extends DeploymentSpec.Step {
/** The instances deployed in this step */
- private final List<InstanceName> names;
+ private final List<InstanceName> ids;
private final List<DeploymentSpec.Step> steps;
private final DeploymentSpec.UpgradePolicy upgradePolicy;
@@ -33,30 +33,33 @@ public class DeploymentInstancesSpec extends DeploymentSpec.Step {
private final Optional<String> globalServiceId;
private final Optional<AthenzDomain> athenzDomain;
private final Optional<AthenzService> athenzService;
+ private final Notifications notifications;
private final List<Endpoint> endpoints;
- public DeploymentInstancesSpec(List<InstanceName> names,
+ public DeploymentInstancesSpec(List<InstanceName> ids,
List<DeploymentSpec.Step> steps,
DeploymentSpec.UpgradePolicy upgradePolicy,
List<DeploymentSpec.ChangeBlocker> changeBlockers,
Optional<String> globalServiceId,
Optional<AthenzDomain> athenzDomain,
Optional<AthenzService> athenzService,
+ Notifications notifications,
List<Endpoint> endpoints) {
- this.names = List.copyOf(names);
+ this.ids = List.copyOf(ids);
this.steps = List.copyOf(completeSteps(new ArrayList<>(steps)));
this.upgradePolicy = upgradePolicy;
this.changeBlockers = changeBlockers;
this.globalServiceId = globalServiceId;
this.athenzDomain = athenzDomain;
this.athenzService = athenzService;
+ this.notifications = notifications;
this.endpoints = List.copyOf(validateEndpoints(endpoints, this.steps));
validateZones(this.steps);
validateEndpoints(this.steps, globalServiceId, this.endpoints);
validateAthenz();
}
- public List<InstanceName> names() { return names; }
+ public List<InstanceName> names() { return ids; }
/** Adds missing required steps and reorders steps to a permissible order */
private static List<DeploymentSpec.Step> completeSteps(List<DeploymentSpec.Step> steps) {
@@ -222,9 +225,6 @@ public class DeploymentInstancesSpec extends DeploymentSpec.Step {
return false;
}
- /** Returns the rotations configuration of these instances */
- public List<Endpoint> endpoints() { return endpoints; }
-
/** Returns the athenz domain if configured */
public Optional<AthenzDomain> athenzDomain() { return athenzDomain; }
@@ -237,6 +237,13 @@ public class DeploymentInstancesSpec extends DeploymentSpec.Step {
.orElse(this.athenzService.orElse(null));
return Optional.ofNullable(athenzService);
}
+
+ /** Returns the notification configuration of these instances */
+ public Notifications notifications() { return notifications; }
+
+ /** Returns the rotations configuration of these instances */
+ public List<Endpoint> endpoints() { return endpoints; }
+
/** Returns whether this instances deployment specifies the given zone, either implicitly or explicitly */
public boolean includes(Environment environment, Optional<RegionName> region) {
for (DeploymentSpec.Step step : steps)
@@ -254,12 +261,19 @@ public class DeploymentInstancesSpec extends DeploymentSpec.Step {
changeBlockers.equals(other.changeBlockers) &&
steps.equals(other.steps) &&
athenzDomain.equals(other.athenzDomain) &&
- athenzService.equals(other.athenzService);
+ athenzService.equals(other.athenzService) &&
+ notifications.equals(other.notifications) &&
+ endpoints.equals(other.endpoints);
}
@Override
public int hashCode() {
- return Objects.hash(globalServiceId, upgradePolicy, changeBlockers, steps, athenzDomain, athenzService);
+ return Objects.hash(globalServiceId, upgradePolicy, changeBlockers, steps, athenzDomain, athenzService, notifications, endpoints);
+ }
+
+ @Override
+ public String toString() {
+ return "instance" + ( ids.size() < 1 ? " " : "s " ) + ids;
}
}
diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java b/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java
index 7a554cbb749..4079fbf2fbb 100644
--- a/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java
+++ b/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java
@@ -49,16 +49,13 @@ public class DeploymentSpec {
List.of());
private final List<Step> steps;
- private final Notifications notifications;
private final Optional<Integer> majorVersion;
private final String xmlForm;
public DeploymentSpec(List<Step> steps,
- Notifications notifications,
Optional<Integer> majorVersion,
String xmlForm) {
this.steps = steps;
- this.notifications = notifications;
this.majorVersion = majorVersion;
this.xmlForm = xmlForm;
validateTotalDelay(steps);
@@ -77,8 +74,8 @@ public class DeploymentSpec {
globalServiceId,
athenzDomain,
athenzService,
+ notifications,
endpoints)),
- notifications,
majorVersion,
xmlForm);
}
@@ -95,7 +92,8 @@ public class DeploymentSpec {
private DeploymentInstancesSpec defaultInstance() {
if (hasDefaultInstanceStepOnly()) return (DeploymentInstancesSpec)steps.get(0);
throw new IllegalArgumentException("This deployment spec does not support the legacy API " +
- "as it does not consist only of a default instance");
+ "as it does not consist only of a default instance. Content: " +
+ steps.stream().map(Step::toString).collect(Collectors.joining(",")));
}
// TODO: Remove after October 2019
@@ -136,31 +134,28 @@ public class DeploymentSpec {
.collect(Collectors.toList());
}
- /** Returns the notification configuration */
- public Notifications notifications() { return notifications; }
-
- /** Returns the rotations configuration */
- // TODO: Remove after October 2019
- public List<Endpoint> endpoints() { return defaultInstance().endpoints(); }
-
- /** Returns the athenz domain if configured */
// TODO: Remove after October 2019
public Optional<AthenzDomain> athenzDomain() { return defaultInstance().athenzDomain(); }
- /** Returns the athenz service for environment/region if configured */
// TODO: Remove after October 2019
public Optional<AthenzService> athenzService(Environment environment, RegionName region) {
return defaultInstance().athenzService(environment, region);
}
// TODO: Remove after October 2019
- public boolean includes(Environment environment, Optional<RegionName> region) {
- return defaultInstance().deploysTo(environment, region);
- }
+ public Notifications notifications() { return defaultInstance().notifications(); }
+
+ // TODO: Remove after October 2019
+ public List<Endpoint> endpoints() { return defaultInstance().endpoints(); }
/** Returns the XML form of this spec, or null if it was not created by fromXml, nor is empty */
public String xmlForm() { return xmlForm; }
+ // TODO: Remove after October 2019
+ public boolean includes(Environment environment, Optional<RegionName> region) {
+ return defaultInstance().deploysTo(environment, region);
+ }
+
/**
* Creates a deployment spec from XML.
*
@@ -212,13 +207,12 @@ public class DeploymentSpec {
DeploymentSpec other = (DeploymentSpec) o;
return majorVersion.equals(other.majorVersion) &&
steps.equals(other.steps) &&
- xmlForm.equals(other.xmlForm) &&
- notifications.equals(other.notifications);
+ xmlForm.equals(other.xmlForm);
}
@Override
public int hashCode() {
- return Objects.hash(majorVersion, steps, xmlForm, notifications);
+ return Objects.hash(majorVersion, steps, xmlForm);
}
/** This may be invoked by a continuous build */
@@ -361,21 +355,30 @@ public class DeploymentSpec {
}
- /** A deployment step which is to run deployment to multiple zones in parallel */
+ /** A deployment step which is to run multiple steps (zones or instances) in parallel */
public static class ParallelZones extends Step {
- private final List<DeclaredZone> zones;
+ private final List<Step> steps;
- public ParallelZones(List<DeclaredZone> zones) {
- this.zones = List.copyOf(zones);
+ public ParallelZones(List<Step> steps) {
+ this.steps = List.copyOf(steps);
}
+ /** Returns the steps inside this which are zones */
@Override
- public List<DeclaredZone> zones() { return this.zones; }
+ public List<DeclaredZone> zones() {
+ return this.steps.stream()
+ .filter(step -> step instanceof DeclaredZone)
+ .map(DeclaredZone.class::cast)
+ .collect(Collectors.toList());
+ }
+
+ /** Returns all the steps nested in this */
+ public List<Step> steps() { return steps; }
@Override
public boolean deploysTo(Environment environment, Optional<RegionName> region) {
- return zones.stream().anyMatch(zone -> zone.deploysTo(environment, region));
+ return zones().stream().anyMatch(zone -> zone.deploysTo(environment, region));
}
@Override
@@ -383,13 +386,14 @@ public class DeploymentSpec {
if (this == o) return true;
if (!(o instanceof ParallelZones)) return false;
ParallelZones that = (ParallelZones) o;
- return Objects.equals(zones, that.zones);
+ return Objects.equals(steps, that.steps);
}
@Override
public int hashCode() {
- return Objects.hash(zones);
+ return Objects.hash(steps);
}
+
}
/** Controls when this application will be upgraded to new Vespa versions */
diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java b/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java
index 72a806bb7be..acecb320b83 100644
--- a/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java
+++ b/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.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.api.xml;
+import com.yahoo.config.application.api.DeploymentInstancesSpec;
import com.yahoo.config.application.api.DeploymentSpec;
import com.yahoo.config.application.api.DeploymentSpec.DeclaredZone;
import com.yahoo.config.application.api.DeploymentSpec.Delay;
@@ -14,6 +15,7 @@ import com.yahoo.config.application.api.TimeWindow;
import com.yahoo.config.provision.AthenzDomain;
import com.yahoo.config.provision.AthenzService;
import com.yahoo.config.provision.Environment;
+import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.RegionName;
import com.yahoo.io.IOUtils;
import com.yahoo.text.XML;
@@ -38,27 +40,32 @@ import java.util.stream.Collectors;
*/
public class DeploymentSpecXmlReader {
+ private static final String instanceTag = "instance";
private static final String majorVersionTag = "major-version";
private static final String testTag = "test";
private static final String stagingTag = "staging";
private static final String blockChangeTag = "block-change";
private static final String prodTag = "prod";
+ private static final String regionTag = "region";
+ private static final String delayTag = "delay";
+ private static final String parallelTag = "parallel";
private static final String endpointsTag = "endpoints";
private static final String endpointTag = "endpoint";
+ private static final String athenzServiceAttribute = "athenz-service";
+ private static final String testerFlavorAttribute = "tester-flavor";
+
private final boolean validate;
- /**
- * Creates a validating reader
- */
+ /** Creates a validating reader */
public DeploymentSpecXmlReader() {
this(true);
}
/**
- * Creates a reader
+ * Creates a deployment spec reader
*
- * @param validate true to validate the input, false to accept any input which can be unabiguously parsed
+ * @param validate true to validate the input, false to accept any input which can be unambiguously parsed
*/
public DeploymentSpecXmlReader(boolean validate) {
this.validate = validate;
@@ -73,63 +80,102 @@ public class DeploymentSpecXmlReader {
}
}
- /**
- * Reads a deployment spec from XML
- */
+ /** Reads a deployment spec from XML */
public DeploymentSpec read(String xmlForm) {
- List<Step> steps = new ArrayList<>();
- Optional<String> globalServiceId = Optional.empty();
Element root = XML.getDocument(xmlForm).getDocumentElement();
- if (validate)
- validateTagOrder(root);
- for (Element environmentTag : XML.getChildren(root)) {
- if (!isEnvironmentName(environmentTag.getTagName())) continue;
-
- Environment environment = Environment.from(environmentTag.getTagName());
- Optional<AthenzService> athenzService = stringAttribute("athenz-service", environmentTag).map(AthenzService::from);
- Optional<String> testerFlavor = stringAttribute("tester-flavor", environmentTag);
-
- if (environment == Environment.prod) {
- for (Element stepTag : XML.getChildren(environmentTag)) {
- if (stepTag.getTagName().equals("delay")) {
- steps.add(new Delay(Duration.ofSeconds(longAttribute("hours", stepTag) * 60 * 60 +
- longAttribute("minutes", stepTag) * 60 +
- longAttribute("seconds", stepTag))));
- }
- else if (stepTag.getTagName().equals("parallel")) {
- List<DeclaredZone> zones = new ArrayList<>();
- for (Element regionTag : XML.getChildren(stepTag)) {
- zones.add(readDeclaredZone(environment, athenzService, testerFlavor, regionTag));
- }
- steps.add(new ParallelZones(zones));
- }
- else { // a region: deploy step
- steps.add(readDeclaredZone(environment, athenzService, testerFlavor, stepTag));
- }
- }
- }
- else {
- steps.add(new DeclaredZone(environment, Optional.empty(), false, athenzService, testerFlavor));
+
+ List<Step> steps = new ArrayList<>();
+ if ( ! hasChildTag(instanceTag, root)) { // deployment spec skipping explicit instance -> "default" instance
+ steps.add(readInstanceContent("default", root));
+ }
+ else {
+ if (hasChildTag(prodTag, root))
+ throw new IllegalArgumentException("A deployment spec cannot have both a <prod> tag and an " +
+ "<instance> tag under the root: " +
+ "Wrap the prod tags inside the appropriate instance");
+
+ for (Element topLevelTag : XML.getChildren(root)) {
+ if (topLevelTag.getTagName().equals(instanceTag))
+ steps.add(readInstanceContent(topLevelTag.getAttribute("id"), topLevelTag));
+ else
+ steps.addAll(readNonInstanceSteps(topLevelTag, new MutableOptional<>(), topLevelTag)); // (No global service id here)
}
+ }
+
+ return new DeploymentSpec(steps,
+ optionalIntegerAttribute(majorVersionTag, root),
+ xmlForm);
+ }
+
+ /**
+ * Reads the content of an (implicit or explicit) instance tag producing an instances step
+ *
+ * @param instanceIdString a comma-separated list of the ids of the instance id(s) this is for
+ * @param instanceElement the element having the content of this instance
+ */
+ private DeploymentInstancesSpec readInstanceContent(String instanceIdString, Element instanceElement) {
+ if (validate)
+ validateTagOrder(instanceElement);
- if (environment == Environment.prod)
- globalServiceId = readGlobalServiceId(environmentTag);
- else if (readGlobalServiceId(environmentTag).isPresent())
- throw new IllegalArgumentException("Attribute 'global-service-id' is only valid on 'prod' tag.");
+ List<InstanceName> instanceNames = Arrays.stream(instanceIdString.split("'"))
+ .map(InstanceName::from)
+ .collect(Collectors.toList());
+ MutableOptional<String> globalServiceId = new MutableOptional<>(); // Deprecated: Set of prod, but belongs to instance
+ Optional<AthenzDomain> athenzDomain = stringAttribute("athenz-domain", instanceElement).map(AthenzDomain::from);
+ Optional<AthenzService> athenzService = stringAttribute("athenz-service", instanceElement).map(AthenzService::from);
+ List<Step> steps = new ArrayList<>();
+ for (Element instanceChild : XML.getChildren(instanceElement))
+ steps.addAll(readNonInstanceSteps(instanceChild, globalServiceId, instanceChild));
+
+ return new DeploymentInstancesSpec(instanceNames,
+ steps,
+ readUpgradePolicy(instanceElement),
+ readChangeBlockers(instanceElement),
+ globalServiceId.asOptional(),
+ athenzDomain,
+ athenzService,
+ readNotifications(instanceElement),
+ readEndpoints(instanceElement));
+ }
+
+ // Consume the give tag as 0-N steps. 0 if it is not a step, >1 if it contains multiple nested steps that should be flattened
+ private List<Step> readNonInstanceSteps(Element stepTag, MutableOptional<String> globalServiceId, Element parentTag) {
+ Optional<AthenzService> athenzService = stringAttribute(athenzServiceAttribute, stepTag)
+ .or(() -> stringAttribute(athenzServiceAttribute, parentTag))
+ .map(AthenzService::from);
+ Optional<String> testerFlavor = stringAttribute(testerFlavorAttribute, stepTag)
+ .or(() -> stringAttribute(testerFlavorAttribute, parentTag));
+
+ if (prodTag.equals(stepTag.getTagName()))
+ globalServiceId.set(readGlobalServiceId(stepTag));
+ else if (readGlobalServiceId(stepTag).isPresent())
+ throw new IllegalArgumentException("Attribute 'global-service-id' is only valid on 'prod' tag.");
+
+ switch (stepTag.getTagName()) {
+ case testTag: case stagingTag:
+ return List.of(new DeclaredZone(Environment.from(stepTag.getTagName()), Optional.empty(), false, athenzService, testerFlavor));
+ case prodTag: // regions, delay and parallel may be nested within, but we can flatten them
+ return XML.getChildren(stepTag).stream()
+ .flatMap(child -> readNonInstanceSteps(child, globalServiceId, stepTag).stream())
+ .collect(Collectors.toList());
+ case delayTag:
+ return List.of(new Delay(Duration.ofSeconds(longAttribute("hours", stepTag) * 60 * 60 +
+ longAttribute("minutes", stepTag) * 60 +
+ longAttribute("seconds", stepTag))));
+ case parallelTag: // regions and instances may be nested within
+ return List.of(new ParallelZones(XML.getChildren(stepTag).stream()
+ .flatMap(child -> readNonInstanceSteps(child, globalServiceId, stepTag).stream())
+ .collect(Collectors.toList())));
+ case regionTag:
+ return List.of(readDeclaredZone(Environment.prod, athenzService, testerFlavor, stepTag));
+ default:
+ return List.of();
}
- Optional<AthenzDomain> athenzDomain = stringAttribute("athenz-domain", root).map(AthenzDomain::from);
- Optional<AthenzService> athenzService = stringAttribute("athenz-service", root).map(AthenzService::from);
- return new DeploymentSpec(globalServiceId,
- readUpgradePolicy(root),
- optionalIntegerAttribute(majorVersionTag, root),
- readChangeBlockers(root),
- steps,
- xmlForm,
- athenzDomain,
- athenzService,
- readNotifications(root),
- readEndpoints(root));
+ }
+
+ private boolean hasChildTag(String childTagName, Element parent) {
+ return XML.getChildren(parent).stream().anyMatch(child -> child.getTagName().equals(childTagName));
}
private Notifications readNotifications(Element root) {
@@ -159,15 +205,15 @@ public class DeploymentSpecXmlReader {
}
private List<Endpoint> readEndpoints(Element root) {
- final var endpointsElement = XML.getChild(root, endpointsTag);
+ var endpointsElement = XML.getChild(root, endpointsTag);
if (endpointsElement == null) { return Collections.emptyList(); }
- final var endpoints = new LinkedHashMap<String, Endpoint>();
+ var endpoints = new LinkedHashMap<String, Endpoint>();
for (var endpointElement : XML.getChildren(endpointsElement, endpointTag)) {
- final Optional<String> rotationId = stringAttribute("id", endpointElement);
- final Optional<String> containerId = stringAttribute("container-id", endpointElement);
- final var regions = new HashSet<String>();
+ Optional<String> rotationId = stringAttribute("id", endpointElement);
+ Optional<String> containerId = stringAttribute("container-id", endpointElement);
+ var regions = new HashSet<String>();
if (containerId.isEmpty()) {
throw new IllegalArgumentException("Missing 'container-id' from 'endpoint' tag.");
@@ -255,10 +301,6 @@ public class DeploymentSpecXmlReader {
return Optional.ofNullable(value).filter(s -> !s.equals(""));
}
- private boolean isEnvironmentName(String tagName) {
- return tagName.equals(testTag) || tagName.equals(stagingTag) || tagName.equals(prodTag);
- }
-
private DeclaredZone readDeclaredZone(Environment environment, Optional<AthenzService> athenzService,
Optional<String> testerFlavor, Element regionTag) {
return new DeclaredZone(environment, Optional.of(RegionName.from(XML.getValue(regionTag).trim())),
@@ -324,4 +366,14 @@ public class DeploymentSpecXmlReader {
"to control whether the region should receive production traffic");
}
+ private static class MutableOptional<T> {
+
+ private Optional<T> value = Optional.empty();
+
+ public void set(Optional<T> value) { this.value = value; }
+
+ public Optional<T> asOptional() { return value; }
+
+ }
+
}
diff --git a/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java b/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java
index 694917e1bff..c99a3be7303 100644
--- a/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java
+++ b/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java
@@ -32,9 +32,9 @@ public class DeploymentSpecTest {
@Test
public void testSpec() {
String specXml = "<deployment version='1.0'>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <test/>" +
- " </instances>" +
+ " </instance>" +
"</deployment>";
StringReader r = new StringReader(specXml);
@@ -53,9 +53,9 @@ public class DeploymentSpecTest {
@Test
public void testSpecPinningMajorVersion() {
String specXml = "<deployment version='1.0' major-version='6'>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <test/>" +
- " </instances>" +
+ " </instance>" +
"</deployment>";
StringReader r = new StringReader(specXml);
@@ -70,9 +70,9 @@ public class DeploymentSpecTest {
public void stagingSpec() {
StringReader r = new StringReader(
"<deployment version='1.0'>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <staging/>" +
- " </instances>" +
+ " </instance>" +
"</deployment>"
);
@@ -91,12 +91,12 @@ public class DeploymentSpecTest {
public void minimalProductionSpec() {
StringReader r = new StringReader(
"<deployment version='1.0'>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <prod>" +
" <region active='false'>us-east1</region>" +
" <region active='true'>us-west1</region>" +
" </prod>" +
- " </instances>" +
+ " </instance>" +
"</deployment>"
);
@@ -128,7 +128,7 @@ public class DeploymentSpecTest {
public void maximalProductionSpec() {
StringReader r = new StringReader(
"<deployment version='1.0'>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <test/>" +
" <staging/>" +
" <prod>" +
@@ -136,7 +136,7 @@ public class DeploymentSpecTest {
" <delay hours='3' minutes='30'/>" +
" <region active='true'>us-west1</region>" +
" </prod>" +
- " </instances>" +
+ " </instance>" +
"</deployment>"
);
@@ -170,12 +170,12 @@ public class DeploymentSpecTest {
public void productionSpecWithGlobalServiceId() {
StringReader r = new StringReader(
"<deployment version='1.0'>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <prod global-service-id='query'>" +
" <region active='true'>us-east-1</region>" +
" <region active='true'>us-west-1</region>" +
" </prod>" +
- " </instances>" +
+ " </instance>" +
"</deployment>"
);
@@ -187,9 +187,9 @@ public class DeploymentSpecTest {
public void globalServiceIdInTest() {
StringReader r = new StringReader(
"<deployment version='1.0'>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <test global-service-id='query' />" +
- " </instances>" +
+ " </instance>" +
"</deployment>"
);
DeploymentSpec spec = DeploymentSpec.fromXml(r);
@@ -199,9 +199,9 @@ public class DeploymentSpecTest {
public void globalServiceIdInStaging() {
StringReader r = new StringReader(
"<deployment version='1.0'>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <staging global-service-id='query' />" +
- " </instances>" +
+ " </instance>" +
"</deployment>"
);
DeploymentSpec spec = DeploymentSpec.fromXml(r);
@@ -211,7 +211,7 @@ public class DeploymentSpecTest {
public void productionSpecWithGlobalServiceIdBeforeStaging() {
StringReader r = new StringReader(
"<deployment>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <test/>" +
" <prod global-service-id='qrs'>" +
" <region active='true'>us-west-1</region>" +
@@ -219,7 +219,7 @@ public class DeploymentSpecTest {
" <region active='true'>us-east-3</region>" +
" </prod>" +
" <staging/>" +
- " </instances>" +
+ " </instance>" +
"</deployment>"
);
@@ -231,14 +231,14 @@ public class DeploymentSpecTest {
public void productionSpecWithUpgradePolicy() {
StringReader r = new StringReader(
"<deployment>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <upgrade policy='canary'/>" +
" <prod>" +
" <region active='true'>us-west-1</region>" +
" <region active='true'>us-central-1</region>" +
" <region active='true'>us-east-3</region>" +
" </prod>" +
- " </instances>" +
+ " </instance>" +
"</deployment>"
);
@@ -251,7 +251,7 @@ public class DeploymentSpecTest {
try {
StringReader r = new StringReader(
"<deployment>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <upgrade policy='canary'/>" +
" <prod>" +
" <region active='true'>us-west-1</region>" +
@@ -260,7 +260,7 @@ public class DeploymentSpecTest {
" <delay minutes='59' seconds='61'/>" +
" <region active='true'>us-east-3</region>" +
" </prod>" +
- " </instances>" +
+ " </instance>" +
"</deployment>"
);
DeploymentSpec.fromXml(r);
@@ -284,7 +284,7 @@ public class DeploymentSpecTest {
public void productionSpecWithParallelDeployments() {
StringReader r = new StringReader(
"<deployment>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <prod>" +
" <region active='true'>us-west-1</region>" +
" <parallel>" +
@@ -292,7 +292,7 @@ public class DeploymentSpecTest {
" <region active='true'>us-east-3</region>" +
" </parallel>" +
" </prod>" +
- " </instances>" +
+ " </instance>" +
"</deployment>"
);
DeploymentSpec spec = DeploymentSpec.fromXml(r);
@@ -306,7 +306,7 @@ public class DeploymentSpecTest {
public void productionSpecWithDuplicateRegions() {
StringReader r = new StringReader(
"<deployment>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <prod>" +
" <region active='true'>us-west-1</region>" +
" <parallel>" +
@@ -315,7 +315,7 @@ public class DeploymentSpecTest {
" <region active='true'>us-east-3</region>" +
" </parallel>" +
" </prod>" +
- " </instances>" +
+ " </instance>" +
"</deployment>"
);
try {
@@ -330,13 +330,13 @@ public class DeploymentSpecTest {
public void deploymentSpecWithIllegallyOrderedDeploymentSpec1() {
StringReader r = new StringReader(
"<deployment>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <block-change days='sat' hours='10' time-zone='CET'/>" +
" <prod>" +
" <region active='true'>us-west-1</region>" +
" </prod>" +
" <block-change days='mon,tue' hours='15-16'/>" +
- " </instances>" +
+ " </instance>" +
"</deployment>"
);
DeploymentSpec spec = DeploymentSpec.fromXml(r);
@@ -346,13 +346,13 @@ public class DeploymentSpecTest {
public void deploymentSpecWithIllegallyOrderedDeploymentSpec2() {
StringReader r = new StringReader(
"<deployment>\n" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <block-change days='sat' hours='10' time-zone='CET'/>" +
" <test/>" +
" <prod>" +
" <region active='true'>us-west-1</region>" +
" </prod>" +
- " </instances>" +
+ " </instance>" +
"</deployment>"
);
DeploymentSpec spec = DeploymentSpec.fromXml(r);
@@ -362,13 +362,13 @@ public class DeploymentSpecTest {
public void deploymentSpecWithChangeBlocker() {
StringReader r = new StringReader(
"<deployment>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <block-change revision='false' days='mon,tue' hours='15-16'/>" +
" <block-change days='sat' hours='10' time-zone='CET'/>" +
" <prod>" +
" <region active='true'>us-west-1</region>" +
" </prod>" +
- " </instances>" +
+ " </instance>" +
"</deployment>"
);
DeploymentSpec spec = DeploymentSpec.fromXml(r);
@@ -395,11 +395,11 @@ public class DeploymentSpecTest {
public void athenz_config_is_disallowed_on_deployment_if_instances() {
StringReader r = new StringReader(
"<deployment athenz-domain='domain' athenz-service='service''>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <prod>" +
" <region active='true'>us-west-1</region>" +
" </prod>" +
- " </instances>" +
+ " </instance>" +
"</deployment>"
);
DeploymentSpec spec = DeploymentSpec.fromXml(r);
@@ -408,12 +408,12 @@ public class DeploymentSpecTest {
@Test
public void athenz_config_is_read_from_instance() {
StringReader r = new StringReader(
- "<deployment'>" +
- " <instances name='default' athenz-domain='domain' athenz-service='service'>" +
+ "<deployment>" +
+ " <instance id='default' athenz-domain='domain' athenz-service='service'>" +
" <prod>" +
" <region active='true'>us-west-1</region>" +
" </prod>" +
- " </instances>" +
+ " </instance>" +
"</deployment>"
);
DeploymentSpec spec = DeploymentSpec.fromXml(r);
@@ -425,12 +425,12 @@ public class DeploymentSpecTest {
public void athenz_service_is_overridden_from_environment() {
StringReader r = new StringReader(
"<deployment athenz-domain='domain' athenz-service='service'>" +
- " <instances name='default' athenz-domain='domain' athenz-service='service'>" +
+ " <instance id='default' athenz-domain='domain' athenz-service='service'>" +
" <test/>" +
" <prod athenz-service='prod-service'>" +
" <region active='true'>us-west-1</region>" +
" </prod>" +
- " </instances>" +
+ " </instance>" +
"</deployment>"
);
DeploymentSpec spec = DeploymentSpec.fromXml(r);
@@ -442,11 +442,11 @@ public class DeploymentSpecTest {
public void it_fails_when_athenz_service_is_not_defined() {
StringReader r = new StringReader(
"<deployment>" +
- " <instances name='default' athenz-domain='domain'>" +
+ " <instance id='default' athenz-domain='domain'>" +
" <prod>" +
" <region active='true'>us-west-1</region>" +
" </prod>" +
- " </instances>" +
+ " </instance>" +
"</deployment>"
);
DeploymentSpec spec = DeploymentSpec.fromXml(r);
@@ -456,11 +456,11 @@ public class DeploymentSpecTest {
public void it_fails_when_athenz_service_is_configured_but_not_athenz_domain() {
StringReader r = new StringReader(
"<deployment>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <prod athenz-service='service'>" +
" <region active='true'>us-west-1</region>" +
" </prod>" +
- " </instances>" +
+ " </instance>" +
"</deployment>"
);
DeploymentSpec spec = DeploymentSpec.fromXml(r);
@@ -470,16 +470,16 @@ public class DeploymentSpecTest {
public void noNotifications() {
assertEquals(Notifications.none(),
DeploymentSpec.fromXml("<deployment>" +
- " <instances name='default'/>" +
+ " <instance id='default'/>" +
"</deployment>").notifications());
}
@Test
public void emptyNotifications() {
DeploymentSpec spec = DeploymentSpec.fromXml("<deployment>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <notifications/>" +
- " </instances>" +
+ " </instance>" +
"</deployment>");
assertEquals(Notifications.none(),
spec.notifications());
@@ -488,13 +488,13 @@ public class DeploymentSpecTest {
@Test
public void someNotifications() {
DeploymentSpec spec = DeploymentSpec.fromXml("<deployment>\n" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <notifications when=\"failing\">" +
" <email role=\"author\"/>" +
" <email address=\"john@dev\" when=\"failing-commit\"/>" +
" <email address=\"jane@dev\"/>" +
" </notifications>" +
- " </instances>" +
+ " </instance>" +
"</deployment>");
assertEquals(ImmutableSet.of(author), spec.notifications().emailRolesFor(failing));
assertEquals(ImmutableSet.of(author), spec.notifications().emailRolesFor(failingCommit));
@@ -505,12 +505,12 @@ public class DeploymentSpecTest {
@Test
public void customTesterFlavor() {
DeploymentSpec spec = DeploymentSpec.fromXml("<deployment>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <test tester-flavor=\"d-1-4-20\" />" +
" <prod tester-flavor=\"d-2-8-50\">" +
" <region active=\"false\">us-north-7</region>" +
" </prod>" +
- " </instances>" +
+ " </instance>" +
"</deployment>");
assertEquals(Optional.of("d-1-4-20"), spec.steps().get(0).zones().get(0).testerFlavor());
assertEquals(Optional.empty(), spec.steps().get(1).zones().get(0).testerFlavor());
@@ -521,16 +521,16 @@ public class DeploymentSpecTest {
public void noEndpoints() {
assertEquals(Collections.emptyList(),
DeploymentSpec.fromXml("<deployment>" +
- " <instances name='default'/>" +
+ " <instance id='default'/>" +
"</deployment>").endpoints());
}
@Test
public void emptyEndpoints() {
var spec = DeploymentSpec.fromXml("<deployment>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <endpoints/>" +
- " </instances>" +
+ " </instance>" +
"</deployment>");
assertEquals(Collections.emptyList(), spec.endpoints());
}
@@ -539,7 +539,7 @@ public class DeploymentSpecTest {
public void someEndpoints() {
var spec = DeploymentSpec.fromXml("" +
"<deployment>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <prod>" +
" <region active=\"true\">us-east</region>" +
" </prod>" +
@@ -550,7 +550,7 @@ public class DeploymentSpecTest {
" <endpoint id=\"nalle\" container-id=\"frosk\" />" +
" <endpoint container-id=\"quux\" />" +
" </endpoints>" +
- " </instances>" +
+ " </instance>" +
"</deployment>");
assertEquals(
@@ -593,7 +593,7 @@ public class DeploymentSpecTest {
public void endpointDefaultRegions() {
var spec = DeploymentSpec.fromXml("" +
"<deployment>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <prod>" +
" <region active=\"true\">us-east</region>" +
" <region active=\"true\">us-west</region>" +
@@ -605,7 +605,7 @@ public class DeploymentSpecTest {
" <endpoint id=\"nalle\" container-id=\"frosk\" />" +
" <endpoint container-id=\"quux\" />" +
" </endpoints>" +
- " </instances>" +
+ " </instance>" +
"</deployment>");
assertEquals(Set.of("us-east"), endpointRegions("foo", spec));
@@ -630,14 +630,14 @@ public class DeploymentSpecTest {
private static List<String> endpointIds(String endpointTag) {
var xml = "<deployment>" +
- " <instances name='default'>" +
+ " <instance id='default'>" +
" <prod>" +
" <region active=\"true\">us-east</region>" +
" </prod>" +
" <endpoints>" +
endpointTag +
" </endpoints>" +
- " </instances>" +
+ " </instance>" +
"</deployment>";
return DeploymentSpec.fromXml(xml).endpoints().stream()