diff options
author | Jon Marius Venstad <venstad@gmail.com> | 2022-02-21 21:55:10 +0100 |
---|---|---|
committer | Jon Marius Venstad <venstad@gmail.com> | 2022-02-22 12:20:27 +0100 |
commit | 2aa8213873330a461e9b49ae257d01eb08648495 (patch) | |
tree | f56c05271df57e0d06add5ced348b970f11cd08a /config-model-api | |
parent | 96916710a1b46cbed64f15345e56a3a68df235f5 (diff) |
Do not roll out new application package with pure deployment orchestration changes
Diffstat (limited to 'config-model-api')
4 files changed, 164 insertions, 3 deletions
diff --git a/config-model-api/abi-spec.json b/config-model-api/abi-spec.json index 4635070fee8..db85fd47a43 100644 --- a/config-model-api/abi-spec.json +++ b/config-model-api/abi-spec.json @@ -445,7 +445,8 @@ "public static com.yahoo.config.application.api.DeploymentSpec fromXml(java.lang.String, boolean)", "public static java.lang.String toMessageString(java.lang.Throwable)", "public boolean equals(java.lang.Object)", - "public int hashCode()" + "public int hashCode()", + "public int deployableHashCode()" ], "fields": [ "public static final com.yahoo.config.application.api.DeploymentSpec empty" 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 e701f3903cb..677933f3b85 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 @@ -9,14 +9,21 @@ import com.yahoo.config.provision.RegionName; import java.time.Duration; import java.time.Instant; import java.time.temporal.ChronoUnit; +import java.util.Arrays; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; +import static com.yahoo.config.provision.Environment.prod; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toSet; + /** * The deployment spec for an application instance * @@ -224,6 +231,19 @@ public class DeploymentInstanceSpec extends DeploymentSpec.Steps { return Objects.hash(globalServiceId, upgradePolicy, revisionTarget, upgradeRollout, changeBlockers, steps(), athenzService, notifications, endpoints); } + int deployableHashCode() { + List<DeploymentSpec.DeclaredZone> zones = zones().stream().filter(zone -> zone.concerns(prod)).collect(toList()); + Object[] toHash = new Object[zones.size() + 3]; + int i = 0; + toHash[i++] = name; + toHash[i++] = endpoints; + toHash[i++] = globalServiceId; + for (DeploymentSpec.DeclaredZone zone : zones) + toHash[i++] = Objects.hash(zone, zone.athenzService()); + + return Arrays.hashCode(toHash); + } + @Override public String toString() { 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 96e3ba75a38..9135e9f49ff 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 @@ -11,6 +11,7 @@ import com.yahoo.config.provision.RegionName; import java.io.Reader; import java.time.Duration; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -285,6 +286,19 @@ public class DeploymentSpec { return Objects.hash(majorVersion, steps, xmlForm); } + /** Computes a hash of all fields that influence what is deployed with this spec, i.e., not orchestration. */ + public int deployableHashCode() { + Object[] toHash = new Object[instances().size() + 3]; + int i = 0; + toHash[i++] = athenzDomain; + toHash[i++] = athenzService; + toHash[i++] = endpoints; + for (DeploymentInstanceSpec instance : instances()) + toHash[i++] = instance.deployableHashCode(); + + return Arrays.hashCode(toHash); + } + /** A deployment step */ public abstract static class Step { @@ -395,7 +409,7 @@ public class DeploymentSpec { public int hashCode() { return Objects.hash(environment, region); } - + @Override public boolean equals(Object o) { if (o == this) return true; @@ -405,7 +419,7 @@ public class DeploymentSpec { if ( ! this.region.equals(other.region())) return false; return true; } - + @Override public String toString() { return environment + (region.map(regionName -> "." + regionName).orElse("")); 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 86a2ede85ab..5efa49b3656 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 @@ -25,6 +25,7 @@ import static com.yahoo.config.application.api.Notifications.When.failing; import static com.yahoo.config.application.api.Notifications.When.failingCommit; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -1337,6 +1338,131 @@ public class DeploymentSpecTest { } } + @Test + public void testDeployableHash() { + assertEquals(DeploymentSpec.fromXml("<deployment>\n" + + " <instance id='default' />\n" + + "</deployment>").deployableHashCode(), + DeploymentSpec.fromXml("<deployment major-version='9'>\n" + + " <instance id='default'>\n" + + " <test />\n" + + " <staging tester-flavor='2-8-50' />\n" + + " <block-change days='mon' />\n" + + " <upgrade policy='canary' revision-target='next' revision-change='when-clear' rollout='simultaneous' />\n" + + " <prod />\n" + + " <notifications>\n" + + " <email role='author' />\n" + + " <email address='dev@duff' />\n" + + " </notifications>\n" + + " </instance>\n" + + "</deployment>").deployableHashCode()); + + assertEquals(DeploymentSpec.fromXml("<deployment>\n" + + " <parallel>\n" + + " <instance id='one'>\n" + + " <prod>\n" + + " <region>name</region>\n" + + " </prod>\n" + + " </instance>\n" + + " <instance id='two' />" + + " </parallel>\n" + + "</deployment>").deployableHashCode(), + DeploymentSpec.fromXml("<deployment>\n" + + " <instance id='one'>\n" + + " <prod>\n" + + " <steps>\n" + + " <region>name</region>\n" + + " <delay hours='3' />\n" + + " <test>name</test>\n" + + " </steps>\n" + + " </prod>\n" + + " </instance>\n" + + " <instance id='two' />" + + "</deployment>").deployableHashCode()); + + String referenceSpec = "<deployment>\n" + + " <instance id='default'>" + + " <prod>" + + " <region>name</region>\n" + + " </prod>\n" + + " </instance>\n" + + "</deployment>"; + + assertNotEquals(DeploymentSpec.fromXml(referenceSpec).deployableHashCode(), + DeploymentSpec.fromXml("<deployment />").deployableHashCode()); + + assertNotEquals(DeploymentSpec.fromXml(referenceSpec).deployableHashCode(), + DeploymentSpec.fromXml("<deployment>\n" + + " <instance id='default' />\n" + + "</deployment>").deployableHashCode()); + + assertNotEquals(DeploymentSpec.fromXml(referenceSpec).deployableHashCode(), + DeploymentSpec.fromXml("<deployment>\n" + + " <instance id='custom'>" + + " <prod>" + + " <region>name</region>\n" + + " </prod>\n" + + " </instance>\n" + + "</deployment>").deployableHashCode()); + + assertNotEquals(DeploymentSpec.fromXml(referenceSpec).deployableHashCode(), + DeploymentSpec.fromXml("<deployment>\n" + + " <instance id='custom'>" + + " <prod>" + + " <region>other</region>\n" + + " </prod>\n" + + " </instance>\n" + + "</deployment>").deployableHashCode()); + + assertNotEquals(DeploymentSpec.fromXml(referenceSpec).deployableHashCode(), + DeploymentSpec.fromXml("<deployment athenz-domain='domain' athenz-service='service'>\n" + + " <instance id='default'>" + + " <prod>" + + " <region>name</region>\n" + + " </prod>\n" + + " </instance>\n" + + "</deployment>").deployableHashCode()); + + assertNotEquals(DeploymentSpec.fromXml(referenceSpec).deployableHashCode(), + DeploymentSpec.fromXml("<deployment athenz-domain='domain'>\n" + + " <instance id='default' athenz-service='service'>" + + " <prod>" + + " <region>name</region>\n" + + " </prod>\n" + + " </instance>\n" + + "</deployment>").deployableHashCode()); + + assertNotEquals(DeploymentSpec.fromXml(referenceSpec).deployableHashCode(), + DeploymentSpec.fromXml("<deployment athenz-domain='domain'>\n" + + " <instance id='default'>" + + " <prod athenz-service='prod'>" + + " <region>name</region>\n" + + " </prod>\n" + + " </instance>\n" + + "</deployment>").deployableHashCode()); + + assertNotEquals(DeploymentSpec.fromXml(referenceSpec).deployableHashCode(), + DeploymentSpec.fromXml("<deployment>\n" + + " <instance id='default'>" + + " <prod global-service-id='service'>" + + " <region>name</region>\n" + + " </prod>\n" + + " </instance>\n" + + "</deployment>").deployableHashCode()); + + assertNotEquals(DeploymentSpec.fromXml(referenceSpec).deployableHashCode(), + DeploymentSpec.fromXml("<deployment>\n" + + " <instance id='default'>" + + " <prod>" + + " <region>name</region>\n" + + " </prod>\n" + + " <endpoints>" + + " <endpoint container-id=\"quux\" />" + + " </endpoints>" + + " </instance>\n" + + "</deployment>").deployableHashCode()); + } + private static void assertInvalid(String deploymentSpec, String errorMessagePart) { assertInvalid(deploymentSpec, errorMessagePart, new ManualClock()); } |