diff options
author | olaaun <olaa@oath.com> | 2018-11-09 10:43:04 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-09 10:43:04 +0100 |
commit | a9d8f3fcbb5e348ef1e91aefd7bd5caf4356e533 (patch) | |
tree | af0a79403c1cd744a5b11183d93b6cb33c062317 /controller-api | |
parent | 6253162369e45210be6bdef22cd5a004420304d9 (diff) |
Split Organization to two classes. Add contact info for all tenants. Add queue and component in contact info (#7533)
Diffstat (limited to 'controller-api')
10 files changed, 213 insertions, 155 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/Contact.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/Contact.java new file mode 100644 index 00000000000..9ca83673b8a --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/Contact.java @@ -0,0 +1,92 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.controller.api.integration.organization; + +import com.google.common.collect.ImmutableList; + +import java.net.URI; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +/** + * Contact information for a tenant. + * + * @author mpolden + */ +public class Contact { + + private final URI url; + private final URI propertyUrl; + private final URI issueTrackerUrl; + private final List<List<String>> persons; + private final String queue; + private final Optional<String> component; + + public Contact(URI url, URI propertyUrl, URI issueTrackerUrl, List<List<String>> persons, String queue, Optional<String> component) { + this.propertyUrl = Objects.requireNonNull(propertyUrl, "propertyUrl must be non-null"); + this.url = Objects.requireNonNull(url, "url must be non-null"); + this.issueTrackerUrl = Objects.requireNonNull(issueTrackerUrl, "issueTrackerUrl must be non-null"); + this.persons = ImmutableList.copyOf(Objects.requireNonNull(persons, "persons must be non-null")); + this.queue = queue; + this.component = component; + } + + /** URL to this */ + public URI url() { + return url; + } + + /** URL to information about this property */ + public URI propertyUrl() { + return propertyUrl; + } + + /** URL to this contacts's issue tracker */ + public URI issueTrackerUrl() { + return issueTrackerUrl; + } + + /** Nested list of persons representing this. First level represents that person's rank in the corporate dystopia. */ + public List<List<String>> persons() { + return persons; + } + + public String queue() { + return queue; + } + + public Optional<String> component() { + return component; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Contact contact = (Contact) o; + return Objects.equals(url, contact.url) && + Objects.equals(propertyUrl, contact.propertyUrl) && + Objects.equals(issueTrackerUrl, contact.issueTrackerUrl) && + Objects.equals(persons, contact.persons) && + Objects.equals(queue, contact.queue) && + Objects.equals(component, contact.component); + } + + @Override + public int hashCode() { + return Objects.hash(url, propertyUrl, issueTrackerUrl, persons); + } + + @Override + public String toString() { + return "Contact{" + + "url=" + url + + ", propertyUrl=" + propertyUrl + + ", issueTrackerUrl=" + issueTrackerUrl + + ", persons=" + persons + + ", queue=" + queue + + (component.isPresent() ? ", component=" + component.get() : "") + + '}'; + } + +} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/ContactRetriever.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/ContactRetriever.java new file mode 100644 index 00000000000..9b05234d529 --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/ContactRetriever.java @@ -0,0 +1,12 @@ +package com.yahoo.vespa.hosted.controller.api.integration.organization; + +import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId; + +import java.util.Optional; + +/** + * @author olaa + */ +public interface ContactRetriever { + Contact getContact(Optional<PropertyId> propertyId); +} 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 6888e8ac06d..bafedb543f6 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 @@ -3,7 +3,6 @@ package com.yahoo.vespa.hosted.controller.api.integration.organization; import com.yahoo.component.Version; import com.yahoo.config.provision.ApplicationId; -import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId; import java.time.Duration; import java.util.Collection; @@ -16,12 +15,10 @@ import java.util.Optional; */ public interface DeploymentIssues { - IssueId fileUnlessOpen(Optional<IssueId> issueId, ApplicationId applicationId, PropertyId propertyId); - - IssueId fileUnlessOpen(Optional<IssueId> issueId, ApplicationId applicationId, User assignee); + IssueId fileUnlessOpen(Optional<IssueId> issueId, ApplicationId applicationId, User asignee, Contact contact); IssueId fileUnlessOpen(Collection<ApplicationId> applicationIds, Version version); - void escalateIfInactive(IssueId issueId, Optional<PropertyId> propertyId, Duration maxInactivity); + void escalateIfInactive(IssueId issueId, Duration maxInactivity, Optional<Contact> contact); } 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 a9bc7868f7a..7f42767d931 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 @@ -22,52 +22,49 @@ public class Issue { private final String description; private final List<String> labels; private final User assignee; - private final PropertyId propertyId; private final Type type; + private final String queue; + private final Optional<String> component; - private Issue(String summary, String description, List<String> labels, User assignee, PropertyId propertyId, Type type) { + private Issue(String summary, String description, List<String> labels, User assignee, 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!"); - Objects.requireNonNull(propertyId, "An issue must belong to a property!"); this.summary = summary; this.description = description; this.labels = ImmutableList.copyOf(labels); this.assignee = assignee; - this.propertyId = propertyId; this.type = type; + this.queue = queue; + this.component = component; } - public Issue(String summary, String description, PropertyId propertyId) { - this(summary, description, Collections.emptyList(), null, propertyId, Type.defect); + public Issue(String summary, String description, String queue, Optional<String> component) { + this(summary, description, Collections.emptyList(), null, Type.defect, queue, component); } public Issue append(String appendage) { - return new Issue(summary, description + appendage, labels, assignee, propertyId, type); + return new Issue(summary, description + appendage, labels, assignee, 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, propertyId, type); + return new Issue(summary, description, labels, assignee, 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, propertyId, type); + return new Issue(summary, description, newLabels, assignee, type, queue, component); } public Issue with(User assignee) { - return new Issue(summary, description, labels, assignee, propertyId, type); - } - - public Issue with(PropertyId propertyId) { - return new Issue(summary, description, labels, assignee, propertyId, type); + return new Issue(summary, description, labels, assignee, type, queue, component); } public Issue with(Type type) { - return new Issue(summary, description, labels, assignee, propertyId, type); + return new Issue(summary, description, labels, assignee, type, queue, component); } public String summary() { @@ -86,15 +83,17 @@ public class Issue { return Optional.ofNullable(assignee); } - public PropertyId propertyId() { - return propertyId; - } - public Type type() { return type; } + public String queue() { + return queue; + } + 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/Organization.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/IssueHandler.java index 6dccaec3b7a..db4f0eb5c59 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/Organization.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/IssueHandler.java @@ -1,20 +1,14 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.controller.api.integration.organization; -import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId; -import java.net.URI; import java.time.Duration; -import java.util.List; import java.util.Optional; /** - * Represents the humans who use this software, and their organization. - * Lets the software report issues to its caretakers, and provides other useful human resource lookups. - * * @author jonmv */ -public interface Organization { +public interface IssueHandler { /** * File an issue with its given property or the default, and with the specific assignee, if present. @@ -85,40 +79,8 @@ public interface Organization { * Escalate an issue filed with the given property. * * @param issueId ID of the issue to escalate. - * @param propertyId PropertyId of the tenant owning the application for which the issue was filed. * @return User that was assigned issue as a result of the escalation, if any */ - default Optional<User> escalate(IssueId issueId, PropertyId propertyId) { - List<? extends List<? extends User>> contacts = contactsFor(propertyId); - - Optional<User> assignee = assigneeOf(issueId); - int assigneeLevel = -1; - if (assignee.isPresent()) - for (int level = contacts.size(); --level > assigneeLevel; ) - if (contacts.get(level).contains(assignee.get())) - assigneeLevel = level; - - for (int level = assigneeLevel + 1; level < contacts.size(); level++) - for (User target : contacts.get(level)) - if (reassign(issueId, target)) - return Optional.of(target); - - return Optional.empty(); - } - - /** - * Returns a nested list where the entries have increasing rank, and where each entry is - * a list of the users of that rank, by decreasing relevance. - * - * @param propertyId ID of the property for which to list contacts. - * @return A sorted, nested, reverse sorted list of contacts. - */ - List<? extends List<? extends User>> contactsFor(PropertyId propertyId); - - URI issueCreationUri(PropertyId propertyId); - - URI contactsUri(PropertyId propertyId); - - URI propertyUri(PropertyId propertyId); + Optional<User> escalate(IssueId issueId, Contact contact); } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockContactRetriever.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockContactRetriever.java new file mode 100644 index 00000000000..55bad0b77ac --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockContactRetriever.java @@ -0,0 +1,36 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.controller.api.integration.organization; + +import com.yahoo.component.AbstractComponent; +import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId; + +import java.net.URI; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +/** + * @author olaa + */ +public class MockContactRetriever extends AbstractComponent implements ContactRetriever{ + + private final Map<PropertyId, Contact> contacts = new HashMap<>(); + + + + @Override + public Contact getContact(Optional<PropertyId> propertyId) { + return contacts.getOrDefault(propertyId.get(), contact()); + } + + public void addContact(PropertyId propertyId, Contact contact) { + contacts.put(propertyId, contact); + } + + + public Contact contact() { + return new Contact(URI.create("contacts.tld"), URI.create("properties.tld"), URI.create("issues.tld"), Collections.emptyList(), "queue", Optional.of("component")); + } + +} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockOrganization.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockIssueHandler.java index 82d3be596bc..674523ba26b 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockOrganization.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockIssueHandler.java @@ -2,7 +2,6 @@ package com.yahoo.vespa.hosted.controller.api.integration.organization; import com.google.inject.Inject; -import com.yahoo.component.AbstractComponent; import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId; import java.net.URI; @@ -13,34 +12,32 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.NoSuchElementException; import java.util.Optional; import java.util.concurrent.atomic.AtomicLong; +import java.util.stream.Collectors; /** * @author jvenstad */ -public class MockOrganization extends AbstractComponent implements Organization { +public class MockIssueHandler implements IssueHandler { private final Clock clock; private final AtomicLong counter = new AtomicLong(); private final Map<IssueId, MockIssue> issues = new HashMap<>(); - private final Map<PropertyId, PropertyInfo> properties = new HashMap<>(); @Inject @SuppressWarnings("unused") - public MockOrganization() { + public MockIssueHandler() { this(Clock.systemUTC()); } - public MockOrganization(Clock clock) { + public MockIssueHandler(Clock clock) { this.clock = clock; } @Override public IssueId file(Issue issue) { - if ( ! properties.containsKey(issue.propertyId())) - throw new NoSuchElementException("Unknown property '" + issue.propertyId() + "'!"); + if (!issue.assignee().isPresent()) throw new RuntimeException(); IssueId issueId = IssueId.from("" + counter.incrementAndGet()); issues.put(issueId, new MockIssue(issue)); return issueId; @@ -49,9 +46,9 @@ public class MockOrganization extends AbstractComponent implements Organization @Override public Optional<IssueId> findBySimilarity(Issue issue) { return issues.entrySet().stream() - .filter(entry -> entry.getValue().issue.summary().equals(issue.summary())) - .findFirst() - .map(Map.Entry::getKey); + .filter(entry -> entry.getValue().issue.summary().equals(issue.summary())) + .findFirst() + .map(Map.Entry::getKey); } @Override @@ -87,62 +84,55 @@ public class MockOrganization extends AbstractComponent implements Organization } @Override - public List<? extends List<? extends User>> contactsFor(PropertyId propertyId) { - return properties.getOrDefault(propertyId, new PropertyInfo()).contacts; - } - - @Override - public URI issueCreationUri(PropertyId propertyId) { - return properties.getOrDefault(propertyId, new PropertyInfo()).issueUrl; - } - - @Override - public URI contactsUri(PropertyId propertyId) { - return properties.getOrDefault(propertyId, new PropertyInfo()).contactsUrl; - } + public Optional<User> escalate(IssueId issueId, Contact contact) { + List<List<User>> contacts = getContactUsers(contact); + Optional<User> assignee = assigneeOf(issueId); + int assigneeLevel = -1; + if (assignee.isPresent()) + for (int level = contacts.size(); --level > assigneeLevel; ) + if (contacts.get(level).contains(assignee.get())) + assigneeLevel = level; - @Override - public URI propertyUri(PropertyId propertyId) { - return properties.getOrDefault(propertyId, new PropertyInfo()).propertyUrl; - } + for (int level = assigneeLevel + 1; level < contacts.size(); level++) + for (User target : contacts.get(level)) + if (reassign(issueId, target)) + return Optional.of(target); - public Map<IssueId, MockIssue> issues() { - return Collections.unmodifiableMap(issues); + return Optional.empty(); } - public MockOrganization close(IssueId issueId) { + public MockIssueHandler close(IssueId issueId) { issues.get(issueId).open = false; touch(issueId); return this; } - public MockOrganization setContactsFor(PropertyId propertyId, List<List<User>> contacts) { - properties.get(propertyId).contacts = contacts; - return this; + public Map<IssueId, MockIssue> issues() { + return issues; } - public MockOrganization setPropertyUrl(PropertyId propertyId, URI url) { - properties.get(propertyId).propertyUrl = url; - return this; + private List<List<User>> getContactUsers(Contact contact) { + return contact.persons().stream() + .map(userList -> + userList.stream().map(user -> + user.split(" ")[0]) + .map(User::from) + .collect(Collectors.toList()) + ).collect(Collectors.toList()); } - public MockOrganization setContactsUrl(PropertyId propertyId, URI url) { - properties.get(propertyId).contactsUrl = url; - return this; - } - public MockOrganization setIssueUrl(PropertyId propertyId, URI url) { - properties.get(propertyId).issueUrl = url; - return this; + private void touch(IssueId issueId) { + issues.get(issueId).updated = clock.instant(); } - public MockOrganization addProperty(PropertyId propertyId) { - properties.put(propertyId, new PropertyInfo()); - return this; - } + private 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"); - private void touch(IssueId issueId) { - issues.get(issueId).updated = clock.instant(); } public class MockIssue { @@ -165,14 +155,4 @@ public class MockOrganization extends AbstractComponent implements Organization } - private 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"); - - } - } - 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 ee17859c0fb..6a69eb54d2c 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 @@ -2,7 +2,6 @@ package com.yahoo.vespa.hosted.controller.api.integration.organization; import com.yahoo.config.provision.ApplicationId; -import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId; import java.util.Optional; @@ -19,31 +18,21 @@ import java.util.Optional; public interface OwnershipIssues { /** - * Ensure ownership of the given application has been recently confirmed by the given property. - * - * @param issueId ID of the previous ownership issue filed for the given application. - * @param applicationId ID of the application for which to file an issue. - * @param propertyId ID of the property responsible for the given application. - * @return ID of the created issue, if one was created. - */ - Optional<IssueId> confirmOwnership(Optional<IssueId> issueId, ApplicationId applicationId, PropertyId propertyId); - - /** * Ensure ownership of the given application has been recently confirmed by the given user. * * @param issueId ID of the previous ownership issue filed for the given application. * @param applicationId ID of the application for which to file an issue. - * @param owner ID of the user responsible for the given application. + * @param asignee Issue asignee + * @param contact Contact info for the application tenant * @return ID of the created issue, if one was created. */ - Optional<IssueId> confirmOwnership(Optional<IssueId> issueId, ApplicationId applicationId, User owner); + Optional<IssueId> confirmOwnership(Optional<IssueId> issueId, ApplicationId applicationId, User asignee, Contact contact); /** * Make sure the given ownership confirmation request is acted upon, unless it is already acknowledged. - * * @param issueId ID of the ownership issue to escalate. - * @param propertyId ID of the property responsible for the issue, if any. + * @param contact Contact information of application tenant */ - void ensureResponse(IssueId issueId, Optional<PropertyId> propertyId); + void ensureResponse(IssueId issueId, Optional<Contact> contact); } 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 6e4761d1cf8..14f252732fb 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 @@ -2,7 +2,7 @@ package com.yahoo.vespa.hosted.controller.api.integration.stubs; import com.yahoo.config.provision.ApplicationId; -import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId; +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.OwnershipIssues; import com.yahoo.vespa.hosted.controller.api.integration.organization.User; @@ -12,17 +12,12 @@ import java.util.Optional; public class DummyOwnershipIssues implements OwnershipIssues { @Override - public Optional<IssueId> confirmOwnership(Optional<IssueId> issueId, ApplicationId applicationId, PropertyId propertyId) { + public Optional<IssueId> confirmOwnership(Optional<IssueId> issueId, ApplicationId applicationId, User asignee, Contact contact) { return Optional.empty(); } @Override - public Optional<IssueId> confirmOwnership(Optional<IssueId> issueId, ApplicationId applicationId, User owner) { - return Optional.empty(); - } - - @Override - public void ensureResponse(IssueId issueId, Optional<PropertyId> propertyId) { + public void ensureResponse(IssueId issueId, Optional<Contact> contact) { } 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 c5efffd979a..5dfbeb5e756 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 @@ -6,6 +6,7 @@ import com.google.inject.Inject; import com.yahoo.component.Version; import com.yahoo.config.provision.ApplicationId; import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId; +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; import com.yahoo.vespa.hosted.controller.api.integration.organization.User; @@ -54,12 +55,7 @@ public class LoggingDeploymentIssues implements DeploymentIssues { } @Override - public IssueId fileUnlessOpen(Optional<IssueId> issueId, ApplicationId applicationId, PropertyId propertyId) { - return fileUnlessPresent(issueId, applicationId); - } - - @Override - public IssueId fileUnlessOpen(Optional<IssueId> issueId, ApplicationId applicationId, User assignee) { + public IssueId fileUnlessOpen(Optional<IssueId> issueId, ApplicationId applicationId, User asignee, Contact contact) { return fileUnlessPresent(issueId, applicationId); } @@ -73,7 +69,7 @@ public class LoggingDeploymentIssues implements DeploymentIssues { } @Override - public void escalateIfInactive(IssueId issueId, Optional<PropertyId> propertyId, Duration maxInactivity) { + public void escalateIfInactive(IssueId issueId, Duration maxInactivity, Optional<Contact> contact) { if (issueUpdates.containsKey(issueId) && issueUpdates.get(issueId).isBefore(clock.instant().minus(maxInactivity))) escalateIssue(issueId); } |