summaryrefslogtreecommitdiffstats
path: root/controller-server/src
diff options
context:
space:
mode:
authorolaaun <olaa@oath.com>2018-11-21 14:19:50 +0100
committerGitHub <noreply@github.com>2018-11-21 14:19:50 +0100
commit5ebe52d9631cedfd7893b43674782b679c655008 (patch)
treebce570c7c9449d3edb30b072d601bd3679583b7b /controller-server/src
parent18e7977064d2266209248399536d91fc742d5aba (diff)
Add owner to application info (#7724)
Diffstat (limited to 'controller-server/src')
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Application.java15
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/LockedApplication.java47
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ApplicationOwnershipConfirmer.java17
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java6
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java1
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ApplicationOwnershipConfirmerTest.java16
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java3
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java4
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application1-recursive.json1
9 files changed, 80 insertions, 30 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Application.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Application.java
index 619f8abc180..1baff026385 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Application.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Application.java
@@ -11,6 +11,7 @@ import com.yahoo.config.provision.HostName;
import com.yahoo.config.provision.SystemName;
import com.yahoo.vespa.hosted.controller.api.integration.MetricsService.ApplicationMetrics;
import com.yahoo.vespa.hosted.controller.api.integration.organization.IssueId;
+import com.yahoo.vespa.hosted.controller.api.integration.organization.User;
import com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneId;
import com.yahoo.vespa.hosted.controller.application.ApplicationActivity;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.ApplicationVersion;
@@ -50,6 +51,7 @@ public class Application {
private final Change change;
private final Change outstandingChange;
private final Optional<IssueId> ownershipIssueId;
+ private final Optional<User> owner;
private final ApplicationMetrics metrics;
private final Optional<RotationId> rotation;
private final Map<HostName, RotationStatus> rotationStatus;
@@ -58,23 +60,23 @@ public class Application {
public Application(ApplicationId id, Instant now) {
this(id, now, DeploymentSpec.empty, ValidationOverrides.empty, Collections.emptyMap(),
new DeploymentJobs(OptionalLong.empty(), Collections.emptyList(), Optional.empty(), false),
- Change.empty(), Change.empty(), Optional.empty(), new ApplicationMetrics(0, 0),
+ Change.empty(), Change.empty(), Optional.empty(), Optional.empty(), new ApplicationMetrics(0, 0),
Optional.empty(), Collections.emptyMap());
}
/** Used from persistence layer: Do not use */
public Application(ApplicationId id, Instant createdAt, DeploymentSpec deploymentSpec, ValidationOverrides validationOverrides,
List<Deployment> deployments, DeploymentJobs deploymentJobs, Change change,
- Change outstandingChange, Optional<IssueId> ownershipIssueId, ApplicationMetrics metrics,
+ Change outstandingChange, Optional<IssueId> ownershipIssueId, Optional<User> owner, ApplicationMetrics metrics,
Optional<RotationId> rotation, Map<HostName, RotationStatus> rotationStatus) {
this(id, createdAt, deploymentSpec, validationOverrides,
deployments.stream().collect(Collectors.toMap(Deployment::zone, d -> d)),
- deploymentJobs, change, outstandingChange, ownershipIssueId, metrics, rotation, rotationStatus);
+ deploymentJobs, change, outstandingChange, ownershipIssueId, owner, metrics, rotation, rotationStatus);
}
Application(ApplicationId id, Instant createdAt, DeploymentSpec deploymentSpec, ValidationOverrides validationOverrides,
Map<ZoneId, Deployment> deployments, DeploymentJobs deploymentJobs, Change change,
- Change outstandingChange, Optional<IssueId> ownershipIssueId, ApplicationMetrics metrics,
+ Change outstandingChange, Optional<IssueId> ownershipIssueId, Optional<User> owner, ApplicationMetrics metrics,
Optional<RotationId> rotation, Map<HostName, RotationStatus> rotationStatus) {
this.id = Objects.requireNonNull(id, "id cannot be null");
this.createdAt = Objects.requireNonNull(createdAt, "instant of creation cannot be null");
@@ -85,6 +87,7 @@ public class Application {
this.change = Objects.requireNonNull(change, "change cannot be null");
this.outstandingChange = Objects.requireNonNull(outstandingChange, "outstandingChange cannot be null");
this.ownershipIssueId = Objects.requireNonNull(ownershipIssueId, "ownershipIssueId cannot be null");
+ this.owner = Objects.requireNonNull(owner, "owner cannot be null");
this.metrics = Objects.requireNonNull(metrics, "metrics cannot be null");
this.rotation = Objects.requireNonNull(rotation, "rotation cannot be null");
this.rotationStatus = ImmutableMap.copyOf(Objects.requireNonNull(rotationStatus, "rotationStatus cannot be null"));
@@ -139,6 +142,10 @@ public class Application {
return ownershipIssueId;
}
+ public Optional<User> owner() {
+ return owner;
+ }
+
/** Returns metrics for this */
public ApplicationMetrics metrics() {
return metrics;
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 5951ceb4792..1e138dd5a4d 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
@@ -12,6 +12,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.MetricsService;
import com.yahoo.vespa.hosted.controller.api.integration.MetricsService.ApplicationMetrics;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType;
import com.yahoo.vespa.hosted.controller.api.integration.organization.IssueId;
+import com.yahoo.vespa.hosted.controller.api.integration.organization.User;
import com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneId;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.ApplicationVersion;
import com.yahoo.vespa.hosted.controller.application.Change;
@@ -49,6 +50,7 @@ public class LockedApplication {
private final Change change;
private final Change outstandingChange;
private final Optional<IssueId> ownershipIssueId;
+ private Optional<User> owner;
private final ApplicationMetrics metrics;
private final Optional<RotationId> rotation;
private final Map<HostName, RotationStatus> rotationStatus;
@@ -64,7 +66,7 @@ public class LockedApplication {
application.deploymentSpec(), application.validationOverrides(),
application.deployments(),
application.deploymentJobs(), application.change(), application.outstandingChange(),
- application.ownershipIssueId(), application.metrics(),
+ application.ownershipIssueId(), application.owner(), application.metrics(),
application.rotation(),
application.rotationStatus());
}
@@ -72,7 +74,7 @@ public class LockedApplication {
private LockedApplication(Lock lock, ApplicationId id, Instant createdAt,
DeploymentSpec deploymentSpec, ValidationOverrides validationOverrides,
Map<ZoneId, Deployment> deployments, DeploymentJobs deploymentJobs, Change change,
- Change outstandingChange, Optional<IssueId> ownershipIssueId, ApplicationMetrics metrics,
+ Change outstandingChange, Optional<IssueId> ownershipIssueId, Optional<User> owner, ApplicationMetrics metrics,
Optional<RotationId> rotation, Map<HostName, RotationStatus> rotationStatus) {
this.lock = lock;
this.id = id;
@@ -84,6 +86,7 @@ public class LockedApplication {
this.change = change;
this.outstandingChange = outstandingChange;
this.ownershipIssueId = ownershipIssueId;
+ this.owner = owner;
this.metrics = metrics;
this.rotation = rotation;
this.rotationStatus = rotationStatus;
@@ -92,44 +95,44 @@ public class LockedApplication {
/** Returns a read-only copy of this */
public Application get() {
return new Application(id, createdAt, deploymentSpec, validationOverrides, deployments, deploymentJobs, change,
- outstandingChange, ownershipIssueId, metrics, rotation, rotationStatus);
+ outstandingChange, ownershipIssueId, owner, metrics, rotation, rotationStatus);
}
public LockedApplication withBuiltInternally(boolean builtInternally) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides, deployments,
deploymentJobs.withBuiltInternally(builtInternally), change, outstandingChange,
- ownershipIssueId, metrics, rotation, rotationStatus);
+ ownershipIssueId, owner, metrics, rotation, rotationStatus);
}
public LockedApplication withProjectId(OptionalLong projectId) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides, deployments,
deploymentJobs.withProjectId(projectId), change, outstandingChange,
- ownershipIssueId, metrics, rotation, rotationStatus);
+ ownershipIssueId, owner, metrics, rotation, rotationStatus);
}
public LockedApplication withDeploymentIssueId(IssueId issueId) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides, deployments,
deploymentJobs.with(issueId), change, outstandingChange,
- ownershipIssueId, metrics, rotation, rotationStatus);
+ ownershipIssueId, owner, metrics, rotation, rotationStatus);
}
public LockedApplication withJobPause(JobType jobType, OptionalLong pausedUntil) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides, deployments,
deploymentJobs.withPause(jobType, pausedUntil), change, outstandingChange,
- ownershipIssueId, metrics, rotation, rotationStatus);
+ ownershipIssueId, owner, metrics, rotation, rotationStatus);
}
public LockedApplication withJobCompletion(long projectId, JobType jobType, JobStatus.JobRun completion,
Optional<DeploymentJobs.JobError> jobError) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides, deployments,
deploymentJobs.withCompletion(projectId, jobType, completion, jobError),
- change, outstandingChange, ownershipIssueId, metrics, rotation, rotationStatus);
+ change, outstandingChange, ownershipIssueId, owner, metrics, rotation, rotationStatus);
}
public LockedApplication withJobTriggering(JobType jobType, JobStatus.JobRun job) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides, deployments,
deploymentJobs.withTriggering(jobType, job), change, outstandingChange,
- ownershipIssueId, metrics, rotation, rotationStatus);
+ ownershipIssueId, owner, metrics, rotation, rotationStatus);
}
public LockedApplication withNewDeployment(ZoneId zone, ApplicationVersion applicationVersion, Version version,
@@ -179,54 +182,60 @@ public class LockedApplication {
public LockedApplication withoutDeploymentJob(JobType jobType) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides, deployments,
deploymentJobs.without(jobType), change, outstandingChange,
- ownershipIssueId, metrics, rotation, rotationStatus);
+ ownershipIssueId, owner, metrics, rotation, rotationStatus);
}
public LockedApplication with(DeploymentSpec deploymentSpec) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides, deployments,
deploymentJobs, change, outstandingChange,
- ownershipIssueId, metrics, rotation, rotationStatus);
+ ownershipIssueId, owner, metrics, rotation, rotationStatus);
}
public LockedApplication with(ValidationOverrides validationOverrides) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides, deployments,
deploymentJobs, change, outstandingChange,
- ownershipIssueId, metrics, rotation, rotationStatus);
+ ownershipIssueId, owner, metrics, rotation, rotationStatus);
}
public LockedApplication withChange(Change change) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides, deployments,
deploymentJobs, change, outstandingChange,
- ownershipIssueId, metrics, rotation, rotationStatus);
+ ownershipIssueId, owner, metrics, rotation, rotationStatus);
}
public LockedApplication withOutstandingChange(Change outstandingChange) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides, deployments,
deploymentJobs, change, outstandingChange,
- ownershipIssueId, metrics, rotation, rotationStatus);
+ ownershipIssueId, owner, metrics, rotation, rotationStatus);
}
public LockedApplication withOwnershipIssueId(IssueId issueId) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides, deployments,
deploymentJobs, change, outstandingChange,
- Optional.ofNullable(issueId), metrics, rotation, rotationStatus);
+ Optional.ofNullable(issueId), owner, metrics, rotation, rotationStatus);
+ }
+
+ public LockedApplication withOwner(User owner) {
+ return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides, deployments,
+ deploymentJobs, change, outstandingChange,
+ ownershipIssueId, Optional.ofNullable(owner), metrics, rotation, rotationStatus);
}
public LockedApplication with(MetricsService.ApplicationMetrics metrics) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides, deployments,
deploymentJobs, change, outstandingChange,
- ownershipIssueId, metrics, rotation, rotationStatus);
+ ownershipIssueId, owner, metrics, rotation, rotationStatus);
}
public LockedApplication with(RotationId rotation) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides, deployments,
deploymentJobs, change, outstandingChange,
- ownershipIssueId, metrics, Optional.of(rotation), rotationStatus);
+ ownershipIssueId, owner, metrics, Optional.of(rotation), rotationStatus);
}
public LockedApplication withRotationStatus(Map<HostName, RotationStatus> rotationStatus) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides, deployments, deploymentJobs, change,
- outstandingChange, ownershipIssueId, metrics, rotation, rotationStatus);
+ outstandingChange, ownershipIssueId, owner, metrics, rotation, rotationStatus);
}
/** Don't expose non-leaf sub-objects. */
@@ -239,7 +248,7 @@ public class LockedApplication {
private LockedApplication with(Map<ZoneId, Deployment> deployments) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides, deployments,
deploymentJobs, change, outstandingChange,
- ownershipIssueId, metrics, rotation, rotationStatus);
+ ownershipIssueId, owner, metrics, rotation, rotationStatus);
}
@Override
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ApplicationOwnershipConfirmer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ApplicationOwnershipConfirmer.java
index 2e6b3d1360d..b710b78682a 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ApplicationOwnershipConfirmer.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ApplicationOwnershipConfirmer.java
@@ -38,6 +38,7 @@ public class ApplicationOwnershipConfirmer extends Maintainer {
protected void maintain() {
confirmApplicationOwnerships();
ensureConfirmationResponses();
+ updateConfirmedApplicationOwners();
}
/** File an ownership issue with the owners of all applications we know about. */
@@ -81,6 +82,22 @@ public class ApplicationOwnershipConfirmer extends Maintainer {
});
}
+ private void updateConfirmedApplicationOwners() {
+ ApplicationList.from(controller().applications().asList())
+ .withProjectId()
+ .hasProductionDeployment()
+ .asList()
+ .stream()
+ .filter(application -> application.ownershipIssueId().isPresent())
+ .forEach(application -> {
+ IssueId ownershipIssueId = application.ownershipIssueId().get();
+ ownershipIssues.getConfirmedOwner(ownershipIssueId).ifPresent(owner -> {
+ controller().applications().lockIfPresent(application.id(), lockedApplication ->
+ controller().applications().store(lockedApplication.withOwner(owner)));
+ });
+ });
+ }
+
private Tenant ownerOf(ApplicationId applicationId) {
return controller().tenants().tenant(applicationId.tenant())
.orElseThrow(() -> new IllegalStateException("No tenant found for application " + applicationId));
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 c69e77a43e1..9c087a101b9 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
@@ -16,6 +16,7 @@ import com.yahoo.vespa.hosted.controller.Application;
import com.yahoo.vespa.hosted.controller.api.integration.MetricsService.ApplicationMetrics;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType;
import com.yahoo.vespa.hosted.controller.api.integration.organization.IssueId;
+import com.yahoo.vespa.hosted.controller.api.integration.organization.User;
import com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneId;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.ApplicationVersion;
import com.yahoo.vespa.hosted.controller.application.Change;
@@ -61,6 +62,7 @@ public class ApplicationSerializer {
private final String deployingField = "deployingField";
private final String outstandingChangeField = "outstandingChangeField";
private final String ownershipIssueIdField = "ownershipIssueId";
+ private final String ownerField = "confirmedOwner";
private final String writeQualityField = "writeQuality";
private final String queryQualityField = "queryQuality";
private final String rotationField = "rotation";
@@ -146,6 +148,7 @@ public class ApplicationSerializer {
toSlime(application.change(), root, deployingField);
toSlime(application.outstandingChange(), root, outstandingChangeField);
application.ownershipIssueId().ifPresent(issueId -> root.setString(ownershipIssueIdField, issueId.value()));
+ application.owner().ifPresent(owner -> root.setString(ownerField, owner.username()));
root.setDouble(queryQualityField, application.metrics().queryServiceQuality());
root.setDouble(writeQualityField, application.metrics().writeServiceQuality());
application.rotation().ifPresent(rotation -> root.setString(rotationField, rotation.asString()));
@@ -301,13 +304,14 @@ public class ApplicationSerializer {
Change deploying = changeFromSlime(root.field(deployingField));
Change outstandingChange = changeFromSlime(root.field(outstandingChangeField));
Optional<IssueId> ownershipIssueId = optionalString(root.field(ownershipIssueIdField)).map(IssueId::from);
+ Optional<User> owner = optionalString(root.field(ownerField)).map(User::from);
ApplicationMetrics metrics = new ApplicationMetrics(root.field(queryQualityField).asDouble(),
root.field(writeQualityField).asDouble());
Optional<RotationId> rotation = rotationFromSlime(root.field(rotationField));
Map<HostName, RotationStatus> rotationStatus = rotationStatusFromSlime(root.field(rotationStatusField));
return new Application(id, createdAt, deploymentSpec, validationOverrides, deployments, deploymentJobs, deploying,
- outstandingChange, ownershipIssueId, metrics, rotation, rotationStatus);
+ outstandingChange, ownershipIssueId, owner, metrics, rotation, rotationStatus);
}
private List<Deployment> deploymentsFromSlime(Inspector array) {
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 57f729ced85..26495178c9b 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
@@ -482,6 +482,7 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
application.activity().lastWritesPerSecond().ifPresent(value -> activity.setDouble("lastWritesPerSecond", value));
application.ownershipIssueId().ifPresent(issueId -> object.setString("ownershipIssueId", issueId.value()));
+ application.owner().ifPresent(owner -> object.setString("owner", owner.username()));
application.deploymentJobs().issueId().ifPresent(issueId -> object.setString("deploymentIssueId", issueId.value()));
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ApplicationOwnershipConfirmerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ApplicationOwnershipConfirmerTest.java
index 62653f29518..75c287e700f 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ApplicationOwnershipConfirmerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ApplicationOwnershipConfirmerTest.java
@@ -58,14 +58,12 @@ public class ApplicationOwnershipConfirmerTest {
Optional<IssueId> issueId = Optional.of(IssueId.from("1"));
issues.response = issueId;
confirmer.maintain();
- confirmer.maintain();
assertFalse("No issue is stored for an application newer than 3 months.", propertyApp.get().ownershipIssueId().isPresent());
assertFalse("No issue is stored for an application newer than 3 months.", userApp.get().ownershipIssueId().isPresent());
tester.clock().advance(Duration.ofDays(91));
confirmer.maintain();
- confirmer.maintain();
assertEquals("Confirmation issue has been filed for property owned application.", issueId, propertyApp.get().ownershipIssueId());
assertEquals("Confirmation issue has been filed for user owned application.", issueId, userApp.get().ownershipIssueId());
@@ -75,7 +73,6 @@ public class ApplicationOwnershipConfirmerTest {
// No new issue is created, so return empty now.
issues.response = Optional.empty();
confirmer.maintain();
- confirmer.maintain();
assertEquals("Confirmation issue reference is not updated when no issue id is returned.", issueId, propertyApp.get().ownershipIssueId());
assertEquals("Confirmation issue reference is not updated when no issue id is returned.", issueId, userApp.get().ownershipIssueId());
@@ -86,16 +83,20 @@ public class ApplicationOwnershipConfirmerTest {
tester.controller().applications().deactivate(userApp.get().id(), userApp.get().productionDeployments().keySet().stream().findAny().get());
assertTrue("No production deployments are listed for user.", userApp.get().productionDeployments().isEmpty());
confirmer.maintain();
- confirmer.maintain();
// Time has passed, and a new confirmation issue is in order for the property which is still in production.
Optional<IssueId> issueId2 = Optional.of(IssueId.from("2"));
issues.response = issueId2;
confirmer.maintain();
- confirmer.maintain();
assertEquals("A new confirmation issue id is stored when something is returned to the maintainer.", issueId2, propertyApp.get().ownershipIssueId());
assertEquals("Confirmation issue for application without production deployments has not been filed.", issueId, userApp.get().ownershipIssueId());
+
+ assertFalse("No owner is stored for application", propertyApp.get().owner().isPresent());
+ issues.owner = Optional.of(User.from("username"));
+ confirmer.maintain();
+ assertEquals("Owner has been added to application", propertyApp.get().owner().get().username(), "username");
+
}
private class MockOwnershipIssues implements OwnershipIssues {
@@ -103,6 +104,7 @@ public class ApplicationOwnershipConfirmerTest {
private Optional<IssueId> response;
private boolean escalatedToContact = false;
private boolean escalatedToTerminator = false;
+ private Optional<User> owner = Optional.empty();
@Override
public Optional<IssueId> confirmOwnership(Optional<IssueId> issueId, ApplicationId applicationId, User asignee, Contact contact) {
@@ -115,6 +117,10 @@ public class ApplicationOwnershipConfirmerTest {
else escalatedToTerminator = true;
}
+ @Override
+ public Optional<User> getConfirmedOwner(IssueId issueId) {
+ return owner;
+ }
}
}
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 a6a6635032d..42ce696af89 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
@@ -12,6 +12,7 @@ import com.yahoo.vespa.hosted.controller.Application;
import com.yahoo.vespa.hosted.controller.api.integration.MetricsService;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType;
import com.yahoo.vespa.hosted.controller.api.integration.organization.IssueId;
+import com.yahoo.vespa.hosted.controller.api.integration.organization.User;
import com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneId;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.ApplicationVersion;
import com.yahoo.vespa.hosted.controller.application.Change;
@@ -106,6 +107,7 @@ public class ApplicationSerializerTest {
Change.of(Version.fromString("6.7")),
Change.of(ApplicationVersion.from(new SourceRevision("repo", "master", "deadcafe"), 42)),
Optional.of(IssueId.from("1234")),
+ Optional.of(User.from("by-username")),
new MetricsService.ApplicationMetrics(0.5, 0.9),
Optional.of(new RotationId("my-rotation")),
rotationStatus);
@@ -138,6 +140,7 @@ public class ApplicationSerializerTest {
assertEquals(original.outstandingChange(), serialized.outstandingChange());
assertEquals(original.ownershipIssueId(), serialized.ownershipIssueId());
+ assertEquals(original.owner(), serialized.owner());
assertEquals(original.change(), serialized.change());
assertEquals(original.rotation().get(), serialized.rotation().get());
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
index 2856bbe214d..33ac089439c 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
@@ -27,6 +27,7 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId;
import com.yahoo.vespa.hosted.controller.api.identifiers.ScrewdriverId;
import com.yahoo.vespa.hosted.controller.api.identifiers.UserId;
import com.yahoo.vespa.hosted.controller.api.integration.MetricsService.ApplicationMetrics;
+import com.yahoo.vespa.hosted.controller.api.integration.organization.User;
import com.yahoo.vespa.hosted.controller.athenz.ApplicationAction;
import com.yahoo.vespa.hosted.controller.athenz.HostedAthenzIdentities;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServerException;
@@ -505,7 +506,8 @@ public class ApplicationApiTest extends ControllerContainerTest {
private void addIssues(ContainerControllerTester tester, ApplicationId id) {
tester.controller().applications().lockOrThrow(id, application ->
tester.controller().applications().store(application.withDeploymentIssueId(IssueId.from("123"))
- .withOwnershipIssueId(IssueId.from("321"))));
+ .withOwnershipIssueId(IssueId.from("321"))
+ .withOwner(User.from("owner-username"))));
}
@Test
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application1-recursive.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application1-recursive.json
index 70da148ef86..da6bf455857 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application1-recursive.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application1-recursive.json
@@ -231,5 +231,6 @@
"lastWritesPerSecond": 2.0
},
"ownershipIssueId": "321",
+ "owner": "owner-username",
"deploymentIssueId": "123"
}