summaryrefslogtreecommitdiffstats
path: root/config-model-api/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'config-model-api/src/main')
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstanceSpec.java (renamed from config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstancesSpec.java)34
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java89
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java50
3 files changed, 97 insertions, 76 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/DeploymentInstanceSpec.java
index 344f3438804..1fc3a8af2eb 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/DeploymentInstanceSpec.java
@@ -18,14 +18,14 @@ import java.util.Set;
import java.util.stream.Collectors;
/**
- * The deployment spec for some specified application instances
+ * The deployment spec for an application instance
*
* @author bratseth
*/
-public class DeploymentInstancesSpec extends DeploymentSpec.Step {
+public class DeploymentInstanceSpec extends DeploymentSpec.Step {
- /** The instances deployed in this step */
- private final List<InstanceName> ids;
+ /** The name of the instance this step deploys */
+ private final InstanceName name;
private final List<DeploymentSpec.Step> steps;
private final DeploymentSpec.UpgradePolicy upgradePolicy;
@@ -36,16 +36,16 @@ public class DeploymentInstancesSpec extends DeploymentSpec.Step {
private final Notifications notifications;
private final List<Endpoint> endpoints;
- 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.ids = List.copyOf(ids);
+ public DeploymentInstanceSpec(InstanceName name,
+ 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.name = name;
this.steps = List.copyOf(completeSteps(new ArrayList<>(steps)));
this.upgradePolicy = upgradePolicy;
this.changeBlockers = changeBlockers;
@@ -59,7 +59,7 @@ public class DeploymentInstancesSpec extends DeploymentSpec.Step {
validateAthenz();
}
- public List<InstanceName> names() { return ids; }
+ public InstanceName name() { return name; }
/** Adds missing required steps and reorders steps to a permissible order */
private static List<DeploymentSpec.Step> completeSteps(List<DeploymentSpec.Step> steps) {
@@ -255,7 +255,7 @@ public class DeploymentInstancesSpec extends DeploymentSpec.Step {
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
- DeploymentInstancesSpec other = (DeploymentInstancesSpec) o;
+ DeploymentInstanceSpec other = (DeploymentInstanceSpec) o;
return globalServiceId.equals(other.globalServiceId) &&
upgradePolicy == other.upgradePolicy &&
changeBlockers.equals(other.changeBlockers) &&
@@ -273,7 +273,7 @@ public class DeploymentInstancesSpec extends DeploymentSpec.Step {
@Override
public String toString() {
- return "instance" + ( ids.size() < 1 ? " " : "s " ) + ids;
+ return "instance '" + name + "'";
}
}
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 e54371e714d..db383a1bea5 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
@@ -13,13 +13,10 @@ import java.io.FileReader;
import java.io.Reader;
import java.time.Duration;
import java.time.Instant;
-import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
-import java.util.Set;
import java.util.stream.Collectors;
/**
@@ -67,15 +64,15 @@ public class DeploymentSpec {
Optional<AthenzDomain> athenzDomain, Optional<AthenzService> athenzService,
Notifications notifications,
List<Endpoint> endpoints) {
- this(List.of(new DeploymentInstancesSpec(List.of(InstanceName.from("default")),
- steps,
- upgradePolicy,
- changeBlockers,
- globalServiceId,
- athenzDomain,
- athenzService,
- notifications,
- endpoints)),
+ this(List.of(new DeploymentInstanceSpec(InstanceName.from("default"),
+ steps,
+ upgradePolicy,
+ changeBlockers,
+ globalServiceId,
+ athenzDomain,
+ athenzService,
+ notifications,
+ endpoints)),
majorVersion,
xmlForm);
}
@@ -89,18 +86,11 @@ public class DeploymentSpec {
}
// TODO: Remove after October 2019
- private DeploymentInstancesSpec defaultInstance() {
- if (hasDefaultInstanceStepOnly()) return (DeploymentInstancesSpec)steps.get(0);
+ private DeploymentInstanceSpec defaultInstance() {
+ if (instances().size() == 1) return (DeploymentInstanceSpec)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. Content: " +
- steps.stream().map(Step::toString).collect(Collectors.joining(",")));
- }
-
- // TODO: Remove after October 2019
- private boolean hasDefaultInstanceStepOnly() {
- return steps.size() == 1
- && (steps.get(0) instanceof DeploymentInstancesSpec)
- && ((DeploymentInstancesSpec)steps.get(0)).names().equals(List.of(InstanceName.from("default")));
+ "as it has multiple instances: " +
+ instances().stream().map(Step::toString).collect(Collectors.joining(",")));
}
// TODO: Remove after October 2019
@@ -112,61 +102,86 @@ public class DeploymentSpec {
/** Returns the major version this application is pinned to, or empty (default) to allow all major versions */
public Optional<Integer> majorVersion() { return majorVersion; }
- // TODO: Remove after October 2019
+ // TODO: Remove after November 2019
public boolean canUpgradeAt(Instant instant) { return defaultInstance().canUpgradeAt(instant); }
- // TODO: Remove after October 2019
+ // TODO: Remove after November 2019
public boolean canChangeRevisionAt(Instant instant) { return defaultInstance().canChangeRevisionAt(instant); }
- // TODO: Remove after October 2019
+ // TODO: Remove after November 2019
public List<ChangeBlocker> changeBlocker() { return defaultInstance().changeBlocker(); }
/** Returns the deployment steps of this in the order they will be performed */
public List<Step> steps() {
- if (hasDefaultInstanceStepOnly()) return defaultInstance().steps(); // TODO: Remove line after October 2019
+ if (steps.size() == 1) return defaultInstance().steps(); // TODO: Remove line after November 2019
return steps;
}
- // TODO: Remove after October 2019
+ // TODO: Remove after November 2019
public List<DeclaredZone> zones() {
return defaultInstance().steps().stream()
.flatMap(step -> step.zones().stream())
.collect(Collectors.toList());
}
- // TODO: Remove after October 2019
+ // TODO: Remove after November 2019
public Optional<AthenzDomain> athenzDomain() { return defaultInstance().athenzDomain(); }
- // TODO: Remove after October 2019
+ // TODO: Remove after November 2019
public Optional<AthenzService> athenzService(Environment environment, RegionName region) {
return defaultInstance().athenzService(environment, region);
}
- // TODO: Remove after October 2019
+ // TODO: Remove after November 2019
public Notifications notifications() { return defaultInstance().notifications(); }
- // TODO: Remove after October 2019
+ // TODO: Remove after November 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
+ // TODO: Remove after November 2019
public boolean includes(Environment environment, Optional<RegionName> region) {
return defaultInstance().deploysTo(environment, region);
}
/** Returns the instance step containing the given instance name, or null if not present */
- public DeploymentInstancesSpec instance(String name) {
+ public DeploymentInstanceSpec instance(String name) {
+ return instance(InstanceName.from(name));
+ }
+
+ /** Returns the instance step containing the given instance name, or null if not present */
+ public DeploymentInstanceSpec instance(InstanceName name) {
for (Step step : steps) {
- if ( ! (step instanceof DeploymentInstancesSpec)) continue;
- DeploymentInstancesSpec instanceStep = (DeploymentInstancesSpec)step;
- if (instanceStep.names().contains(InstanceName.from(name)))
+ if ( ! (step instanceof DeploymentInstanceSpec)) continue;
+ DeploymentInstanceSpec instanceStep = (DeploymentInstanceSpec)step;
+ if (instanceStep.name().equals(name))
return instanceStep;
}
return null;
}
+ /** Returns the instance step containing the given instance name, or throws an IllegalArgumentException if not present */
+ public DeploymentInstanceSpec requireInstance(String name) {
+ return requireInstance(InstanceName.from(name));
+ }
+
+ public DeploymentInstanceSpec requireInstance(InstanceName name) {
+ DeploymentInstanceSpec instance = instance(name);
+ if (instance == null)
+ throw new IllegalArgumentException("No instance '" + name + "' in deployment.xml'. Instances: " +
+ instances().stream().map(spec -> spec.name().toString()).collect(Collectors.joining(",")));
+ return instance;
+ }
+
+ /** Returns the steps of this which are instances */
+ public List<DeploymentInstanceSpec> instances() {
+ return steps.stream()
+ .filter(step -> step instanceof DeploymentInstanceSpec).map(DeploymentInstanceSpec.class::cast)
+ .collect(Collectors.toList());
+ }
+
/**
* Creates a deployment spec from XML.
*
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 acecb320b83..4d6495482ea 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,7 +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.DeploymentInstanceSpec;
import com.yahoo.config.application.api.DeploymentSpec;
import com.yahoo.config.application.api.DeploymentSpec.DeclaredZone;
import com.yahoo.config.application.api.DeploymentSpec.Delay;
@@ -53,6 +53,7 @@ public class DeploymentSpecXmlReader {
private static final String endpointTag = "endpoint";
private static final String athenzServiceAttribute = "athenz-service";
+ private static final String athenzDomainAttribute = "athenz-domain";
private static final String testerFlavorAttribute = "tester-flavor";
private final boolean validate;
@@ -86,7 +87,7 @@ public class DeploymentSpecXmlReader {
List<Step> steps = new ArrayList<>();
if ( ! hasChildTag(instanceTag, root)) { // deployment spec skipping explicit instance -> "default" instance
- steps.add(readInstanceContent("default", root));
+ steps.addAll(readInstanceContent("default", root, root));
}
else {
if (hasChildTag(prodTag, root))
@@ -96,7 +97,7 @@ public class DeploymentSpecXmlReader {
for (Element topLevelTag : XML.getChildren(root)) {
if (topLevelTag.getTagName().equals(instanceTag))
- steps.add(readInstanceContent(topLevelTag.getAttribute("id"), topLevelTag));
+ steps.addAll(readInstanceContent(topLevelTag.getAttribute("id"), topLevelTag, root));
else
steps.addAll(readNonInstanceSteps(topLevelTag, new MutableOptional<>(), topLevelTag)); // (No global service id here)
}
@@ -110,33 +111,38 @@ public class DeploymentSpecXmlReader {
/**
* 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
+ * @param instanceNameString a comma-separated list of the names of the instances this is for
+ * @param instanceTag the element having the content of this instance
+ * @param parentTag the parent of instanceTag (or the same, if this instances is implicitly defined which means instanceTag is the root)
+ * @return the instances specified, one for each instance name element
*/
- private DeploymentInstancesSpec readInstanceContent(String instanceIdString, Element instanceElement) {
+ private List<DeploymentInstanceSpec> readInstanceContent(String instanceNameString, Element instanceTag, Element parentTag) {
if (validate)
- validateTagOrder(instanceElement);
+ validateTagOrder(instanceTag);
- 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);
+ Optional<AthenzDomain> athenzDomain = stringAttribute(athenzDomainAttribute, instanceTag)
+ .or(() -> stringAttribute(athenzDomainAttribute, parentTag))
+ .map(AthenzDomain::from);
+ Optional<AthenzService> athenzService = stringAttribute(athenzServiceAttribute, instanceTag)
+ .or(() -> stringAttribute(athenzServiceAttribute, parentTag))
+ .map(AthenzService::from);
List<Step> steps = new ArrayList<>();
- for (Element instanceChild : XML.getChildren(instanceElement))
+ for (Element instanceChild : XML.getChildren(instanceTag))
steps.addAll(readNonInstanceSteps(instanceChild, globalServiceId, instanceChild));
- return new DeploymentInstancesSpec(instanceNames,
- steps,
- readUpgradePolicy(instanceElement),
- readChangeBlockers(instanceElement),
- globalServiceId.asOptional(),
- athenzDomain,
- athenzService,
- readNotifications(instanceElement),
- readEndpoints(instanceElement));
+ return Arrays.stream(instanceNameString.split("'"))
+ .map(name -> new DeploymentInstanceSpec(InstanceName.from(name),
+ steps,
+ readUpgradePolicy(instanceTag),
+ readChangeBlockers(instanceTag),
+ globalServiceId.asOptional(),
+ athenzDomain,
+ athenzService,
+ readNotifications(instanceTag),
+ readEndpoints(instanceTag)))
+ .collect(Collectors.toList());
}
// 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