summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2018-06-06 15:55:37 +0200
committerMartin Polden <mpolden@mpolden.no>2018-06-07 10:59:56 +0200
commite114f3f407fb61d00b010c86159d0153f95161c5 (patch)
tree81f0819cc95b19ecb2a0d1c952490941ace297cf
parentbe02268dc732784e577ed40040585f88b27e63f8 (diff)
Remove LockedApplication inheritance
This avoids passing around LockedApplication as Application in code that don't require a modifiable application.
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java41
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/LockedApplication.java211
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTrigger.java14
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java10
5 files changed, 138 insertions, 140 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java
index 8b0dc35e16b..5c4e4e6d96b 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java
@@ -256,7 +256,7 @@ public class ApplicationController {
LockedApplication application = new LockedApplication(new Application(id), lock);
store(application);
log.info("Created " + application);
- return application;
+ return application.get();
}
}
@@ -285,7 +285,7 @@ public class ApplicationController {
} else {
JobType jobType = JobType.from(controller.system(), zone)
.orElseThrow(() -> new IllegalArgumentException("No job found for zone " + zone));
- Optional<JobStatus> job = Optional.ofNullable(application.deploymentJobs().jobStatus().get(jobType));
+ Optional<JobStatus> job = Optional.ofNullable(application.get().deploymentJobs().jobStatus().get(jobType));
if ( ! job.isPresent()
|| ! job.get().lastTriggered().isPresent()
|| job.get().lastCompleted().isPresent() && job.get().lastCompleted().get().at().isAfter(job.get().lastTriggered().get().at()))
@@ -297,8 +297,8 @@ public class ApplicationController {
applicationVersion = preferOldestVersion
? triggered.sourceApplication().orElse(triggered.application())
: triggered.application();
- applicationPackage = new ApplicationPackage(artifactRepository.getApplicationPackage(application.id(), applicationVersion.id()));
- validateRun(application, zone, platformVersion, applicationVersion);
+ applicationPackage = new ApplicationPackage(artifactRepository.getApplicationPackage(application.get().id(), applicationVersion.id()));
+ validateRun(application.get(), zone, platformVersion, applicationVersion);
}
validate(applicationPackage.deploymentSpec());
@@ -323,7 +323,7 @@ public class ApplicationController {
application = withRotation(application, zone);
Set<String> rotationNames = new HashSet<>();
Set<String> cnames = new HashSet<>();
- application.rotation().ifPresent(applicationRotation -> {
+ application.get().rotation().ifPresent(applicationRotation -> {
rotationNames.add(applicationRotation.id().asString());
cnames.add(applicationRotation.dnsName());
cnames.add(applicationRotation.secureDnsName());
@@ -366,15 +366,15 @@ public class ApplicationController {
/** Makes sure the application has a global rotation, if eligible. */
private LockedApplication withRotation(LockedApplication application, ZoneId zone) {
- if (zone.environment() == Environment.prod && application.deploymentSpec().globalServiceId().isPresent()) {
+ if (zone.environment() == Environment.prod && application.get().deploymentSpec().globalServiceId().isPresent()) {
try (RotationLock rotationLock = rotationRepository.lock()) {
- Rotation rotation = rotationRepository.getOrAssignRotation(application, rotationLock);
+ Rotation rotation = rotationRepository.getOrAssignRotation(application.get(), rotationLock);
application = application.with(rotation.id());
store(application); // store assigned rotation even if deployment fails
- registerRotationInDns(rotation, application.rotation().get().dnsName());
- registerRotationInDns(rotation, application.rotation().get().secureDnsName());
- registerRotationInDns(rotation, application.rotation().get().oathDnsName());
+ registerRotationInDns(rotation, application.get().rotation().get().dnsName());
+ registerRotationInDns(rotation, application.get().rotation().get().secureDnsName());
+ registerRotationInDns(rotation, application.get().rotation().get().oathDnsName());
}
}
return application;
@@ -394,15 +394,15 @@ public class ApplicationController {
}
private LockedApplication deleteRemovedDeployments(LockedApplication application) {
- List<Deployment> deploymentsToRemove = application.productionDeployments().values().stream()
- .filter(deployment -> ! application.deploymentSpec().includes(deployment.zone().environment(),
- Optional.of(deployment.zone().region())))
+ List<Deployment> deploymentsToRemove = application.get().productionDeployments().values().stream()
+ .filter(deployment -> ! application.get().deploymentSpec().includes(deployment.zone().environment(),
+ Optional.of(deployment.zone().region())))
.collect(Collectors.toList());
if (deploymentsToRemove.isEmpty()) return application;
- if ( ! application.validationOverrides().allows(ValidationId.deploymentRemoval, clock.instant()))
- throw new IllegalArgumentException(ValidationId.deploymentRemoval.value() + ": " + application +
+ if ( ! application.get().validationOverrides().allows(ValidationId.deploymentRemoval, clock.instant()))
+ throw new IllegalArgumentException(ValidationId.deploymentRemoval.value() + ": " + application.get() +
" is deployed in " +
deploymentsToRemove.stream()
.map(deployment -> deployment.zone().region().value())
@@ -418,10 +418,11 @@ public class ApplicationController {
}
private LockedApplication deleteUnreferencedDeploymentJobs(LockedApplication application) {
- for (JobType job : application.deploymentJobs().jobStatus().keySet()) {
+ for (JobType job : application.get().deploymentJobs().jobStatus().keySet()) {
Optional<ZoneId> zone = job.zone(controller.system());
- if ( ! job.isProduction() || (zone.isPresent() && application.deploymentSpec().includes(zone.get().environment(), zone.map(ZoneId::region))))
+ if ( ! job.isProduction() || (zone.isPresent() && application.get().deploymentSpec().includes(
+ zone.get().environment(), zone.map(ZoneId::region))))
continue;
application = application.withoutDeploymentJob(job);
}
@@ -493,7 +494,7 @@ public class ApplicationController {
// TODO: Make this one transaction when database is moved to ZooKeeper
instances.forEach(id -> lockOrThrow(id, application -> {
- if ( ! application.deployments().isEmpty())
+ if ( ! application.get().deployments().isEmpty())
throw new IllegalArgumentException("Could not delete '" + application + "': It has active deployments");
Tenant tenant = controller.tenants().tenant(id.tenant()).get();
@@ -518,7 +519,7 @@ public class ApplicationController {
* @param application a locked application to store
*/
public void store(LockedApplication application) {
- curator.writeApplication(application);
+ curator.writeApplication(application.get());
}
/**
@@ -572,7 +573,7 @@ public class ApplicationController {
*/
private LockedApplication deactivate(LockedApplication application, ZoneId zone) {
try {
- configServer.deactivate(new DeploymentId(application.id(), zone));
+ configServer.deactivate(new DeploymentId(application.get().id(), zone));
}
catch (NoInstanceException ignored) {
// ok; already gone
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/LockedApplication.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/LockedApplication.java
index 795b12f8af9..3207d4b8399 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/LockedApplication.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/LockedApplication.java
@@ -26,17 +26,29 @@ import com.yahoo.vespa.hosted.controller.rotation.RotationId;
import java.time.Instant;
import java.util.LinkedHashMap;
import java.util.Map;
+import java.util.Objects;
import java.util.Optional;
import java.util.OptionalLong;
/**
- * A combination of an application instance and a lock for that application. Provides methods for updating application
- * fields.
+ * An application that has been locked for modification. Provides methods for modifying an application's fields.
*
* @author mpolden
* @author jvenstad
*/
-public class LockedApplication extends Application {
+public class LockedApplication {
+
+ private final Lock lock;
+ private final ApplicationId id;
+ private final DeploymentSpec deploymentSpec;
+ private final ValidationOverrides validationOverrides;
+ private final Map<ZoneId, Deployment> deployments;
+ private final DeploymentJobs deploymentJobs;
+ private final Change change;
+ private final Change outstandingChange;
+ private final Optional<IssueId> ownershipIssueId;
+ private final ApplicationMetrics metrics;
+ private final Optional<RotationId> rotation;
/**
* Used to create a locked application
@@ -44,38 +56,69 @@ public class LockedApplication extends Application {
* @param application The application to lock.
* @param lock The lock for the application.
*/
- LockedApplication(Application application, @SuppressWarnings("unused") Lock lock) {
- this(new Builder(application));
- }
-
- private LockedApplication(Builder builder) {
- super(builder.applicationId, builder.deploymentSpec, builder.validationOverrides,
- builder.deployments, builder.deploymentJobs, builder.deploying,
- builder.outstandingChange, builder.ownershipIssueId, builder.metrics, builder.rotation);
+ LockedApplication(Application application, Lock lock) {
+ this(Objects.requireNonNull(lock, "lock cannot be null"), application.id(),
+ application.deploymentSpec(), application.validationOverrides(),
+ application.deployments(),
+ application.deploymentJobs(), application.change(), application.outstandingChange(),
+ application.ownershipIssueId(), application.metrics(),
+ application.rotation().map(ApplicationRotation::id));
+ }
+
+ private LockedApplication(Lock lock, ApplicationId id,
+ DeploymentSpec deploymentSpec, ValidationOverrides validationOverrides,
+ Map<ZoneId, Deployment> deployments, DeploymentJobs deploymentJobs, Change change,
+ Change outstandingChange, Optional<IssueId> ownershipIssueId, ApplicationMetrics metrics,
+ Optional<RotationId> rotation) {
+ this.lock = lock;
+ this.id = id;
+ this.deploymentSpec = deploymentSpec;
+ this.validationOverrides = validationOverrides;
+ this.deployments = deployments;
+ this.deploymentJobs = deploymentJobs;
+ this.change = change;
+ this.outstandingChange = outstandingChange;
+ this.ownershipIssueId = ownershipIssueId;
+ this.metrics = metrics;
+ this.rotation = rotation;
+ }
+
+ /** Returns a read-only copy of this */
+ public Application get() {
+ return new Application(id, deploymentSpec, validationOverrides, deployments, deploymentJobs, change,
+ outstandingChange, ownershipIssueId, metrics, rotation);
}
public LockedApplication withProjectId(OptionalLong projectId) {
- return new LockedApplication(new Builder(this).with(deploymentJobs().withProjectId(projectId)));
+ return new LockedApplication(lock, id, deploymentSpec, validationOverrides, deployments,
+ deploymentJobs.withProjectId(projectId), change, outstandingChange,
+ ownershipIssueId, metrics, rotation);
}
public LockedApplication withDeploymentIssueId(IssueId issueId) {
- return new LockedApplication(new Builder(this).with(deploymentJobs().with(issueId)));
+ return new LockedApplication(lock, id, deploymentSpec, validationOverrides, deployments,
+ deploymentJobs.with(issueId), change, outstandingChange,
+ ownershipIssueId, metrics, rotation);
}
- public LockedApplication withJobCompletion(long projectId, JobType jobType, JobStatus.JobRun completion, Optional<DeploymentJobs.JobError> jobError) {
- return new LockedApplication(new Builder(this).with(deploymentJobs().withCompletion(projectId, jobType, completion, jobError))
- );
+ public LockedApplication withJobCompletion(long projectId, JobType jobType, JobStatus.JobRun completion,
+ Optional<DeploymentJobs.JobError> jobError) {
+ return new LockedApplication(lock, id, deploymentSpec, validationOverrides, deployments,
+ deploymentJobs.withCompletion(projectId, jobType, completion, jobError),
+ change, outstandingChange, ownershipIssueId, metrics, rotation);
}
public LockedApplication withJobTriggering(JobType jobType, JobStatus.JobRun job) {
- return new LockedApplication(new Builder(this).with(deploymentJobs().withTriggering(jobType, job)));
+ return new LockedApplication(lock, id, deploymentSpec, validationOverrides, deployments,
+ deploymentJobs.withTriggering(jobType, job), change, outstandingChange,
+ ownershipIssueId, metrics, rotation);
}
public LockedApplication withNewDeployment(ZoneId zone, ApplicationVersion applicationVersion, Version version,
Instant instant) {
// Use info from previous deployment if available, otherwise create a new one.
- Deployment previousDeployment = deployments().getOrDefault(zone, new Deployment(zone, applicationVersion,
- version, instant));
+ Deployment previousDeployment = deployments.getOrDefault(zone, new Deployment(zone, applicationVersion,
+ version, instant));
Deployment newDeployment = new Deployment(zone, applicationVersion, version, instant,
previousDeployment.clusterUtils(),
previousDeployment.clusterInfo(),
@@ -85,146 +128,100 @@ public class LockedApplication extends Application {
}
public LockedApplication withClusterUtilization(ZoneId zone, Map<ClusterSpec.Id, ClusterUtilization> clusterUtilization) {
- Deployment deployment = deployments().get(zone);
+ Deployment deployment = deployments.get(zone);
if (deployment == null) return this; // No longer deployed in this zone.
return with(deployment.withClusterUtils(clusterUtilization));
}
public LockedApplication withClusterInfo(ZoneId zone, Map<ClusterSpec.Id, ClusterInfo> clusterInfo) {
- Deployment deployment = deployments().get(zone);
+ Deployment deployment = deployments.get(zone);
if (deployment == null) return this; // No longer deployed in this zone.
return with(deployment.withClusterInfo(clusterInfo));
}
public LockedApplication recordActivityAt(Instant instant, ZoneId zone) {
- Deployment deployment = deployments().get(zone);
+ Deployment deployment = deployments.get(zone);
if (deployment == null) return this;
return with(deployment.recordActivityAt(instant));
}
public LockedApplication with(ZoneId zone, DeploymentMetrics deploymentMetrics) {
- Deployment deployment = deployments().get(zone);
+ Deployment deployment = deployments.get(zone);
if (deployment == null) return this; // No longer deployed in this zone.
return with(deployment.withMetrics(deploymentMetrics));
}
public LockedApplication withoutDeploymentIn(ZoneId zone) {
- Map<ZoneId, Deployment> deployments = new LinkedHashMap<>(deployments());
+ Map<ZoneId, Deployment> deployments = new LinkedHashMap<>(this.deployments);
deployments.remove(zone);
- return new LockedApplication(new Builder(this).with(deployments));
+ return with(deployments);
}
public LockedApplication withoutDeploymentJob(DeploymentJobs.JobType jobType) {
- return new LockedApplication(new Builder(this).with(deploymentJobs().without(jobType)));
+ return new LockedApplication(lock, id, deploymentSpec, validationOverrides, deployments,
+ deploymentJobs.without(jobType), change, outstandingChange,
+ ownershipIssueId, metrics, rotation);
}
public LockedApplication with(DeploymentSpec deploymentSpec) {
- return new LockedApplication(new Builder(this).with(deploymentSpec));
+ return new LockedApplication(lock, id, deploymentSpec, validationOverrides, deployments,
+ deploymentJobs, change, outstandingChange,
+ ownershipIssueId, metrics, rotation);
}
public LockedApplication with(ValidationOverrides validationOverrides) {
- return new LockedApplication(new Builder(this).with(validationOverrides));
+ return new LockedApplication(lock, id, deploymentSpec, validationOverrides, deployments,
+ deploymentJobs, change, outstandingChange,
+ ownershipIssueId, metrics, rotation);
}
public LockedApplication withChange(Change change) {
- return new LockedApplication(new Builder(this).withChange(change));
+ return new LockedApplication(lock, id, deploymentSpec, validationOverrides, deployments,
+ deploymentJobs, change, outstandingChange,
+ ownershipIssueId, metrics, rotation);
}
public LockedApplication withOutstandingChange(Change outstandingChange) {
- return new LockedApplication(new Builder(this).withOutstandingChange(outstandingChange));
+ return new LockedApplication(lock, id, deploymentSpec, validationOverrides, deployments,
+ deploymentJobs, change, outstandingChange,
+ ownershipIssueId, metrics, rotation);
}
public LockedApplication withOwnershipIssueId(IssueId issueId) {
- return new LockedApplication(new Builder(this).withOwnershipIssueId(Optional.ofNullable(issueId)));
+ return new LockedApplication(lock, id, deploymentSpec, validationOverrides, deployments,
+ deploymentJobs, change, outstandingChange,
+ Optional.ofNullable(issueId), metrics, rotation);
}
public LockedApplication with(MetricsService.ApplicationMetrics metrics) {
- return new LockedApplication(new Builder(this).with(metrics));
+ return new LockedApplication(lock, id, deploymentSpec, validationOverrides, deployments,
+ deploymentJobs, change, outstandingChange,
+ ownershipIssueId, metrics, rotation);
}
public LockedApplication with(RotationId rotation) {
- return new LockedApplication(new Builder(this).with(rotation));
+ return new LockedApplication(lock, id, deploymentSpec, validationOverrides, deployments,
+ deploymentJobs, change, outstandingChange,
+ ownershipIssueId, metrics, Optional.of(rotation));
}
/** Don't expose non-leaf sub-objects. */
private LockedApplication with(Deployment deployment) {
- Map<ZoneId, Deployment> deployments = new LinkedHashMap<>(deployments());
+ Map<ZoneId, Deployment> deployments = new LinkedHashMap<>(this.deployments);
deployments.put(deployment.zone(), deployment);
- return new LockedApplication(new Builder(this).with(deployments));
- }
-
- private static class Builder {
-
- private final ApplicationId applicationId;
- private DeploymentSpec deploymentSpec;
- private ValidationOverrides validationOverrides;
- private Map<ZoneId, Deployment> deployments;
- private DeploymentJobs deploymentJobs;
- private Change deploying;
- private Change outstandingChange;
- private Optional<IssueId> ownershipIssueId;
- private ApplicationMetrics metrics;
- private Optional<RotationId> rotation;
-
- private Builder(Application application) {
- this.applicationId = application.id();
- this.deploymentSpec = application.deploymentSpec();
- this.validationOverrides = application.validationOverrides();
- this.deployments = application.deployments();
- this.deploymentJobs = application.deploymentJobs();
- this.deploying = application.change();
- this.outstandingChange = application.outstandingChange();
- this.ownershipIssueId = application.ownershipIssueId();
- this.metrics = application.metrics();
- this.rotation = application.rotation().map(ApplicationRotation::id);
- }
-
- private Builder with(DeploymentSpec deploymentSpec) {
- this.deploymentSpec = deploymentSpec;
- return this;
- }
-
- private Builder with(ValidationOverrides validationOverrides) {
- this.validationOverrides = validationOverrides;
- return this;
- }
-
- private Builder with(Map<ZoneId, Deployment> deployments) {
- this.deployments = deployments;
- return this;
- }
-
- private Builder with(DeploymentJobs deploymentJobs) {
- this.deploymentJobs = deploymentJobs;
- return this;
- }
-
- private Builder withChange(Change deploying) {
- this.deploying = deploying;
- return this;
- }
-
- private Builder withOutstandingChange(Change outstandingChange) {
- this.outstandingChange = outstandingChange;
- return this;
- }
-
- private Builder withOwnershipIssueId(Optional<IssueId> ownershipIssueId) {
- this.ownershipIssueId = ownershipIssueId;
- return this;
- }
-
- private Builder with(ApplicationMetrics metrics) {
- this.metrics = metrics;
- return this;
- }
-
- private Builder with(RotationId rotation) {
- this.rotation = Optional.of(rotation);
- return this;
- }
+ return with(deployments);
+ }
+
+ private LockedApplication with(Map<ZoneId, Deployment> deployments) {
+ return new LockedApplication(lock, id, deploymentSpec, validationOverrides, deployments,
+ deploymentJobs, change, outstandingChange,
+ ownershipIssueId, metrics, rotation);
+ }
+ @Override
+ public String toString() {
+ return "application '" + id + "'";
}
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTrigger.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTrigger.java
index e902206ad8b..9a9e03be697 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTrigger.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTrigger.java
@@ -116,15 +116,15 @@ public class DeploymentTrigger {
triggering = JobRun.triggering(controller.systemVersion(), applicationVersion, Optional
.empty(), Optional.empty(), "Application commit", clock.instant());
if (report.success()) {
- if (acceptNewApplicationVersion(application))
- application = application.withChange(application.change().with(applicationVersion))
+ if (acceptNewApplicationVersion(application.get()))
+ application = application.withChange(application.get().change().with(applicationVersion))
.withOutstandingChange(Change.empty());
else
application = application.withOutstandingChange(Change.of(applicationVersion));
}
}
else {
- triggering = application.deploymentJobs().statusOf(report.jobType()).flatMap(JobStatus::lastTriggered)
+ triggering = application.get().deploymentJobs().statusOf(report.jobType()).flatMap(JobStatus::lastTriggered)
.orElseThrow(() -> new IllegalStateException("Notified of completion of " + report.jobType().jobName() + " for " +
report.applicationId() + ", but that has neither been triggered nor deployed"));
}
@@ -132,7 +132,7 @@ public class DeploymentTrigger {
report.jobType(),
triggering.completion(report.buildNumber(), clock.instant()),
report.jobError());
- application = application.withChange(remainingChange(application));
+ application = application.withChange(remainingChange(application.get()));
applications().store(application);
});
}
@@ -216,9 +216,9 @@ public class DeploymentTrigger {
*/
public void triggerChange(ApplicationId applicationId, Change change) {
applications().lockOrThrow(applicationId, application -> {
- if (application.changeAt(controller.clock().instant()).isPresent() && ! application.deploymentJobs().hasFailures())
+ if (application.get().changeAt(controller.clock().instant()).isPresent() && ! application.get().deploymentJobs().hasFailures())
throw new IllegalArgumentException("Could not start " + change + " on " + application + ": " +
- application.change() + " is already in progress");
+ application.get().change() + " is already in progress");
application = application.withChange(change);
if (change.application().isPresent())
application = application.withOutstandingChange(Change.empty());
@@ -230,7 +230,7 @@ public class DeploymentTrigger {
/** Cancels a platform upgrade of the given application, and an application upgrade as well if {@code keepApplicationChange}. */
public void cancelChange(ApplicationId applicationId, boolean keepApplicationChange) {
applications().lockOrThrow(applicationId, application -> {
- applications().store(application.withChange(application.change().application()
+ applications().store(application.withChange(application.get().change().application()
.filter(__ -> keepApplicationChange)
.map(Change::of)
.orElse(Change.empty())));
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 d58c3ed7dae..6b35e09e049 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
@@ -678,7 +678,7 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
ApplicationId id = ApplicationId.from(tenantName, applicationName, "default");
controller.applications().lockOrThrow(id, application -> {
- controller.applications().deploymentTrigger().triggerChange(application.id(), Change.of(version));
+ controller.applications().deploymentTrigger().triggerChange(application.get().id(), Change.of(version));
});
return new MessageResponse("Triggered deployment of application '" + id + "' on version " + version);
}
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 26cb68647e4..5c5827fa167 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
@@ -156,26 +156,26 @@ public class ApplicationSerializerTest {
assertEquals(original.deployments().get(zone2).metrics().writeLatencyMillis(), serialized.deployments().get(zone2).metrics().writeLatencyMillis(), Double.MIN_VALUE);
{ // test more deployment serialization cases
- Application original2 = writable(original).withChange(Change.of(ApplicationVersion.from(new SourceRevision("repo1", "branch1", "commit1"), 42)));
+ Application original2 = writable(original).withChange(Change.of(ApplicationVersion.from(new SourceRevision("repo1", "branch1", "commit1"), 42))).get();
Application serialized2 = applicationSerializer.fromSlime(applicationSerializer.toSlime(original2));
assertEquals(original2.change(), serialized2.change());
assertEquals(serialized2.change().application().get().source(),
original2.change().application().get().source());
- Application original3 = writable(original).withChange(Change.of(ApplicationVersion.from(new SourceRevision("a", "b", "c"), 42)));
+ Application original3 = writable(original).withChange(Change.of(ApplicationVersion.from(new SourceRevision("a", "b", "c"), 42))).get();
Application serialized3 = applicationSerializer.fromSlime(applicationSerializer.toSlime(original3));
assertEquals(original3.change(), serialized3.change());
assertEquals(serialized3.change().application().get().source(),
original3.change().application().get().source());
- Application original4 = writable(original).withChange(Change.empty());
+ Application original4 = writable(original).withChange(Change.empty()).get();
Application serialized4 = applicationSerializer.fromSlime(applicationSerializer.toSlime(original4));
assertEquals(original4.change(), serialized4.change());
- Application original5 = writable(original).withChange(Change.of(ApplicationVersion.from(new SourceRevision("a", "b", "c"), 42)));
+ Application original5 = writable(original).withChange(Change.of(ApplicationVersion.from(new SourceRevision("a", "b", "c"), 42))).get();
Application serialized5 = applicationSerializer.fromSlime(applicationSerializer.toSlime(original5));
assertEquals(original5.change(), serialized5.change());
- Application original6 = writable(original).withOutstandingChange(Change.of(ApplicationVersion.from(new SourceRevision("a", "b", "c"), 42)));
+ Application original6 = writable(original).withOutstandingChange(Change.of(ApplicationVersion.from(new SourceRevision("a", "b", "c"), 42))).get();
Application serialized6 = applicationSerializer.fromSlime(applicationSerializer.toSlime(original6));
assertEquals(original6.outstandingChange(), serialized6.outstandingChange());
}