summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Marius Venstad <jonmv@users.noreply.github.com>2023-08-28 15:52:07 +0200
committerGitHub <noreply@github.com>2023-08-28 15:52:07 +0200
commitbd5fa1d77691b408a52de516657dc7e7410be81d (patch)
tree37c40e5fb8971d26ab4e60de3fcd34f0885428eb
parentffbc28f7cad786f78236aef0248f3543dcf25f4e (diff)
parentd506e48f27d0907308238271ca75de9159911d8c (diff)
Merge pull request #28158 from vespa-engine/jonmv/account-id-owners
Use JIRA account owners instead of usernames
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/AccountId.java12
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/DeploymentIssues.java2
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/Issue.java33
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/IssueHandler.java8
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/IssueInfo.java11
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockIssueHandler.java21
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/OwnershipIssues.java5
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/DummyOwnershipIssues.java5
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/LoggingDeploymentIssues.java3
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Application.java19
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/LockedApplication.java50
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ApplicationOwnershipConfirmer.java12
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentIssueReporter.java5
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java12
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java4
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/DeploymentQuotaCalculatorTest.java2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ApplicationOwnershipConfirmerTest.java13
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java5
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java3
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance1-recursive.json2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/recursive-root.json2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant1-recursive.json2
22 files changed, 144 insertions, 87 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/AccountId.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/AccountId.java
new file mode 100644
index 00000000000..34438c2dd1e
--- /dev/null
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/AccountId.java
@@ -0,0 +1,12 @@
+package com.yahoo.vespa.hosted.controller.api.integration.organization;
+
+import ai.vespa.validation.StringWrapper;
+
+public class AccountId extends StringWrapper<AccountId> {
+
+ public AccountId(String value) {
+ super(value);
+ if (value.isBlank()) throw new IllegalArgumentException("id must be non-blank");
+ }
+
+}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/DeploymentIssues.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/DeploymentIssues.java
index 75866b68ab1..3989d4bbae6 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/DeploymentIssues.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/DeploymentIssues.java
@@ -15,7 +15,7 @@ import java.util.Optional;
*/
public interface DeploymentIssues {
- IssueId fileUnlessOpen(Optional<IssueId> issueId, ApplicationId applicationId, User asignee, Contact contact);
+ IssueId fileUnlessOpen(Optional<IssueId> issueId, ApplicationId applicationId, AccountId assigneeId, User assignee, Contact contact);
IssueId fileUnlessOpen(Collection<ApplicationId> applicationIds, Version version);
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/Issue.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/Issue.java
index 7db85da1dbb..57696e0649d 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/Issue.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/Issue.java
@@ -18,11 +18,13 @@ public class Issue {
private final String description;
private final List<String> labels;
private final User assignee;
+ private final AccountId assigneeId;
private final Type type;
private final String queue;
private final Optional<String> component;
- private Issue(String summary, String description, List<String> labels, User assignee, Type type, String queue, Optional<String> component) {
+ private Issue(String summary, String description, List<String> labels, User assignee,
+ AccountId assigneeId, Type type, String queue, Optional<String> component) {
if (summary.isEmpty()) throw new IllegalArgumentException("Issue summary can not be empty!");
if (description.isEmpty()) throw new IllegalArgumentException("Issue description can not be empty!");
@@ -30,45 +32,50 @@ public class Issue {
this.description = description;
this.labels = List.copyOf(labels);
this.assignee = assignee;
+ this.assigneeId = assigneeId;
this.type = type;
this.queue = queue;
this.component = component;
}
public Issue(String summary, String description, String queue, Optional<String> component) {
- this(summary, description, Collections.emptyList(), null, Type.defect, queue, component);
+ this(summary, description, Collections.emptyList(), null, null, Type.defect, queue, component);
}
public Issue append(String appendage) {
- return new Issue(summary, description + appendage, labels, assignee, type, queue, component);
+ return new Issue(summary, description + appendage, labels, assignee, assigneeId, type, queue, component);
}
public Issue with(String label) {
List<String> labels = new ArrayList<>(this.labels);
labels.add(label);
- return new Issue(summary, description, labels, assignee, type, queue, component);
+ return new Issue(summary, description, labels, assignee, assigneeId, type, queue, component);
}
public Issue with(List<String> labels) {
List<String> newLabels = new ArrayList<>(this.labels);
newLabels.addAll(labels);
- return new Issue(summary, description, newLabels, assignee, type, queue, component);
+ return new Issue(summary, description, newLabels, assignee, assigneeId, type, queue, component);
+ }
+
+ public Issue with(AccountId assigneeId) {
+ return new Issue(summary, description, labels, null, assigneeId, type, queue, component);
}
public Issue with(User assignee) {
- return new Issue(summary, description, labels, assignee, type, queue, component);
+ return new Issue(summary, description, labels, assignee, null, type, queue, component);
}
public Issue with(Type type) {
- return new Issue(summary, description, labels, assignee, type, queue, component);
+ return new Issue(summary, description, labels, assignee, assigneeId, type, queue, component);
}
public Issue in(String queue) {
- return new Issue(summary, description, labels, assignee, type, queue, Optional.empty());
+ return new Issue(summary, description, labels, assignee, assigneeId, type, queue, Optional.empty());
}
public Issue withoutComponent() {
- return new Issue(summary, description, labels, assignee, type, queue, Optional.empty());
+ return new Issue(summary, description, labels, assignee, assigneeId, type, queue, Optional.empty());
}
public String summary() {
@@ -83,8 +90,11 @@ public class Issue {
return labels;
}
- public Optional<User> assignee() {
- return Optional.ofNullable(assignee);
+ public Optional<User> assignee() { return Optional.ofNullable(assignee);
+ }
+
+ public Optional<AccountId> assigneeId() {
+ return Optional.ofNullable(assigneeId);
}
public Type type() {
@@ -98,6 +108,7 @@ public class Issue {
public Optional<String> component() {
return component;
}
+
public enum Type {
defect, // A defect which needs fixing.
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/IssueHandler.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/IssueHandler.java
index 8123b6f2ce6..9b9c3df8104 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/IssueHandler.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/IssueHandler.java
@@ -82,6 +82,14 @@ public interface IssueHandler {
Optional<User> assigneeOf(IssueId issueId);
/**
+ * Returns the account id assigned to the given issue, if any.
+ *
+ * @param issueId ID of the issue for which to find the assignee.
+ * @return The account id of the user responsible for fixing the given issue, if found.
+ */
+ Optional<AccountId> assigneeIdOf(IssueId issueId);
+
+ /**
* Reassign the issue with the given ID to the given user, and returns the outcome of this.
*
* @param issueId ID of the issue to be reassigned.
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/IssueInfo.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/IssueInfo.java
index 52c022bebdf..f71e6b6507d 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/IssueInfo.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/IssueInfo.java
@@ -16,13 +16,13 @@ public class IssueInfo {
private final IssueId id;
private final Instant updated;
private final Status status;
- private final User assignee;
+ private final AccountId assigneeId;
- public IssueInfo(IssueId id, Instant updated, Status status, User assignee) {
+ public IssueInfo(IssueId id, Instant updated, Status status, AccountId assigneeId) {
this.id = id;
this.updated = updated;
this.status = status;
- this.assignee = assignee;
+ this.assigneeId = assigneeId;
}
public IssueId id() {
@@ -37,11 +37,10 @@ public class IssueInfo {
return status;
}
- public Optional<User> assignee() {
- return Optional.ofNullable(assignee);
+ public Optional<AccountId> assigneeId() {
+ return Optional.ofNullable(assigneeId);
}
-
public enum Status {
toDo("To Do"),
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockIssueHandler.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockIssueHandler.java
index d60c4d196e2..fb4986d0061 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockIssueHandler.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockIssueHandler.java
@@ -42,7 +42,7 @@ public class MockIssueHandler implements IssueHandler {
@Override
public IssueId file(Issue issue) {
- if (!issue.assignee().isPresent()) throw new RuntimeException();
+ if (issue.assignee().isEmpty() && issue.assigneeId().isEmpty()) throw new RuntimeException();
IssueId issueId = IssueId.from("" + counter.incrementAndGet());
issues.put(issueId, new MockIssue(issue));
return issueId;
@@ -55,7 +55,7 @@ public class MockIssueHandler implements IssueHandler {
.map(entry -> new IssueInfo(entry.getKey(),
entry.getValue().updated,
entry.getValue().isOpen() ? Status.toDo : Status.done,
- entry.getValue().assignee))
+ entry.getValue().assigneeId))
.toList();
}
@@ -85,6 +85,11 @@ public class MockIssueHandler implements IssueHandler {
}
@Override
+ public Optional<AccountId> assigneeIdOf(IssueId issueId) {
+ return Optional.ofNullable(issues.get(issueId).assigneeId);
+ }
+
+ @Override
public boolean reassign(IssueId issueId, User assignee) {
issues.get(issueId).assignee = assignee;
touch(issueId);
@@ -159,21 +164,13 @@ public class MockIssueHandler implements IssueHandler {
projects.put(projectKey, projectInfo);
}
- private static class PropertyInfo {
-
- private List<List<User>> contacts = Collections.emptyList();
- private URI issueUrl = URI.create("issues.tld");
- private URI contactsUrl = URI.create("contacts.tld");
- private URI propertyUrl = URI.create("properties.tld");
-
- }
-
public class MockIssue {
private Issue issue;
private Instant updated;
private boolean open;
private User assignee;
+ private AccountId assigneeId;
private List<String> watchers;
private MockIssue(Issue issue) {
@@ -181,11 +178,13 @@ public class MockIssueHandler implements IssueHandler {
this.updated = clock.instant();
this.open = true;
this.assignee = issue.assignee().orElse(null);
+ this.assigneeId = issue.assigneeId().orElse(null);
this.watchers = new ArrayList<>();
}
public Issue issue() { return issue; }
public User assignee() { return assignee; }
+ public AccountId assigneeId() { return assigneeId; }
public boolean isOpen() { return open; }
public List<String> watchers() { return List.copyOf(watchers); }
public void addWatcher(String watcher) { watchers.add(watcher); }
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/OwnershipIssues.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/OwnershipIssues.java
index df128f18193..6822b4b432f 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/OwnershipIssues.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/OwnershipIssues.java
@@ -20,11 +20,12 @@ public interface OwnershipIssues {
*
* @param issueId ID of the previous ownership issue filed for the given application.
* @param summary Summary of an application for which to file an issue.
+ * @param assigneeId Issue assignee id
* @param assignee Issue assignee
* @param contact Contact info for the application tenant
* @return ID of the created issue, if one was created.
*/
- Optional<IssueId> confirmOwnership(Optional<IssueId> issueId, ApplicationSummary summary, User assignee, Contact contact);
+ Optional<IssueId> confirmOwnership(Optional<IssueId> issueId, ApplicationSummary summary, AccountId assigneeId, User assignee, Contact contact);
/**
* Make sure the given ownership confirmation request is acted upon, unless it is already acknowledged.
@@ -38,6 +39,6 @@ public interface OwnershipIssues {
* @param issueId ID of the ownership issue.
* @return The owner of the application, if it has been confirmed.
*/
- Optional<User> getConfirmedOwner(IssueId issueId);
+ Optional<AccountId> getConfirmedOwner(IssueId issueId);
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/DummyOwnershipIssues.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/DummyOwnershipIssues.java
index d3d5ba96781..caff9460628 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/DummyOwnershipIssues.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/DummyOwnershipIssues.java
@@ -1,6 +1,7 @@
// 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.stubs;
+import com.yahoo.vespa.hosted.controller.api.integration.organization.AccountId;
import com.yahoo.vespa.hosted.controller.api.integration.organization.ApplicationSummary;
import com.yahoo.vespa.hosted.controller.api.integration.organization.Contact;
import com.yahoo.vespa.hosted.controller.api.integration.organization.IssueId;
@@ -15,7 +16,7 @@ import java.util.Optional;
public class DummyOwnershipIssues implements OwnershipIssues {
@Override
- public Optional<IssueId> confirmOwnership(Optional<IssueId> issueId, ApplicationSummary summary, User assignee, Contact contact) {
+ public Optional<IssueId> confirmOwnership(Optional<IssueId> issueId, ApplicationSummary summary, AccountId assigneeId, User assignee, Contact contact) {
return Optional.empty();
}
@@ -24,7 +25,7 @@ public class DummyOwnershipIssues implements OwnershipIssues {
}
@Override
- public Optional<User> getConfirmedOwner(IssueId issueId) {
+ public Optional<AccountId> getConfirmedOwner(IssueId issueId) {
return Optional.empty();
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/LoggingDeploymentIssues.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/LoggingDeploymentIssues.java
index 20178f300d2..1de3418bd93 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/LoggingDeploymentIssues.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/LoggingDeploymentIssues.java
@@ -5,6 +5,7 @@ package com.yahoo.vespa.hosted.controller.api.integration.stubs;
import com.yahoo.component.annotation.Inject;
import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.vespa.hosted.controller.api.integration.organization.AccountId;
import com.yahoo.vespa.hosted.controller.api.integration.organization.Contact;
import com.yahoo.vespa.hosted.controller.api.integration.organization.DeploymentIssues;
import com.yahoo.vespa.hosted.controller.api.integration.organization.IssueId;
@@ -52,7 +53,7 @@ public class LoggingDeploymentIssues implements DeploymentIssues {
}
@Override
- public IssueId fileUnlessOpen(Optional<IssueId> issueId, ApplicationId applicationId, User assignee, Contact contact) {
+ public IssueId fileUnlessOpen(Optional<IssueId> issueId, ApplicationId applicationId, AccountId assigneeId, User assignee, Contact contact) {
return fileUnlessPresent(issueId, applicationId);
}
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 66e62ff7b95..f7eb7cdde0d 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
@@ -8,6 +8,7 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.RevisionId;
+import com.yahoo.vespa.hosted.controller.api.integration.organization.AccountId;
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.application.ApplicationActivity;
@@ -52,7 +53,8 @@ public class Application {
private final OptionalLong projectId;
private final Optional<IssueId> deploymentIssueId;
private final Optional<IssueId> ownershipIssueId;
- private final Optional<User> owner;
+ private final Optional<User> userOwner;
+ private final Optional<AccountId> issueOwner;
private final OptionalInt majorVersion;
private final ApplicationMetrics metrics;
private final Set<PublicKey> deployKeys;
@@ -60,14 +62,14 @@ public class Application {
/** Creates an empty application. */
public Application(TenantAndApplicationId id, Instant now) {
- this(id, now, DeploymentSpec.empty, ValidationOverrides.empty, Optional.empty(),
+ this(id, now, DeploymentSpec.empty, ValidationOverrides.empty, Optional.empty(), Optional.empty(),
Optional.empty(), Optional.empty(), OptionalInt.empty(), new ApplicationMetrics(0, 0),
Set.of(), OptionalLong.empty(), RevisionHistory.empty(), List.of());
}
// Do not use directly - edit through LockedApplication.
public Application(TenantAndApplicationId id, Instant createdAt, DeploymentSpec deploymentSpec, ValidationOverrides validationOverrides,
- Optional<IssueId> deploymentIssueId, Optional<IssueId> ownershipIssueId, Optional<User> owner,
+ Optional<IssueId> deploymentIssueId, Optional<IssueId> ownershipIssueId, Optional<User> userOwner, Optional<AccountId> issueOwner,
OptionalInt majorVersion, ApplicationMetrics metrics, Set<PublicKey> deployKeys, OptionalLong projectId,
RevisionHistory revisions, Collection<Instance> instances) {
this.id = Objects.requireNonNull(id, "id cannot be null");
@@ -76,7 +78,8 @@ public class Application {
this.validationOverrides = Objects.requireNonNull(validationOverrides, "validationOverrides cannot be null");
this.deploymentIssueId = Objects.requireNonNull(deploymentIssueId, "deploymentIssueId cannot be null");
this.ownershipIssueId = Objects.requireNonNull(ownershipIssueId, "ownershipIssueId cannot be null");
- this.owner = Objects.requireNonNull(owner, "owner cannot be null");
+ this.userOwner = Objects.requireNonNull(userOwner, "owner cannot be null");
+ this.issueOwner = Objects.requireNonNull(issueOwner, "issueOwner cannot be null");
this.majorVersion = Objects.requireNonNull(majorVersion, "majorVersion cannot be null");
this.metrics = Objects.requireNonNull(metrics, "metrics cannot be null");
this.deployKeys = Objects.requireNonNull(deployKeys, "deployKeys cannot be null");
@@ -143,8 +146,12 @@ public class Application {
return ownershipIssueId;
}
- public Optional<User> owner() {
- return owner;
+ public Optional<User> userOwner() {
+ return userOwner;
+ }
+
+ public Optional<AccountId> issueOwner() {
+ return issueOwner;
}
/**
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 b99c52d1533..066d10041c2 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
@@ -5,6 +5,7 @@ import com.yahoo.config.application.api.DeploymentSpec;
import com.yahoo.config.application.api.ValidationOverrides;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.transaction.Mutex;
+import com.yahoo.vespa.hosted.controller.api.integration.organization.AccountId;
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.application.TenantAndApplicationId;
@@ -37,7 +38,8 @@ public class LockedApplication {
private final ValidationOverrides validationOverrides;
private final Optional<IssueId> deploymentIssueId;
private final Optional<IssueId> ownershipIssueId;
- private final Optional<User> owner;
+ private final Optional<User> userOwner;
+ private final Optional<AccountId> issueOwner;
private final OptionalInt majorVersion;
private final ApplicationMetrics metrics;
private final Set<PublicKey> deployKeys;
@@ -53,15 +55,14 @@ public class LockedApplication {
*/
LockedApplication(Application application, Mutex lock) {
this(Objects.requireNonNull(lock, "lock cannot be null"), application.id(), application.createdAt(),
- application.deploymentSpec(), application.validationOverrides(),
- application.deploymentIssueId(), application.ownershipIssueId(),
- application.owner(), application.majorVersion(), application.metrics(), application.deployKeys(),
+ application.deploymentSpec(), application.validationOverrides(), application.deploymentIssueId(), application.ownershipIssueId(),
+ application.userOwner(), application.issueOwner(), application.majorVersion(), application.metrics(), application.deployKeys(),
application.projectId(), application.instances(), application.revisions());
}
private LockedApplication(Mutex lock, TenantAndApplicationId id, Instant createdAt, DeploymentSpec deploymentSpec,
- ValidationOverrides validationOverrides,
- Optional<IssueId> deploymentIssueId, Optional<IssueId> ownershipIssueId, Optional<User> owner,
+ ValidationOverrides validationOverrides, Optional<IssueId> deploymentIssueId,
+ Optional<IssueId> ownershipIssueId, Optional<User> userOwner, Optional<AccountId> issueOwner,
OptionalInt majorVersion, ApplicationMetrics metrics, Set<PublicKey> deployKeys,
OptionalLong projectId, Map<InstanceName, Instance> instances, RevisionHistory revisions) {
this.lock = lock;
@@ -71,7 +72,8 @@ public class LockedApplication {
this.validationOverrides = validationOverrides;
this.deploymentIssueId = deploymentIssueId;
this.ownershipIssueId = ownershipIssueId;
- this.owner = owner;
+ this.userOwner = userOwner;
+ this.issueOwner = issueOwner;
this.majorVersion = majorVersion;
this.metrics = metrics;
this.deployKeys = deployKeys;
@@ -83,7 +85,7 @@ public class LockedApplication {
/** Returns a read-only copy of this */
public Application get() {
return new Application(id, createdAt, deploymentSpec, validationOverrides,
- deploymentIssueId, ownershipIssueId, owner, majorVersion, metrics, deployKeys,
+ deploymentIssueId, ownershipIssueId, userOwner, issueOwner, majorVersion, metrics, deployKeys,
projectId, revisions, instances.values());
}
@@ -91,7 +93,7 @@ public class LockedApplication {
var instances = new HashMap<>(this.instances);
instances.put(instance, new Instance(id.instance(instance)));
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides,
- deploymentIssueId, ownershipIssueId, owner, majorVersion, metrics, deployKeys,
+ deploymentIssueId, ownershipIssueId, userOwner, issueOwner, majorVersion, metrics, deployKeys,
projectId, instances, revisions);
}
@@ -99,7 +101,7 @@ public class LockedApplication {
var instances = new HashMap<>(this.instances);
instances.put(instance, modification.apply(instances.get(instance)));
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides,
- deploymentIssueId, ownershipIssueId, owner, majorVersion, metrics, deployKeys,
+ deploymentIssueId, ownershipIssueId, userOwner, issueOwner, majorVersion, metrics, deployKeys,
projectId, instances, revisions);
}
@@ -107,57 +109,57 @@ public class LockedApplication {
var instances = new HashMap<>(this.instances);
instances.remove(instance);
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides,
- deploymentIssueId, ownershipIssueId, owner, majorVersion, metrics, deployKeys,
+ deploymentIssueId, ownershipIssueId, userOwner, issueOwner, majorVersion, metrics, deployKeys,
projectId, instances, revisions);
}
public LockedApplication withProjectId(OptionalLong projectId) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides,
- deploymentIssueId, ownershipIssueId, owner, majorVersion, metrics, deployKeys,
+ deploymentIssueId, ownershipIssueId, userOwner, issueOwner, majorVersion, metrics, deployKeys,
projectId, instances, revisions);
}
public LockedApplication withDeploymentIssueId(IssueId issueId) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides,
- Optional.ofNullable(issueId), ownershipIssueId, owner, majorVersion, metrics, deployKeys,
+ Optional.ofNullable(issueId), ownershipIssueId, userOwner, issueOwner, majorVersion, metrics, deployKeys,
projectId, instances, revisions);
}
public LockedApplication with(DeploymentSpec deploymentSpec) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides,
- deploymentIssueId, ownershipIssueId, owner, majorVersion, metrics, deployKeys,
+ deploymentIssueId, ownershipIssueId, userOwner, issueOwner, majorVersion, metrics, deployKeys,
projectId, instances, revisions);
}
public LockedApplication with(ValidationOverrides validationOverrides) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides,
- deploymentIssueId, ownershipIssueId, owner, majorVersion, metrics, deployKeys,
+ deploymentIssueId, ownershipIssueId, userOwner, issueOwner, majorVersion, metrics, deployKeys,
projectId, instances, revisions);
}
public LockedApplication withOwnershipIssueId(IssueId issueId) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides,
- deploymentIssueId, Optional.of(issueId), owner, majorVersion, metrics, deployKeys,
+ deploymentIssueId, Optional.of(issueId), userOwner, issueOwner, majorVersion, metrics, deployKeys,
projectId, instances, revisions);
}
- public LockedApplication withOwner(User owner) {
+ public LockedApplication withOwner(AccountId issueOwner) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides,
- deploymentIssueId, ownershipIssueId, Optional.of(owner), majorVersion, metrics, deployKeys,
+ deploymentIssueId, ownershipIssueId, userOwner, Optional.of(issueOwner), majorVersion, metrics, deployKeys,
projectId, instances, revisions);
}
/** Set a major version for this, or set to null to remove any major version override */
public LockedApplication withMajorVersion(Integer majorVersion) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides,
- deploymentIssueId, ownershipIssueId, owner,
- majorVersion == null ? OptionalInt.empty() : OptionalInt.of(majorVersion),
+ deploymentIssueId, ownershipIssueId, userOwner,
+ issueOwner, majorVersion == null ? OptionalInt.empty() : OptionalInt.of(majorVersion),
metrics, deployKeys, projectId, instances, revisions);
}
public LockedApplication with(ApplicationMetrics metrics) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides,
- deploymentIssueId, ownershipIssueId, owner, majorVersion, metrics, deployKeys,
+ deploymentIssueId, ownershipIssueId, userOwner, issueOwner, majorVersion, metrics, deployKeys,
projectId, instances, revisions);
}
@@ -165,7 +167,7 @@ public class LockedApplication {
Set<PublicKey> keys = new LinkedHashSet<>(deployKeys);
keys.add(pemDeployKey);
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides,
- deploymentIssueId, ownershipIssueId, owner, majorVersion, metrics, keys,
+ deploymentIssueId, ownershipIssueId, userOwner, issueOwner, majorVersion, metrics, keys,
projectId, instances, revisions);
}
@@ -173,13 +175,13 @@ public class LockedApplication {
Set<PublicKey> keys = new LinkedHashSet<>(deployKeys);
keys.remove(pemDeployKey);
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides,
- deploymentIssueId, ownershipIssueId, owner, majorVersion, metrics, keys,
+ deploymentIssueId, ownershipIssueId, userOwner, issueOwner, majorVersion, metrics, keys,
projectId, instances, revisions);
}
public LockedApplication withRevisions(UnaryOperator<RevisionHistory> change) {
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides,
- deploymentIssueId, ownershipIssueId, owner, majorVersion, metrics,
+ deploymentIssueId, ownershipIssueId, userOwner, issueOwner, majorVersion, metrics,
deployKeys, projectId, instances, change.apply(revisions));
}
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 cbdfcf70123..1a944cfd5d7 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
@@ -6,6 +6,7 @@ import com.yahoo.vespa.hosted.controller.ApplicationController;
import com.yahoo.vespa.hosted.controller.Controller;
import com.yahoo.vespa.hosted.controller.Instance;
import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId;
+import com.yahoo.vespa.hosted.controller.api.integration.organization.AccountId;
import com.yahoo.vespa.hosted.controller.api.integration.organization.ApplicationSummary;
import com.yahoo.vespa.hosted.controller.api.integration.organization.IssueId;
import com.yahoo.vespa.hosted.controller.api.integration.organization.OwnershipIssues;
@@ -70,7 +71,8 @@ public class ApplicationOwnershipConfirmer extends ControllerMaintainer {
tenantOf(application.id()).contact().flatMap(contact -> {
return ownershipIssues.confirmOwnership(application.ownershipIssueId(),
summaryOf(application.id()),
- determineAssignee(application),
+ application.issueOwner().orElse(null),
+ application.userOwner().orElse(null),
contact);
}).ifPresent(newIssueId -> store(newIssueId, application.id()));
}
@@ -156,8 +158,12 @@ public class ApplicationOwnershipConfirmer extends ControllerMaintainer {
return ApplicationList.from(controller().applications().readable());
}
- private User determineAssignee(Application application) {
- return application.owner().orElse(null);
+ private AccountId determineAssignee(Application application) {
+ return application.issueOwner().orElse(null);
+ }
+
+ private User determineLegacyAssignee(Application application) {
+ return application.userOwner().orElse(null);
}
private Tenant tenantOf(TenantAndApplicationId applicationId) {
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentIssueReporter.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentIssueReporter.java
index c352fb053dc..cd0f4be7a48 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentIssueReporter.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentIssueReporter.java
@@ -117,9 +117,10 @@ public class DeploymentIssueReporter extends ControllerMaintainer {
try {
Tenant tenant = ownerOf(application.id());
tenant.contact().ifPresent(contact -> {
- User assignee = application.owner().orElse(null);
Optional<IssueId> ourIssueId = application.deploymentIssueId();
- IssueId issueId = deploymentIssues.fileUnlessOpen(ourIssueId, application.id().defaultInstance(), assignee, contact);
+ IssueId issueId = deploymentIssues.fileUnlessOpen(ourIssueId, application.id().defaultInstance(),
+ application.issueOwner().orElse(null), application.userOwner().orElse(null),
+ contact);
store(application.id(), issueId);
});
}
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 41b40f447d8..e6b3dd74abc 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
@@ -24,6 +24,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobId;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.RevisionId;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.SourceRevision;
+import com.yahoo.vespa.hosted.controller.api.integration.organization.AccountId;
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.application.AssignedRotation;
@@ -86,7 +87,8 @@ public class ApplicationSerializer {
private static final String revisionPinnedField = "revisionPinned";
private static final String deploymentIssueField = "deploymentIssueId";
private static final String ownershipIssueIdField = "ownershipIssueId";
- private static final String ownerField = "confirmedOwner";
+ private static final String userOwnerField = "confirmedOwner";
+ private static final String issueOwnerField = "confirmedOwnerId";
private static final String majorVersionField = "majorVersion";
private static final String writeQualityField = "writeQuality";
private static final String queryQualityField = "queryQuality";
@@ -174,7 +176,8 @@ public class ApplicationSerializer {
application.projectId().ifPresent(projectId -> root.setLong(projectIdField, projectId));
application.deploymentIssueId().ifPresent(jiraIssueId -> root.setString(deploymentIssueField, jiraIssueId.value()));
application.ownershipIssueId().ifPresent(issueId -> root.setString(ownershipIssueIdField, issueId.value()));
- application.owner().ifPresent(owner -> root.setString(ownerField, owner.username()));
+ application.userOwner().ifPresent(owner -> root.setString(userOwnerField, owner.username()));
+ application.issueOwner().ifPresent(owner -> root.setString(issueOwnerField, owner.value()));
application.majorVersion().ifPresent(majorVersion -> root.setLong(majorVersionField, majorVersion));
root.setDouble(queryQualityField, application.metrics().queryServiceQuality());
root.setDouble(writeQualityField, application.metrics().writeServiceQuality());
@@ -349,7 +352,8 @@ public class ApplicationSerializer {
ValidationOverrides validationOverrides = ValidationOverrides.fromXml(root.field(validationOverridesField).asString());
Optional<IssueId> deploymentIssueId = SlimeUtils.optionalString(root.field(deploymentIssueField)).map(IssueId::from);
Optional<IssueId> ownershipIssueId = SlimeUtils.optionalString(root.field(ownershipIssueIdField)).map(IssueId::from);
- Optional<User> owner = SlimeUtils.optionalString(root.field(ownerField)).map(User::from);
+ Optional<User> userOwner = SlimeUtils.optionalString(root.field(userOwnerField)).map(User::from);
+ Optional<AccountId> issueOwner = SlimeUtils.optionalString(root.field(issueOwnerField)).map(AccountId::new);
OptionalInt majorVersion = SlimeUtils.optionalInteger(root.field(majorVersionField));
ApplicationMetrics metrics = new ApplicationMetrics(root.field(queryQualityField).asDouble(),
root.field(writeQualityField).asDouble());
@@ -359,7 +363,7 @@ public class ApplicationSerializer {
RevisionHistory revisions = revisionsFromSlime(root.field(prodVersionsField), root.field(devVersionsField), id);
return new Application(id, createdAt, deploymentSpec, validationOverrides,
- deploymentIssueId, ownershipIssueId, owner, majorVersion, metrics,
+ deploymentIssueId, ownershipIssueId, userOwner, issueOwner, majorVersion, metrics,
deployKeys, projectId, revisions, instances);
}
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 94c7829a851..9394a1fcbe2 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
@@ -1739,7 +1739,7 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler {
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.issueOwner().ifPresent(owner -> object.setString("owner", owner.value()));
application.deploymentIssueId().ifPresent(issueId -> object.setString("deploymentIssueId", issueId.value()));
}
@@ -1931,7 +1931,7 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler {
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.issueOwner().ifPresent(owner -> object.setString("owner", owner.value()));
application.deploymentIssueId().ifPresent(issueId -> object.setString("deploymentIssueId", issueId.value()));
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/DeploymentQuotaCalculatorTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/DeploymentQuotaCalculatorTest.java
index cb9c1c2fa13..f2897c14ffe 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/DeploymentQuotaCalculatorTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/DeploymentQuotaCalculatorTest.java
@@ -63,7 +63,7 @@ public class DeploymentQuotaCalculatorTest {
void quota_is_divided_among_prod_and_manual_instances() {
var existing_dev_deployment = new Application(TenantAndApplicationId.from(ApplicationId.defaultId()), Instant.EPOCH, DeploymentSpec.empty, ValidationOverrides.empty, Optional.empty(),
- Optional.empty(), Optional.empty(), OptionalInt.empty(), new ApplicationMetrics(1, 1), Set.of(), OptionalLong.empty(), RevisionHistory.empty(),
+ Optional.empty(), Optional.empty(), Optional.empty(), OptionalInt.empty(), new ApplicationMetrics(1, 1), Set.of(), OptionalLong.empty(), RevisionHistory.empty(),
List.of(new Instance(ApplicationId.defaultId()).withNewDeployment(ZoneId.from(Environment.dev, RegionName.defaultName()),
RevisionId.forProduction(1), Version.emptyVersion, Instant.EPOCH, Map.of(), QuotaUsage.create(0.53d), CloudAccount.empty)));
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 b643d3e90d2..142210843ff 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
@@ -3,6 +3,7 @@ package com.yahoo.vespa.hosted.controller.maintenance;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.vespa.hosted.controller.LockedTenant;
+import com.yahoo.vespa.hosted.controller.api.integration.organization.AccountId;
import com.yahoo.vespa.hosted.controller.api.integration.organization.ApplicationSummary;
import com.yahoo.vespa.hosted.controller.api.integration.organization.Contact;
import com.yahoo.vespa.hosted.controller.api.integration.organization.IssueId;
@@ -80,10 +81,10 @@ public class ApplicationOwnershipConfirmerTest {
assertEquals(issueId2, app.application().ownershipIssueId(), "A new confirmation issue id is stored when something is returned to the maintainer.");
- assertFalse(app.application().owner().isPresent(), "No owner is stored for application");
- issues.owner = Optional.of(User.from("username"));
+ assertFalse(app.application().issueOwner().isPresent(), "No owner is stored for application");
+ issues.owner = Optional.of(new AccountId("username"));
confirmer.maintain();
- assertEquals(app.application().owner().get().username(), "username", "Owner has been added to application");
+ assertEquals(app.application().issueOwner().get().value(), "username", "Owner has been added to application");
// The app deletes all production deployments — see that the issue is forgotten.
assertEquals(issueId2, app.application().ownershipIssueId(), "Confirmation issue for application is still open.");
@@ -103,10 +104,10 @@ public class ApplicationOwnershipConfirmerTest {
private Optional<IssueId> response;
private boolean escalated = false;
- private Optional<User> owner = Optional.empty();
+ private Optional<AccountId> owner = Optional.empty();
@Override
- public Optional<IssueId> confirmOwnership(Optional<IssueId> issueId, ApplicationSummary summary, User assignee, Contact contact) {
+ public Optional<IssueId> confirmOwnership(Optional<IssueId> issueId, ApplicationSummary summary, AccountId assigneeId, User assignee, Contact contact) {
return response;
}
@@ -116,7 +117,7 @@ public class ApplicationOwnershipConfirmerTest {
}
@Override
- public Optional<User> getConfirmedOwner(IssueId issueId) {
+ public Optional<AccountId> 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 7e10d481f0f..13f7ec2a4ec 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
@@ -17,6 +17,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.deployment.ApplicationV
import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobId;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.RevisionId;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.SourceRevision;
+import com.yahoo.vespa.hosted.controller.api.integration.organization.AccountId;
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.application.AssignedRotation;
@@ -159,6 +160,7 @@ public class ApplicationSerializerTest {
Optional.of(IssueId.from("4321")),
Optional.of(IssueId.from("1234")),
Optional.of(User.from("by-username")),
+ Optional.of(new AccountId("foo8ar")),
OptionalInt.of(7),
new ApplicationMetrics(0.5, 0.9),
Set.of(publicKey, otherPublicKey),
@@ -211,7 +213,8 @@ public class ApplicationSerializerTest {
serialized.require(id1.instance()).jobPause(DeploymentContext.stagingTest));
assertEquals(original.ownershipIssueId(), serialized.ownershipIssueId());
- assertEquals(original.owner(), serialized.owner());
+ assertEquals(original.userOwner(), serialized.userOwner());
+ assertEquals(original.issueOwner(), serialized.issueOwner());
assertEquals(original.majorVersion(), serialized.majorVersion());
assertEquals(original.deployKeys(), serialized.deployKeys());
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 8e73c26a2b2..345f164f8da 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
@@ -44,6 +44,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServ
import com.yahoo.vespa.hosted.controller.api.integration.configserver.Node;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.ApplicationVersion;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.RunId;
+import com.yahoo.vespa.hosted.controller.api.integration.organization.AccountId;
import com.yahoo.vespa.hosted.controller.api.integration.organization.Contact;
import com.yahoo.vespa.hosted.controller.api.integration.organization.IssueId;
import com.yahoo.vespa.hosted.controller.api.integration.organization.User;
@@ -1032,7 +1033,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
tester.applications().lockApplicationOrThrow(id, application ->
tester.controller().applications().store(application.withDeploymentIssueId(IssueId.from("123"))
.withOwnershipIssueId(IssueId.from("321"))
- .withOwner(User.from("owner-username"))));
+ .withOwner(new AccountId("owner-account-id"))));
}
@Test
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance1-recursive.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance1-recursive.json
index 32b091a92ca..e5ee9157792 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance1-recursive.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance1-recursive.json
@@ -182,6 +182,6 @@
"lastWritesPerSecond": 2.0
},
"ownershipIssueId": "321",
- "owner": "owner-username",
+ "owner": "owner-account-id",
"deploymentIssueId": "123"
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/recursive-root.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/recursive-root.json
index 6dc58cc2800..f1aba622fcf 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/recursive-root.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/recursive-root.json
@@ -189,7 +189,7 @@
"lastWritesPerSecond": 2.0
},
"ownershipIssueId": "321",
- "owner": "owner-username",
+ "owner": "owner-account-id",
"deploymentIssueId": "123"
}
],
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant1-recursive.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant1-recursive.json
index 210a637ece8..e252e042e43 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant1-recursive.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant1-recursive.json
@@ -188,7 +188,7 @@
"lastWritesPerSecond": 2.0
},
"ownershipIssueId": "321",
- "owner": "owner-username",
+ "owner": "owner-account-id",
"deploymentIssueId": "123"
}
],