From 2e5310deae9e7ecc9f6e6776dc717abde8dda5d4 Mon Sep 17 00:00:00 2001 From: Jon Marius Venstad Date: Fri, 18 Feb 2022 13:45:10 +0100 Subject: Split revision target and when to change settings in deployment spec --- .../application/api/DeploymentInstanceSpec.java | 24 +++++++----- .../config/application/api/DeploymentSpec.java | 21 ++++++++--- .../api/xml/DeploymentSpecXmlReader.java | 43 ++++++++++++++++------ 3 files changed, 62 insertions(+), 26 deletions(-) (limited to 'config-model-api/src/main/java/com') diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstanceSpec.java b/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstanceSpec.java index ea38860c29b..e701f3903cb 100644 --- a/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstanceSpec.java +++ b/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstanceSpec.java @@ -31,7 +31,8 @@ public class DeploymentInstanceSpec extends DeploymentSpec.Steps { private final InstanceName name; private final DeploymentSpec.UpgradePolicy upgradePolicy; - private final DeploymentSpec.UpgradeRevision upgradeRevision; + private final DeploymentSpec.RevisionTarget revisionTarget; + private final DeploymentSpec.RevisionChange revisionChange; private final DeploymentSpec.UpgradeRollout upgradeRollout; private final List changeBlockers; private final Optional globalServiceId; @@ -42,7 +43,8 @@ public class DeploymentInstanceSpec extends DeploymentSpec.Steps { public DeploymentInstanceSpec(InstanceName name, List steps, DeploymentSpec.UpgradePolicy upgradePolicy, - DeploymentSpec.UpgradeRevision upgradeRevision, + DeploymentSpec.RevisionTarget revisionTarget, + DeploymentSpec.RevisionChange revisionChange, DeploymentSpec.UpgradeRollout upgradeRollout, List changeBlockers, Optional globalServiceId, @@ -53,7 +55,8 @@ public class DeploymentInstanceSpec extends DeploymentSpec.Steps { super(steps); this.name = name; this.upgradePolicy = upgradePolicy; - this.upgradeRevision = upgradeRevision; + this.revisionTarget = revisionTarget; + this.revisionChange = revisionChange; this.upgradeRollout = upgradeRollout; this.changeBlockers = changeBlockers; this.globalServiceId = globalServiceId; @@ -150,13 +153,16 @@ public class DeploymentInstanceSpec extends DeploymentSpec.Steps { return true; } - /** Returns the upgrade policy of this, which is defaultPolicy if none is specified */ + /** Returns the upgrade policy of this, which is {@link DeploymentSpec.UpgradePolicy#defaultPolicy} by default */ public DeploymentSpec.UpgradePolicy upgradePolicy() { return upgradePolicy; } - /** Returns the upgrade revision strategy of this, which is separate if none is specified */ - public DeploymentSpec.UpgradeRevision upgradeRevision() { return upgradeRevision; } + /** Returns the revision target choice of this, which is {@link DeploymentSpec.RevisionTarget#latest} by default */ + public DeploymentSpec.RevisionTarget revisionTarget() { return revisionTarget; } - /** Returns the upgrade rollout strategy of this, which is separate if none is specified */ + /** Returns the revision change strategy of this, which is {@link DeploymentSpec.RevisionChange#whenFailing} by default */ + public DeploymentSpec.RevisionChange revisionChange() { return revisionChange; } + + /** Returns the upgrade rollout strategy of this, which is {@link DeploymentSpec.UpgradeRollout#separate} by default */ public DeploymentSpec.UpgradeRollout upgradeRollout() { return upgradeRollout; } /** Returns time windows where upgrades are disallowed for these instances */ @@ -204,7 +210,7 @@ public class DeploymentInstanceSpec extends DeploymentSpec.Steps { DeploymentInstanceSpec other = (DeploymentInstanceSpec) o; return globalServiceId.equals(other.globalServiceId) && upgradePolicy == other.upgradePolicy && - upgradeRevision == other.upgradeRevision && + revisionTarget == other.revisionTarget && upgradeRollout == other.upgradeRollout && changeBlockers.equals(other.changeBlockers) && steps().equals(other.steps()) && @@ -215,7 +221,7 @@ public class DeploymentInstanceSpec extends DeploymentSpec.Steps { @Override public int hashCode() { - return Objects.hash(globalServiceId, upgradePolicy, upgradeRevision, upgradeRollout, changeBlockers, steps(), athenzService, notifications, endpoints); + return Objects.hash(globalServiceId, upgradePolicy, revisionTarget, upgradeRollout, changeBlockers, steps(), athenzService, notifications, endpoints); } @Override 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 3a66fb0c1a5..96e3ba75a38 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 @@ -550,14 +550,23 @@ public class DeploymentSpec { } - /** Determines when application changes deploy, when an older revision is already rolling out. */ - public enum UpgradeRevision { - /** Exclusive: Application changes are rolled one at a time through this instance, even when they fail. */ - exclusive, + /** Determines what application changes to deploy to the instance. */ + public enum RevisionTarget { + /** Next: Application changes are rolled through this instance in the same manner as they become ready. */ + next, + /** Latest: Application changes are merged, so the latest available is always chosen for roll-out. */ + latest + } + + + /** Determines when application changes deploy. */ + public enum RevisionChange { + /** Exclusive: Application changes always wait for already rolling application changes to complete. */ + whenClear, /** Separate: Application changes wait for already rolling application changes to complete, unless they fail. */ - separate, + whenFailing, /** Latest: Application changes immediately supersede previous application changes, unless currently blocked. */ - latest + always } 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 fdd7733a5f6..050fba1cd2f 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 @@ -165,7 +165,8 @@ public class DeploymentSpecXmlReader { // Values where the parent may provide a default DeploymentSpec.UpgradePolicy upgradePolicy = readUpgradePolicy(instanceTag, parentTag); - DeploymentSpec.UpgradeRevision upgradeRevision = readUpgradeRevision(instanceTag, parentTag); + DeploymentSpec.RevisionTarget revisionTarget = readRevisionTarget(instanceTag, parentTag); + DeploymentSpec.RevisionChange revisionChange = readRevisionChange(instanceTag, parentTag); DeploymentSpec.UpgradeRollout upgradeRollout = readUpgradeRollout(instanceTag, parentTag); List changeBlockers = readChangeBlockers(instanceTag, parentTag); Optional athenzService = mostSpecificAttribute(instanceTag, athenzServiceAttribute).map(AthenzService::from); @@ -184,7 +185,8 @@ public class DeploymentSpecXmlReader { .map(name -> new DeploymentInstanceSpec(InstanceName.from(name), steps, upgradePolicy, - upgradeRevision, + revisionTarget, + revisionChange, upgradeRollout, changeBlockers, globalServiceId.asOptional(), @@ -474,23 +476,42 @@ public class DeploymentSpecXmlReader { } } - private DeploymentSpec.UpgradeRevision readUpgradeRevision(Element parent, Element fallbackParent) { + private DeploymentSpec.RevisionChange readRevisionChange(Element parent, Element fallbackParent) { Element upgradeElement = XML.getChild(parent, upgradeTag); if (upgradeElement == null) upgradeElement = XML.getChild(fallbackParent, upgradeTag); if (upgradeElement == null) - return DeploymentSpec.UpgradeRevision.separate; + return DeploymentSpec.RevisionChange.whenFailing; - String revision = upgradeElement.getAttribute("revision"); + String revision = upgradeElement.getAttribute("revision-change"); if (revision.isEmpty()) - return DeploymentSpec.UpgradeRevision.separate; + return DeploymentSpec.RevisionChange.whenFailing; switch (revision) { - case "exclusive": return DeploymentSpec.UpgradeRevision.exclusive; - case "separate": return DeploymentSpec.UpgradeRevision.separate; - case "latest": return DeploymentSpec.UpgradeRevision.latest; - default: throw new IllegalArgumentException("Illegal upgrade revision '" + revision + "': " + - "Must be one of " + Arrays.toString(DeploymentSpec.UpgradeRevision.values())); + case "when-clear": return DeploymentSpec.RevisionChange.whenClear; + case "when-failing": return DeploymentSpec.RevisionChange.whenFailing; + case "always": return DeploymentSpec.RevisionChange.always; + default: throw new IllegalArgumentException("Illegal upgrade revision change policy '" + revision + "': " + + "Must be one of " + Arrays.toString(DeploymentSpec.RevisionTarget.values())); + } + } + + private DeploymentSpec.RevisionTarget readRevisionTarget(Element parent, Element fallbackParent) { + Element upgradeElement = XML.getChild(parent, upgradeTag); + if (upgradeElement == null) + upgradeElement = XML.getChild(fallbackParent, upgradeTag); + if (upgradeElement == null) + return DeploymentSpec.RevisionTarget.latest; + + String revision = upgradeElement.getAttribute("revision-target"); + if (revision.isEmpty()) + return DeploymentSpec.RevisionTarget.latest; + + switch (revision) { + case "next": return DeploymentSpec.RevisionTarget.next; + case "latest": return DeploymentSpec.RevisionTarget.latest; + default: throw new IllegalArgumentException("Illegal upgrade revision target '" + revision + "': " + + "Must be one of " + Arrays.toString(DeploymentSpec.RevisionTarget.values())); } } -- cgit v1.2.3