summaryrefslogtreecommitdiffstats
path: root/config-model-api
diff options
context:
space:
mode:
authorJon Marius Venstad <venstad@gmail.com>2022-02-21 21:55:10 +0100
committerJon Marius Venstad <venstad@gmail.com>2022-02-22 12:20:27 +0100
commit2aa8213873330a461e9b49ae257d01eb08648495 (patch)
treef56c05271df57e0d06add5ced348b970f11cd08a /config-model-api
parent96916710a1b46cbed64f15345e56a3a68df235f5 (diff)
Do not roll out new application package with pure deployment orchestration changes
Diffstat (limited to 'config-model-api')
-rw-r--r--config-model-api/abi-spec.json3
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstanceSpec.java20
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java18
-rw-r--r--config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java126
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());
}