summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/JobType.java366
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/RevisionId.java2
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/TesterCloud.java5
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/DeploymentFailureMails.java4
-rw-r--r--controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/JobTypeTest.java33
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentStatus.java2
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java33
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/RunList.java2
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java21
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/BufferedLogStore.java4
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/CuratorDb.java8
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java40
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java2
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java24
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiHandler.java2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java8
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java1
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializerTest.java26
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/dev-us-east-1-log-first-part.json2
19 files changed, 375 insertions, 210 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/JobType.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/JobType.java
index 52b43ac475a..e9231f80091 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/JobType.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/JobType.java
@@ -5,173 +5,230 @@ import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.zone.ZoneId;
+import com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneRegistry;
+import java.util.Arrays;
+import java.util.Comparator;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Optional;
+import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import static ai.vespa.validation.Validation.require;
+import static com.yahoo.config.provision.Environment.prod;
+import static com.yahoo.config.provision.Environment.staging;
+import static com.yahoo.config.provision.Environment.test;
import static com.yahoo.config.provision.SystemName.Public;
import static com.yahoo.config.provision.SystemName.PublicCd;
import static com.yahoo.config.provision.SystemName.cd;
import static com.yahoo.config.provision.SystemName.main;
/** Job types that exist in the build system */
-public enum JobType {
+public final class JobType implements Comparable<JobType> {
// | enum name ------------| job name ------------------| Zone in main system ---------------------------------------| Zone in CD system -------------------------------------------
- systemTest ("system-test",
+ public static final JobType systemTest = of("system-test",
Map.of(main , ZoneId.from("test", "us-east-1"),
cd , ZoneId.from("test", "cd-us-west-1"),
PublicCd, ZoneId.from("test", "aws-us-east-1c"),
- Public , ZoneId.from("test", "aws-us-east-1c"))),
+ Public , ZoneId.from("test", "aws-us-east-1c")));
- stagingTest ("staging-test",
+ public static final JobType stagingTest = of("staging-test",
Map.of(main , ZoneId.from("staging", "us-east-3"),
cd , ZoneId.from("staging", "cd-us-west-1"),
PublicCd, ZoneId.from("staging", "aws-us-east-1c"),
- Public , ZoneId.from("staging", "aws-us-east-1c"))),
+ Public , ZoneId.from("staging", "aws-us-east-1c")));
- productionUsEast3 ("production-us-east-3",
- Map.of(main, ZoneId.from("prod" , "us-east-3"))),
+ public static final JobType productionUsEast3 = of("production-us-east-3",
+ Map.of(main, ZoneId.from("prod" , "us-east-3")));
- testUsEast3 ("test-us-east-3",
- Map.of(main, ZoneId.from("prod" , "us-east-3")), true),
+ public static final JobType testUsEast3 = of("test-us-east-3",
+ Map.of(main, ZoneId.from("prod" , "us-east-3")), true);
- productionUsWest1 ("production-us-west-1",
- Map.of(main, ZoneId.from("prod" , "us-west-1"))),
+ public static final JobType productionUsWest1 = of("production-us-west-1",
+ Map.of(main, ZoneId.from("prod" , "us-west-1")));
- testUsWest1 ("test-us-west-1",
- Map.of(main, ZoneId.from("prod" , "us-west-1")), true),
+ public static final JobType testUsWest1 = of("test-us-west-1",
+ Map.of(main, ZoneId.from("prod" , "us-west-1")), true);
- productionUsCentral1 ("production-us-central-1",
- Map.of(main, ZoneId.from("prod" , "us-central-1"))),
+ public static final JobType productionUsCentral1 = of("production-us-central-1",
+ Map.of(main, ZoneId.from("prod" , "us-central-1")));
- testUsCentral1 ("test-us-central-1",
- Map.of(main, ZoneId.from("prod" , "us-central-1")), true),
+ public static final JobType testUsCentral1 = of("test-us-central-1",
+ Map.of(main, ZoneId.from("prod" , "us-central-1")), true);
- productionApNortheast1 ("production-ap-northeast-1",
- Map.of(main, ZoneId.from("prod" , "ap-northeast-1"))),
+ public static final JobType productionApNortheast1 = of("production-ap-northeast-1",
+ Map.of(main, ZoneId.from("prod" , "ap-northeast-1")));
- testApNortheast1 ("test-ap-northeast-1",
- Map.of(main, ZoneId.from("prod" , "ap-northeast-1")), true),
+ public static final JobType testApNortheast1 = of("test-ap-northeast-1",
+ Map.of(main, ZoneId.from("prod" , "ap-northeast-1")), true);
- productionApNortheast2 ("production-ap-northeast-2",
- Map.of(main, ZoneId.from("prod" , "ap-northeast-2"))),
+ public static final JobType productionApNortheast2 = of("production-ap-northeast-2",
+ Map.of(main, ZoneId.from("prod" , "ap-northeast-2")));
- testApNortheast2 ("test-ap-northeast-2",
- Map.of(main, ZoneId.from("prod" , "ap-northeast-2")), true),
+ public static final JobType testApNortheast2 = of("test-ap-northeast-2",
+ Map.of(main, ZoneId.from("prod" , "ap-northeast-2")), true);
- productionApSoutheast1 ("production-ap-southeast-1",
- Map.of(main, ZoneId.from("prod" , "ap-southeast-1"))),
+ public static final JobType productionApSoutheast1 = of("production-ap-southeast-1",
+ Map.of(main, ZoneId.from("prod" , "ap-southeast-1")));
- testApSoutheast1 ("test-ap-southeast-1",
- Map.of(main, ZoneId.from("prod" , "ap-southeast-1")), true),
+ public static final JobType testApSoutheast1 = of("test-ap-southeast-1",
+ Map.of(main, ZoneId.from("prod" , "ap-southeast-1")), true);
- productionEuWest1 ("production-eu-west-1",
- Map.of(main, ZoneId.from("prod" , "eu-west-1"))),
+ public static final JobType productionEuWest1 = of("production-eu-west-1",
+ Map.of(main, ZoneId.from("prod" , "eu-west-1")));
- testEuWest1 ("test-eu-west-1",
- Map.of(main, ZoneId.from("prod" , "eu-west-1")), true),
+ public static final JobType testEuWest1 = of("test-eu-west-1",
+ Map.of(main, ZoneId.from("prod" , "eu-west-1")), true);
- productionAwsUsEast1a ("production-aws-us-east-1a",
- Map.of(main, ZoneId.from("prod" , "aws-us-east-1a"))),
+ public static final JobType productionAwsUsEast1a= of("production-aws-us-east-1a",
+ Map.of(main, ZoneId.from("prod" , "aws-us-east-1a")));
- testAwsUsEast1a ("test-aws-us-east-1a",
- Map.of(main, ZoneId.from("prod" , "aws-us-east-1a")), true),
+ public static final JobType testAwsUsEast1a = of("test-aws-us-east-1a",
+ Map.of(main, ZoneId.from("prod" , "aws-us-east-1a")), true);
- productionAwsUsEast1c ("production-aws-us-east-1c",
+ public static final JobType productionAwsUsEast1c= of("production-aws-us-east-1c",
Map.of(PublicCd, ZoneId.from("prod", "aws-us-east-1c"),
- Public, ZoneId.from("prod", "aws-us-east-1c"))),
+ Public, ZoneId.from("prod", "aws-us-east-1c")));
- testAwsUsEast1c ("test-aws-us-east-1c",
+ public static final JobType testAwsUsEast1c = of("test-aws-us-east-1c",
Map.of(PublicCd, ZoneId.from("prod", "aws-us-east-1c"),
- Public, ZoneId.from("prod", "aws-us-east-1c")), true),
+ Public, ZoneId.from("prod", "aws-us-east-1c")), true);
- productionAwsApNortheast1a ("production-aws-ap-northeast-1a",
- Map.of(Public, ZoneId.from("prod", "aws-ap-northeast-1a"))),
+ public static final JobType productionAwsApNortheast1a= of("production-aws-ap-northeast-1a",
+ Map.of(Public, ZoneId.from("prod", "aws-ap-northeast-1a")));
- testAwsApNortheast1a ("test-aws-ap-northeast-1a",
- Map.of(Public, ZoneId.from("prod", "aws-ap-northeast-1a")), true),
+ public static final JobType testAwsApNortheast1a = of("test-aws-ap-northeast-1a",
+ Map.of(Public, ZoneId.from("prod", "aws-ap-northeast-1a")), true);
- productionAwsEuWest1a ("production-aws-eu-west-1a",
- Map.of(Public, ZoneId.from("prod", "aws-eu-west-1a"))),
+ public static final JobType productionAwsEuWest1a= of("production-aws-eu-west-1a",
+ Map.of(Public, ZoneId.from("prod", "aws-eu-west-1a")));
- testAwsEuWest1a ("test-aws-eu-west-1a",
- Map.of(Public, ZoneId.from("prod", "aws-eu-west-1a")), true),
+ public static final JobType testAwsEuWest1a = of("test-aws-eu-west-1a",
+ Map.of(Public, ZoneId.from("prod", "aws-eu-west-1a")), true);
- productionAwsUsWest2a ("production-aws-us-west-2a",
+ public static final JobType productionAwsUsWest2a= of("production-aws-us-west-2a",
Map.of(main, ZoneId.from("prod", "aws-us-west-2a"),
- Public, ZoneId.from("prod", "aws-us-west-2a"))),
+ Public, ZoneId.from("prod", "aws-us-west-2a")));
- testAwsUsWest2a ("test-aws-us-west-2a",
+ public static final JobType testAwsUsWest2a = of("test-aws-us-west-2a",
Map.of(main, ZoneId.from("prod", "aws-us-west-2a"),
- Public, ZoneId.from("prod", "aws-us-west-2a")), true),
+ Public, ZoneId.from("prod", "aws-us-west-2a")), true);
- productionAwsUsEast1b ("production-aws-us-east-1b",
- Map.of(main, ZoneId.from("prod" , "aws-us-east-1b"))),
+ public static final JobType productionAwsUsEast1b= of("production-aws-us-east-1b",
+ Map.of(main, ZoneId.from("prod" , "aws-us-east-1b")));
- testAwsUsEast1b ("test-aws-us-east-1b",
- Map.of(main, ZoneId.from("prod" , "aws-us-east-1b")), true),
+ public static final JobType testAwsUsEast1b = of("test-aws-us-east-1b",
+ Map.of(main, ZoneId.from("prod" , "aws-us-east-1b")), true);
- devUsEast1 ("dev-us-east-1",
- Map.of(main, ZoneId.from("dev" , "us-east-1"))),
+ public static final JobType devUsEast1 = of("dev-us-east-1",
+ Map.of(main, ZoneId.from("dev" , "us-east-1")));
- devAwsUsEast2a ("dev-aws-us-east-2a",
- Map.of(main, ZoneId.from("dev" , "aws-us-east-2a"))),
+ public static final JobType devAwsUsEast2a = of("dev-aws-us-east-2a",
+ Map.of(main, ZoneId.from("dev" , "aws-us-east-2a")));
- productionCdAwsUsEast1a("production-cd-aws-us-east-1a",
- Map.of(cd , ZoneId.from("prod" , "cd-aws-us-east-1a"))),
+ public static final JobType productionCdAwsUsEast1a = of("production-cd-aws-us-east-1a",
+ Map.of(cd , ZoneId.from("prod" , "cd-aws-us-east-1a")));
- testCdAwsUsEast1a ("test-cd-aws-us-east-1a",
- Map.of(cd , ZoneId.from("prod" , "cd-aws-us-east-1a")), true),
+ public static final JobType testCdAwsUsEast1a = of("test-cd-aws-us-east-1a",
+ Map.of(cd , ZoneId.from("prod" , "cd-aws-us-east-1a")), true);
- productionCdUsCentral1 ("production-cd-us-central-1",
- Map.of(cd , ZoneId.from("prod" , "cd-us-central-1"))),
+ public static final JobType productionCdUsCentral1 = of("production-cd-us-central-1",
+ Map.of(cd , ZoneId.from("prod" , "cd-us-central-1")));
- testCdUsCentral1 ("test-cd-us-central-1",
- Map.of(cd , ZoneId.from("prod" , "cd-us-central-1")), true),
+ public static final JobType testCdUsCentral1 = of("test-cd-us-central-1",
+ Map.of(cd , ZoneId.from("prod" , "cd-us-central-1")), true);
// TODO: Cannot remove production-cd-us-central-2 until we know there are no serialized data in controller referencing it
- productionCdUsCentral2 ("production-cd-us-central-2",
- Map.of(cd , ZoneId.from("prod" , "cd-us-central-2"))),
+ public static final JobType productionCdUsCentral2 = of("production-cd-us-central-2",
+ Map.of(cd , ZoneId.from("prod" , "cd-us-central-2")));
- testCdUsCentral2 ("test-cd-us-central-2",
- Map.of(cd , ZoneId.from("prod" , "cd-us-central-2")), true),
+ public static final JobType testCdUsCentral2 = of("test-cd-us-central-2",
+ Map.of(cd , ZoneId.from("prod" , "cd-us-central-2")), true);
- productionCdUsEast1 ("production-cd-us-east-1",
- Map.of(cd , ZoneId.from("prod" , "cd-us-east-1"))),
+ public static final JobType productionCdUsEast1= of("production-cd-us-east-1",
+ Map.of(cd , ZoneId.from("prod" , "cd-us-east-1")));
- testCdUsEast1 ("test-cd-us-east-1",
- Map.of(cd , ZoneId.from("prod" , "cd-us-east-1")), true),
+ public static final JobType testCdUsEast1 = of("test-cd-us-east-1",
+ Map.of(cd , ZoneId.from("prod" , "cd-us-east-1")), true);
- productionCdUsWest1 ("production-cd-us-west-1",
- Map.of(cd , ZoneId.from("prod" , "cd-us-west-1"))),
+ public static final JobType productionCdUsWest1= of("production-cd-us-west-1",
+ Map.of(cd , ZoneId.from("prod" , "cd-us-west-1")));
- testCdUsWest1 ("test-cd-us-west-1",
- Map.of(cd , ZoneId.from("prod" , "cd-us-west-1")), true),
+ public static final JobType testCdUsWest1 = of("test-cd-us-west-1",
+ Map.of(cd , ZoneId.from("prod" , "cd-us-west-1")), true);
- devCdUsCentral1 ("dev-cd-us-central-1",
- Map.of(cd , ZoneId.from("dev" , "cd-us-central-1"))),
+ public static final JobType devCdUsCentral1 = of("dev-cd-us-central-1",
+ Map.of(cd , ZoneId.from("dev" , "cd-us-central-1")));
- devCdUsWest1 ("dev-cd-us-west-1",
- Map.of(cd , ZoneId.from("dev" , "cd-us-west-1"))),
+ public static final JobType devCdUsWest1 = of("dev-cd-us-west-1",
+ Map.of(cd , ZoneId.from("dev" , "cd-us-west-1")));
- devAwsUsEast1c ("dev-aws-us-east-1c",
+ public static final JobType devAwsUsEast1c = of("dev-aws-us-east-1c",
Map.of(Public, ZoneId.from("dev", "aws-us-east-1c"),
- PublicCd, ZoneId.from("dev", "aws-us-east-1c"))),
+ PublicCd, ZoneId.from("dev", "aws-us-east-1c")));
- perfAwsUsEast1c ("perf-aws-us-east-1c",
- Map.of(Public, ZoneId.from("perf", "aws-us-east-1c"))),
+ public static final JobType perfAwsUsEast1c = of("perf-aws-us-east-1c",
+ Map.of(Public, ZoneId.from("perf", "aws-us-east-1c")));
- perfUsEast3 ("perf-us-east-3",
+ public static final JobType perfUsEast3 = of("perf-us-east-3",
Map.of(main, ZoneId.from("perf" , "us-east-3")));
+ private static final JobType[] values = new JobType[] {
+ systemTest,
+ stagingTest,
+ productionUsEast3,
+ testUsEast3,
+ productionUsWest1,
+ testUsWest1,
+ productionUsCentral1,
+ testUsCentral1,
+ productionApNortheast1,
+ testApNortheast1,
+ productionApNortheast2,
+ testApNortheast2,
+ productionApSoutheast1,
+ testApSoutheast1,
+ productionEuWest1,
+ testEuWest1,
+ productionAwsUsEast1a,
+ testAwsUsEast1a,
+ productionAwsUsEast1c,
+ testAwsUsEast1c,
+ productionAwsApNortheast1a,
+ testAwsApNortheast1a,
+ productionAwsEuWest1a,
+ testAwsEuWest1a,
+ productionAwsUsWest2a,
+ testAwsUsWest2a,
+ productionAwsUsEast1b,
+ testAwsUsEast1b,
+ devUsEast1,
+ devAwsUsEast2a,
+ productionCdAwsUsEast1a,
+ testCdAwsUsEast1a,
+ productionCdUsCentral1,
+ testCdUsCentral1,
+ productionCdUsCentral2,
+ testCdUsCentral2,
+ productionCdUsEast1,
+ testCdUsEast1,
+ productionCdUsWest1,
+ testCdUsWest1,
+ devCdUsCentral1,
+ devCdUsWest1,
+ devAwsUsEast1c,
+ perfAwsUsEast1c,
+ perfUsEast3
+ };
+
private final String jobName;
final Map<SystemName, ZoneId> zones;
private final boolean isProductionTest;
- JobType(String jobName, Map<SystemName, ZoneId> zones, boolean isProductionTest) {
+ private JobType(String jobName, Map<SystemName, ZoneId> zones, boolean isProductionTest) {
if (zones.values().stream().map(ZoneId::environment).distinct().count() > 1)
throw new IllegalArgumentException("All zones of a job must be in the same environment");
@@ -180,8 +237,12 @@ public enum JobType {
this.isProductionTest = isProductionTest;
}
- JobType(String jobName, Map<SystemName, ZoneId> zones) {
- this(jobName, zones, false);
+ private static JobType of(String jobName, Map<SystemName, ZoneId> zones, boolean isProductionTest) {
+ return new JobType(jobName, zones, isProductionTest);
+ }
+
+ private static JobType of(String jobName, Map<SystemName, ZoneId> zones) {
+ return of(jobName, zones, false);
}
public String jobName() { return jobName; }
@@ -194,12 +255,92 @@ public enum JobType {
return zones.get(system);
}
- public static List<JobType> allIn(SystemName system) {
- return Stream.of(values()).filter(job -> job.zones.containsKey(system)).collect(Collectors.toUnmodifiableList());
+ public static JobType systemTest(ZoneRegistry zones) {
+ return testIn(test, zones);
+ }
+
+ public static JobType stagingTest(ZoneRegistry zones){
+ return testIn(staging, zones);
+ }
+
+ private static JobType testIn(Environment environment, ZoneRegistry zones) {
+ return zones.zones().controllerUpgraded().in(environment).zones().stream().map(zone -> deploymentTo(zone.getId()))
+ .findFirst().orElseThrow(() -> new IllegalArgumentException("no zones in " + environment + " among " + zones.zones().controllerUpgraded().zones()));
+ }
+
+ public static JobType dev(String region) {
+ return deploymentTo(ZoneId.from("dev", region));
+ }
+
+ public static JobType perf(String region) {
+ return deploymentTo(ZoneId.from("perf", region));
+ }
+
+ public static JobType prod(String region) {
+ return deploymentTo(ZoneId.from("prod", region));
+ }
+
+ public static JobType test(String region) {
+ return productionTestOf(ZoneId.from("prod", region));
+ }
+
+ public static JobType deploymentTo(ZoneId zone) {
+ String name;
+ switch (zone.environment()) {
+ case prod: name = "production-" + zone.region().value(); break;
+ case test: name = "system-test"; break;
+ case staging: name = "staging-test"; break;
+ default: name = zone.environment().value() + "-" + zone.region().value();
+ }
+ return of(name, dummy(zone), false);
+ }
+
+ public static JobType productionTestOf(ZoneId zone) {
+ return of("test-" + require(zone.environment() == prod, zone, "must be prod zone").region().value(), dummy(zone), true);
+ }
+
+ private static Map<SystemName, ZoneId> dummy(ZoneId zone) {
+ return Stream.of(SystemName.values()).collect(Collectors.toMap(Function.identity(), __ -> zone));
+ }
+
+ // TODO jonmv: use for serialisation
+ public static JobType ofSerialized(String raw) {
+ String[] parts = raw.split("\\.");
+ if (parts.length == 2) return deploymentTo(ZoneId.from(parts[0], parts[1]));
+ if (parts.length == 3 && "test".equals(parts[2])) return productionTestOf(ZoneId.from(parts[0], parts[1]));
+ throw new IllegalArgumentException("illegal serialized job type '" + raw + "'");
+ }
+
+ // TODO jonmv: use for serialisation
+ public String serialized() {
+ throw new UnsupportedOperationException();
+ // return zone.environment().value() + "." + zone.region().value() + (isProductionTest ? ".test");
+ }
+
+ public static List<JobType> allIn(ZoneRegistry zones) {
+ return Stream.of(values).filter(job -> job.zones.containsKey(zones.system())).collect(Collectors.toUnmodifiableList());
+ /*
+ return zones.zones().controllerUpgraded().zones().stream()
+ .flatMap(zone -> zone.getEnvironment().isProduction() ? Stream.of(of(zone.getId()), ofTest(zone.getId()))
+ : Stream.of(of(zone.getId())))
+ .collect(Collectors.toUnmodifiableList());
+ */
+ }
+
+ static JobType[] values() {
+ return Arrays.copyOf(values, values.length);
+ }
+
+ public boolean isSystemTest() {
+ return environment() == test;
+ }
+
+ public boolean isStagingTest() {
+ return environment() == staging;
}
/** Returns whether this is a production job */
- public boolean isProduction() { return environment() == Environment.prod; }
+ public boolean isProduction() { return environment() == prod; }
/** Returns whether this job runs tests */
public boolean isTest() { return isProductionTest || environment().isTest(); }
@@ -207,17 +348,20 @@ public enum JobType {
/** Returns whether this job deploys to a zone */
public boolean isDeployment() { return ! (isProduction() && isProductionTest); }
- /** Returns the environment of this job type, or null if it does not have an environment */
+ /** Returns the environment of this job type */
public Environment environment() {
return zones.values().iterator().next().environment();
}
+ // TODO jonmv: require zones
public static Optional<JobType> fromOptionalJobName(String jobName) {
- return Stream.of(values())
+ if (jobName.contains(".")) return Optional.of(ofSerialized(jobName)); // TODO jonmv: remove
+ return Stream.of(values)
.filter(jobType -> jobType.jobName.equals(jobName))
.findAny();
}
+ // TODO jonmv: require zones
public static JobType fromJobName(String jobName) {
return fromOptionalJobName(jobName)
.orElseThrow(() -> new IllegalArgumentException("Unknown job name '" + jobName + "'"));
@@ -225,7 +369,7 @@ public enum JobType {
/** Returns the job type for the given zone */
public static Optional<JobType> from(SystemName system, ZoneId zone, boolean isTest) {
- return Stream.of(values())
+ return Stream.of(values)
.filter(job -> zone.equals(job.zones.get(system)) && job.isTest() == isTest)
.findAny();
}
@@ -237,7 +381,7 @@ public enum JobType {
/** Returns the production test job type for the given environment and region or null if none */
public static Optional<JobType> testFrom(SystemName system, RegionName region) {
- return from(system, ZoneId.from(Environment.prod, region), true);
+ return from(system, ZoneId.from(prod, region), true);
}
/** Returns the job job type for the given environment and region or null if none */
@@ -249,4 +393,26 @@ public enum JobType {
return from(system, ZoneId.from(environment, region));
}
+
+ private static final Comparator<JobType> comparator = Comparator.comparing(JobType::environment)
+ .thenComparing(JobType::isDeployment)
+ .thenComparing(JobType::jobName);
+ @Override
+ public int compareTo(JobType other) {
+ return comparator.compare(this, other);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ JobType jobType = (JobType) o;
+ return jobName.equals(jobType.jobName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(jobName);
+ }
+
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/RevisionId.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/RevisionId.java
index 2ab419b5388..08d800ce26d 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/RevisionId.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/RevisionId.java
@@ -57,7 +57,7 @@ public class RevisionId implements Comparable<RevisionId> {
@Override
public String toString() {
return isProduction() ? "build " + number
- : "dev build " + number + " for " + job.type() + " of " + job.application().instance();
+ : "dev build " + number + " for " + job.type().jobName() + " of " + job.application().instance();
}
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/TesterCloud.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/TesterCloud.java
index 9d6fe07e91c..b4d9dd49880 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/TesterCloud.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/TesterCloud.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.hosted.controller.api.integration.deployment;
import ai.vespa.http.DomainName;
+import com.yahoo.config.provision.Environment;
import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId;
import com.yahoo.vespa.hosted.controller.api.integration.LogEntry;
@@ -78,8 +79,8 @@ public interface TesterCloud {
production;
public static Suite of(JobType type, boolean isSetup) {
- if (type == JobType.systemTest) return system;
- if (type == JobType.stagingTest) return isSetup ? staging_setup : staging;
+ if (type.isSystemTest()) return system;
+ if (type.isStagingTest()) return isSetup ? staging_setup : staging;
if (type.isProduction()) return production;
throw new AssertionError("Unknown JobType '" + type + "'!");
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/DeploymentFailureMails.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/DeploymentFailureMails.java
index 54c4905eb46..b35bf7c68c2 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/DeploymentFailureMails.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/DeploymentFailureMails.java
@@ -71,9 +71,9 @@ public class DeploymentFailureMails {
}
private String jobToString(JobType type) {
- if (type == JobType.systemTest)
+ if (type.isSystemTest())
return "System test";
- if (type == JobType.stagingTest)
+ if (type.isStagingTest())
return "Staging test";
return (type.isDeployment() ? "Deployment to " : "Verification test of ") +
type.zone(registry.system()).region();
diff --git a/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/JobTypeTest.java b/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/JobTypeTest.java
index 51c20056ad4..990e8911e91 100644
--- a/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/JobTypeTest.java
+++ b/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/JobTypeTest.java
@@ -1,8 +1,14 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.controller.api.integration.deployment;
+import com.yahoo.config.provision.Environment;
+import com.yahoo.config.provision.SystemName;
+import com.yahoo.config.provision.zone.ZoneId;
+import com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneRegistry;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
@@ -23,6 +29,33 @@ public class JobTypeTest {
assertTrue(type + " should have matching job", match);
}
}
+
+ assertEquals(JobType.testUsEast3, JobType.fromJobName("prod.us-east-3.test"));
+ assertEquals(JobType.devAwsUsEast1c, JobType.fromJobName("dev.aws-us-east-1c"));
+
+ assertFalse(JobType.dev("snøhetta").isTest());
+ assertTrue(JobType.dev("snøhetta").isDeployment());
+ assertFalse(JobType.dev("snøhetta").isProduction());
+
+ assertFalse(JobType.perf("snøhetta").isTest());
+ assertTrue(JobType.perf("snøhetta").isDeployment());
+ assertFalse(JobType.perf("snøhetta").isProduction());
+
+ assertTrue(JobType.deploymentTo(ZoneId.from("test", "snøhetta")).isTest());
+ assertTrue(JobType.deploymentTo(ZoneId.from("test", "snøhetta")).isDeployment());
+ assertFalse(JobType.deploymentTo(ZoneId.from("test", "snøhetta")).isProduction());
+
+ assertTrue(JobType.deploymentTo(ZoneId.from("staging", "snøhetta")).isTest());
+ assertTrue(JobType.deploymentTo(ZoneId.from("staging", "snøhetta")).isDeployment());
+ assertFalse(JobType.deploymentTo(ZoneId.from("staging", "snøhetta")).isProduction());
+
+ assertFalse(JobType.prod("snøhetta").isTest());
+ assertTrue(JobType.prod("snøhetta").isDeployment());
+ assertTrue(JobType.prod("snøhetta").isProduction());
+
+ assertTrue(JobType.test("snøhetta").isTest());
+ assertFalse(JobType.test("snøhetta").isDeployment());
+ assertTrue(JobType.test("snøhetta").isProduction());
}
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentStatus.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentStatus.java
index 814e33f616b..7b53d9c5d99 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentStatus.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentStatus.java
@@ -927,7 +927,7 @@ public class DeploymentStatus {
private final Change change;
public Job(JobType type, Versions versions, Optional<Instant> readyAt, Change change) {
- this.versions = type == systemTest ? versions.withoutSources() : versions;
+ this.versions = type.isSystemTest() ? versions.withoutSources() : versions;
this.readyAt = readyAt;
this.change = change;
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java
index 4b8339cccb1..4cece8ed575 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java
@@ -121,7 +121,7 @@ public class JobController {
for (ApplicationId id : instances())
for (JobType type : jobs(id)) {
locked(id, type, runs -> { // Runs are not modified here, and are written as they were.
- curator.readLastRun(id, type).ifPresent(run -> curator.writeLastRun(run, controller.applications().requireApplication(TenantAndApplicationId.from(id))));
+ curator.readLastRun(id, type).ifPresent(curator::writeLastRun);
});
}
}
@@ -238,7 +238,7 @@ public class JobController {
/** Returns all job types which have been run for the given application. */
private List<JobType> jobs(ApplicationId id) {
- return JobType.allIn(controller.system()).stream()
+ return JobType.allIn(controller.zoneRegistry()).stream()
.filter(type -> last(id, type).isPresent())
.collect(toUnmodifiableList());
}
@@ -317,20 +317,20 @@ public class JobController {
/** Returns a list of all active runs for the given application. */
public List<Run> active(TenantAndApplicationId id) {
return controller.applications().requireApplication(id).instances().keySet().stream()
- .flatMap(name -> Stream.of(JobType.values())
- .map(type -> last(id.instance(name), type))
- .flatMap(Optional::stream)
- .filter(run -> !run.hasEnded()))
+ .flatMap(name -> JobType.allIn(controller.zoneRegistry()).stream()
+ .map(type -> last(id.instance(name), type))
+ .flatMap(Optional::stream)
+ .filter(run -> ! run.hasEnded()))
.collect(toUnmodifiableList());
}
/** Returns a list of all active runs for the given instance. */
public List<Run> active(ApplicationId id) {
- return Stream.of(JobType.values())
- .map(type -> last(id, type))
- .flatMap(Optional::stream)
- .filter(run -> !run.hasEnded())
- .collect(toUnmodifiableList());
+ return JobType.allIn(controller.zoneRegistry()).stream()
+ .map(type -> last(id, type))
+ .flatMap(Optional::stream)
+ .filter(run -> !run.hasEnded())
+ .collect(toUnmodifiableList());
}
/** Returns the job status of the given job, possibly empty. */
@@ -546,7 +546,7 @@ public class JobController {
throw new IllegalArgumentException("Cannot start " + type + " for " + id + "; it is already running!");
RunId newId = new RunId(id, type, last.map(run -> run.id().number()).orElse(0L) + 1);
- curator.writeLastRun(Run.initial(newId, versions, isRedeployment, controller.clock().instant(), profile, reason), controller.applications().requireApplication(TenantAndApplicationId.from(id)));
+ curator.writeLastRun(Run.initial(newId, versions, isRedeployment, controller.clock().instant(), profile, reason));
metric.jobStarted(newId.job());
});
}
@@ -684,21 +684,18 @@ public class JobController {
/** Locks all runs and modifies the list of historic runs for the given application and job type. */
private void locked(ApplicationId id, JobType type, Consumer<SortedMap<RunId, Run>> modifications) {
- Application application = controller.applications().requireApplication(TenantAndApplicationId.from(id));
- try (Mutex __ = curator.lock(id, type)) {
+ try (Mutex __ = curator.lock(id, type)) {
SortedMap<RunId, Run> runs = new TreeMap<>(curator.readHistoricRuns(id, type));
modifications.accept(runs);
- curator.writeHistoricRuns(id, type, runs.values(), application);
+ curator.writeHistoricRuns(id, type, runs.values());
}
}
/** Locks and modifies the run with the given id, provided it is still active. */
public void locked(RunId id, UnaryOperator<Run> modifications) {
- Application application = controller.applications().requireApplication(TenantAndApplicationId.from(id.application()));
try (Mutex __ = curator.lock(id.application(), id.type())) {
active(id).ifPresent(run -> {
- run = modifications.apply(run);
- curator.writeLastRun(run, application);
+ kurator.writeLastRun(modifications.apply(run));
});
}
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/RunList.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/RunList.java
index 00cd4bd5c6c..80c6552d3d4 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/RunList.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/RunList.java
@@ -38,7 +38,7 @@ public class RunList extends AbstractFilteringList<Run, RunList> {
private static boolean matchingVersions(Run run, Versions versions) {
return versions.targetsMatch(run.versions())
- && (versions.sourcesMatchIfPresent(run.versions()) || run.id().type() == JobType.systemTest);
+ && (versions.sourcesMatchIfPresent(run.versions()) || run.id().type().isSystemTest());
}
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java
index c269463c9fa..4b9df825951 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java
@@ -190,11 +190,11 @@ public class ApplicationSerializer {
for (Instance instance : application.instances().values()) {
Cursor instanceObject = array.addObject();
instanceObject.setString(instanceNameField, instance.name().value());
- deploymentsToSlime(instance.deployments().values(), application, instanceObject.setArray(deploymentsField));
+ deploymentsToSlime(instance.deployments().values(), instanceObject.setArray(deploymentsField));
toSlime(instance.jobPauses(), instanceObject.setObject(deploymentJobsField));
assignedRotationsToSlime(instance.rotations(), instanceObject);
toSlime(instance.rotationStatus(), instanceObject.setArray(rotationStatusField));
- toSlime(instance.change(), application, instanceObject, deployingField);
+ toSlime(instance.change(), instanceObject, deployingField);
}
}
@@ -202,16 +202,16 @@ public class ApplicationSerializer {
deployKeys.forEach(key -> array.addString(KeyUtils.toPem(key)));
}
- private void deploymentsToSlime(Collection<Deployment> deployments, Application application, Cursor array) {
+ private void deploymentsToSlime(Collection<Deployment> deployments, Cursor array) {
for (Deployment deployment : deployments)
- deploymentToSlime(deployment, application.revisions()::get, array.addObject());
+ deploymentToSlime(deployment, array.addObject());
}
- private void deploymentToSlime(Deployment deployment, Function<RevisionId, ApplicationVersion> compatibility, Cursor object) {
+ private void deploymentToSlime(Deployment deployment, Cursor object) {
zoneIdToSlime(deployment.zone(), object.setObject(zoneField));
object.setString(versionField, deployment.version().toString());
object.setLong(deployTimeField, deployment.at().toEpochMilli());
- toSlime(compatibility.apply(deployment.revision()), object.setObject(applicationPackageRevisionField));
+ toSlime(deployment.revision(), object.setObject(applicationPackageRevisionField));
deploymentMetricsToSlime(deployment.metrics(), object);
deployment.activity().lastQueried().ifPresent(instant -> object.setLong(lastQueriedField, instant.toEpochMilli()));
deployment.activity().lastWritten().ifPresent(instant -> object.setLong(lastWrittenField, instant.toEpochMilli()));
@@ -254,6 +254,11 @@ public class ApplicationSerializer {
revisions.forEach(version -> toSlime(version, revisionsArray.addObject()));
}
+ private void toSlime(RevisionId revision, Cursor object) {
+ object.setLong(applicationBuildNumberField, revision.number());
+ object.setBool(deployedDirectlyField, ! revision.isProduction());
+ }
+
private void toSlime(ApplicationVersion applicationVersion, Cursor object) {
applicationVersion.buildNumber().ifPresent(number -> object.setLong(applicationBuildNumberField, number));
applicationVersion.source().ifPresent(source -> toSlime(source, object.setObject(sourceRevisionField)));
@@ -285,14 +290,14 @@ public class ApplicationSerializer {
});
}
- private void toSlime(Change deploying, Application application, Cursor parentObject, String fieldName) {
+ private void toSlime(Change deploying, Cursor parentObject, String fieldName) {
if (deploying.isEmpty()) return;
Cursor object = parentObject.setObject(fieldName);
if (deploying.platform().isPresent())
object.setString(versionField, deploying.platform().get().toString());
if (deploying.revision().isPresent())
- toSlime(application.revisions().get(deploying.revision().get()), object);
+ toSlime(deploying.revision().get(), object);
if (deploying.isPinned())
object.setBool(pinnedField, true);
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/BufferedLogStore.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/BufferedLogStore.java
index 9c3a6aa17d7..9721026c628 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/BufferedLogStore.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/BufferedLogStore.java
@@ -110,10 +110,8 @@ public class BufferedLogStore {
store.delete(id);
}
- /** Deletes all logs for the given application. */
+ /** Deletes all logs in permanent storage for the given application. */
public void delete(ApplicationId id) {
- for (JobType type : JobType.values())
- buffer.deleteLog(id, type);
store.delete(id);
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/CuratorDb.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/CuratorDb.java
index 5e6cfa8b43f..6190d58e0a1 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/CuratorDb.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/CuratorDb.java
@@ -465,13 +465,13 @@ public class CuratorDb {
// -------------- Job Runs ------------------------------------------------
- public void writeLastRun(Run run, Application application) {
- curator.set(lastRunPath(run.id().application(), run.id().type()), asJson(runSerializer.toSlime(run, application)));
+ public void writeLastRun(Run run) {
+ curator.set(lastRunPath(run.id().application(), run.id().type()), asJson(runSerializer.toSlime(run)));
}
- public void writeHistoricRuns(ApplicationId id, JobType type, Iterable<Run> runs, Application application) {
+ public void writeHistoricRuns(ApplicationId id, JobType type, Iterable<Run> runs) {
Path path = runsPath(id, type);
- curator.set(path, asJson(runSerializer.toSlime(runs, application)));
+ curator.set(path, asJson(runSerializer.toSlime(runs)));
}
public Optional<Run> readLastRun(ApplicationId id, JobType type) {
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java
index ea932fd19c8..32ba583321c 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java
@@ -90,17 +90,9 @@ class RunSerializer {
private static final String versionsField = "versions";
private static final String isRedeploymentField = "isRedeployment";
private static final String platformVersionField = "platform";
- private static final String repositoryField = "repository";
- private static final String branchField = "branch";
- private static final String commitField = "commit";
- private static final String authorEmailField = "authorEmail";
private static final String deployedDirectlyField = "deployedDirectly";
- private static final String compileVersionField = "compileVersion";
- private static final String buildTimeField = "buildTime";
- private static final String sourceUrlField = "sourceUrl";
private static final String buildField = "build";
private static final String sourceField = "source";
- private static final String bundleHashField = "bundleHash";
private static final String lastTestRecordField = "lastTestRecord";
private static final String lastVespaLogTimestampField = "lastVespaLogTimestamp";
private static final String noNodesDownSinceField = "noNodesDownSince";
@@ -202,24 +194,20 @@ class RunSerializer {
summaryArray.entry(12).asLong()));
}
- Slime toSlime(Iterable<Run> runs, Application application) {
+ Slime toSlime(Iterable<Run> runs) {
Slime slime = new Slime();
Cursor runArray = slime.setArray();
- runs.forEach(run -> toSlime(run, application.revisions()::get, runArray.addObject()));
+ runs.forEach(run -> toSlime(run, runArray.addObject()));
return slime;
}
- Slime toSlime(Run run, Application application) {
- return toSlime(run, application.revisions()::get);
- }
-
- Slime toSlime(Run run, Function<RevisionId, ApplicationVersion> compatilibity) {
+ Slime toSlime(Run run) {
Slime slime = new Slime();
- toSlime(run, compatilibity, slime.setObject());
+ toSlime(run, slime.setObject());
return slime;
}
- private void toSlime(Run run, Function<RevisionId, ApplicationVersion> compatibility, Cursor runObject) {
+ private void toSlime(Run run, Cursor runObject) {
runObject.setString(applicationField, run.id().application().serializedForm());
runObject.setString(jobTypeField, run.id().type().jobName());
runObject.setBool(isRedeploymentField, run.isRedeployment());
@@ -244,10 +232,10 @@ class RunSerializer {
stepDetailsObject.setObject(valueOf(step)).setLong(startTimeField, valueOf(startTime))));
Cursor versionsObject = runObject.setObject(versionsField);
- toSlime(run.versions().targetPlatform(), compatibility.apply(run.versions().targetRevision()), versionsObject);
+ toSlime(run.versions().targetPlatform(), run.versions().targetRevision(), versionsObject);
run.versions().sourcePlatform().ifPresent(sourcePlatformVersion -> {
toSlime(sourcePlatformVersion,
- run.versions().sourceRevision().map(compatibility)
+ run.versions().sourceRevision()
.orElseThrow(() -> new IllegalArgumentException("Source versions must be both present or absent.")),
versionsObject.setObject(sourceField));
});
@@ -255,18 +243,10 @@ class RunSerializer {
run.reason().ifPresent(reason -> runObject.setString(reasonField, reason));
}
- private void toSlime(Version platformVersion, ApplicationVersion applicationVersion, Cursor versionsObject) {
+ private void toSlime(Version platformVersion, RevisionId revsion, Cursor versionsObject) {
versionsObject.setString(platformVersionField, platformVersion.toString());
- applicationVersion.buildNumber().ifPresent(number -> versionsObject.setLong(buildField, number));
- applicationVersion.source().map(SourceRevision::repository).ifPresent(repository -> versionsObject.setString(repositoryField, repository));
- applicationVersion.source().map(SourceRevision::branch).ifPresent(branch -> versionsObject.setString(branchField, branch));
- applicationVersion.source().map(SourceRevision::commit).ifPresent(commit -> versionsObject.setString(commitField, commit));
- applicationVersion.authorEmail().ifPresent(email -> versionsObject.setString(authorEmailField, email));
- applicationVersion.compileVersion().ifPresent(version -> versionsObject.setString(compileVersionField, version.toString()));
- applicationVersion.buildTime().ifPresent(time -> versionsObject.setLong(buildTimeField, time.toEpochMilli()));
- applicationVersion.sourceUrl().ifPresent(url -> versionsObject.setString(sourceUrlField, url));
- applicationVersion.commit().ifPresent(commit -> versionsObject.setString(commitField, commit));
- versionsObject.setBool(deployedDirectlyField, applicationVersion.isDeployedDirectly());
+ versionsObject.setLong(buildField, revsion.number());
+ versionsObject.setBool(deployedDirectlyField, ! revsion.isProduction());
}
// Don't change this - introduce a separate array with new values if needed.
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
index b0262506c42..8b43de58cbe 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
@@ -2492,7 +2492,7 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler {
.max(Comparator.naturalOrder())
.or(() -> applications.stream()
.flatMap(application -> application.instances().values().stream())
- .flatMap(instance -> JobType.allIn(controller.system()).stream()
+ .flatMap(instance -> JobType.allIn(controller.zoneRegistry()).stream()
.filter(job -> job.environment() == Environment.dev)
.flatMap(jobType -> controller.jobController().last(instance.id(), jobType).stream()))
.map(Run::start)
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java
index cf3642144b1..0bbfaea3e6f 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java
@@ -77,18 +77,18 @@ class JobControllerApiHandlerHelper {
Cursor responseObject = slime.setObject();
Cursor jobsArray = responseObject.setArray("deployment");
- Arrays.stream(JobType.values())
- .filter(type -> type.environment().isManuallyDeployed())
- .map(devType -> new JobId(id, devType))
- .forEach(job -> {
- Collection<Run> runs = controller.jobController().runs(job).descendingMap().values();
- if (runs.isEmpty())
- return;
-
- Cursor jobObject = jobsArray.addObject();
- jobObject.setString("jobName", job.type().jobName());
- toSlime(jobObject.setArray("runs"), runs, controller.applications().requireApplication(TenantAndApplicationId.from(id)), 10, baseUriForJobs);
- });
+ JobType.allIn(controller.zoneRegistry()).stream()
+ .filter(type -> type.environment().isManuallyDeployed())
+ .map(devType -> new JobId(id, devType))
+ .forEach(job -> {
+ Collection<Run> runs = controller.jobController().runs(job).descendingMap().values();
+ if (runs.isEmpty())
+ return;
+
+ Cursor jobObject = jobsArray.addObject();
+ jobObject.setString("jobName", job.type().jobName());
+ toSlime(jobObject.setArray("runs"), runs, controller.applications().requireApplication(TenantAndApplicationId.from(id)), 10, baseUriForJobs);
+ });
return new SlimeJsonResponse(slime);
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiHandler.java
index 1a4a42cb521..effa0906b94 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiHandler.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiHandler.java
@@ -210,7 +210,7 @@ public class DeploymentApiHandler extends ThreadedHttpRequestHandler {
});
});
}
- JobType.allIn(controller.system()).stream()
+ JobType.allIn(controller.zoneRegistry()).stream()
.filter(job -> ! job.environment().isManuallyDeployed())
.map(JobType::jobName).forEach(root.setArray("jobs")::addString);
return new SlimeJsonResponse(slime);
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java
index 04ee21117a9..5a330b00809 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java
@@ -24,10 +24,12 @@ import java.time.Duration;
import java.time.Instant;
import java.util.Collection;
import java.util.EnumSet;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalLong;
+import java.util.Set;
import java.util.stream.Collectors;
import static ai.vespa.validation.Validation.require;
@@ -213,9 +215,9 @@ public class DeploymentTriggerTest {
app.runJob(systemTest).runJob(stagingTest);
tester.triggerJobs();
tester.runner().run();
- assertEquals(EnumSet.of(productionUsCentral1), tester.jobs().active().stream()
- .map(run -> run.id().type())
- .collect(Collectors.toCollection(() -> EnumSet.noneOf(JobType.class))));
+ assertEquals(Set.of(productionUsCentral1), tester.jobs().active().stream()
+ .map(run -> run.id().type())
+ .collect(Collectors.toCollection(HashSet::new)));
}
@Test
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java
index 1fc99b0da1c..5941812d66d 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java
@@ -159,6 +159,7 @@ public class ApplicationSerializerTest {
assertEquals(original.id(), serialized.id());
assertEquals(original.createdAt(), serialized.createdAt());
assertEquals(applicationVersion1, serialized.revisions().last().get());
+ assertEquals(applicationVersion1, serialized.revisions().get(serialized.instances().get(id1.instance()).deployments().get(zone1).revision()));
assertEquals(original.revisions().last(), serialized.revisions().last());
assertEquals(original.revisions().last().get().authorEmail(), serialized.revisions().last().get().authorEmail());
assertEquals(original.revisions().last().get().buildTime(), serialized.revisions().last().get().buildTime());
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializerTest.java
index f5922fd74aa..c63af87c08c 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializerTest.java
@@ -90,21 +90,6 @@ public class RunSerializerTest {
assertEquals(new Version(1, 2, 3), run.versions().targetPlatform());
RevisionId revision1 = RevisionId.forDevelopment(123, id.job());
RevisionId revision2 = RevisionId.forProduction(122);
- ApplicationVersion applicationVersion1 = new ApplicationVersion(revision1,
- Optional.of(new SourceRevision("git@github.com:user/repo.git", "master", "f00bad")),
- Optional.of("a@b"),
- Optional.of(Version.fromString("6.3.1")),
- Optional.of(Instant.ofEpochMilli(100)),
- Optional.empty(),
- Optional.empty(),
- Optional.empty(),
- true,
- false,
- Optional.empty(),
- 0);
- ApplicationVersion applicationVersion2 = ApplicationVersion.from(revision2, new SourceRevision("git@github.com:user/repo.git",
- "master",
- "badb17"));
assertEquals(revision1, run.versions().targetRevision());
assertEquals("because", run.reason().get());
assertEquals(new Version(1, 2, 2), run.versions().sourcePlatform().get());
@@ -138,8 +123,6 @@ public class RunSerializerTest {
.build(),
run.steps());
- Map<RevisionId, ApplicationVersion> revisions = Map.of(revision1, applicationVersion1, revision2, applicationVersion2);
-
run = run.with(1L << 50)
.with(Instant.now().truncatedTo(MILLIS))
.noNodesDownSince(Instant.now().truncatedTo(MILLIS))
@@ -148,8 +131,7 @@ public class RunSerializerTest {
assertEquals(aborted, run.status());
assertTrue(run.hasEnded());
- // Run phoenix = serializer.runsFromSlime(serializer.toSlime(List.of(run))); // TODO jonmv: use runs again, once compatability code is gone.
- Run phoenix = serializer.runFromSlime(serializer.toSlime(run, revisions::get));
+ Run phoenix = serializer.runsFromSlime(serializer.toSlime(List.of(run))).get(id);
assertEquals(run.id(), phoenix.id());
assertEquals(run.start(), phoenix.start());
assertEquals(run.end(), phoenix.end());
@@ -162,11 +144,11 @@ public class RunSerializerTest {
assertEquals(run.isDryRun(), phoenix.isDryRun());
assertEquals(run.reason(), phoenix.reason());
- assertEquals(new String(SlimeUtils.toJsonBytes(serializer.toSlime(run, revisions::get).get(), false), UTF_8),
- new String(SlimeUtils.toJsonBytes(serializer.toSlime(phoenix, revisions::get).get(), false), UTF_8));
+ assertEquals(new String(SlimeUtils.toJsonBytes(serializer.toSlime(run).get(), false), UTF_8),
+ new String(SlimeUtils.toJsonBytes(serializer.toSlime(phoenix).get(), false), UTF_8));
Run initial = Run.initial(id, run.versions(), run.isRedeployment(), run.start(), JobProfile.production, Optional.empty());
- assertEquals(initial, serializer.runFromSlime(serializer.toSlime(initial, revisions::get)));
+ assertEquals(initial, serializer.runFromSlime(serializer.toSlime(initial)));
}
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/dev-us-east-1-log-first-part.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/dev-us-east-1-log-first-part.json
index 2e9618c890d..63869ecfba8 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/dev-us-east-1-log-first-part.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/dev-us-east-1-log-first-part.json
@@ -6,7 +6,7 @@
{
"at": 0,
"type": "info",
- "message": "Deploying platform version 6.1 and application dev build 1 for devUsEast1 of default ..."
+ "message": "Deploying platform version 6.1 and application dev build 1 for dev-us-east-1 of default ..."
},
{
"at": 0,