diff options
Diffstat (limited to 'controller-server')
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" } |