Skip to content

Commit c0291d3

Browse files
committed
Use an optional "notMappedAssignee" user for unmapped assignees
1 parent 9bee577 commit c0291d3

File tree

4 files changed

+49
-13
lines changed

4 files changed

+49
-13
lines changed

src/main/java/org/hibernate/infra/replicate/jira/JiraConfig.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.net.URI;
44
import java.util.Base64;
55
import java.util.Map;
6+
import java.util.Optional;
67

78
import io.smallrye.config.ConfigMapping;
89
import io.smallrye.config.WithDefault;
@@ -241,6 +242,17 @@ interface UserValueMapping extends ValueMapping {
241242
*/
242243
@WithDefault("accountId")
243244
String mappedPropertyName();
245+
246+
/**
247+
* By default, if the assignee of the upstream issue is not mapped, the project
248+
* default will be used (i.e. assignee field will not be sent as part of the
249+
* sync request). If the {@code notMappedAssignee} is provided, this value will
250+
* be set as assignee for those issues where an upstream assignee is not mapped
251+
* to a downstream one. This can be useful to show that the issue is assign to
252+
* someone even though that particular user is not present in the downstream
253+
* Jira.
254+
*/
255+
Optional<String> notMappedAssignee();
244256
}
245257

246258
/**

src/main/java/org/hibernate/infra/replicate/jira/service/jira/HandlerProjectContext.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.hibernate.infra.replicate.jira.service.jira.model.rest.JiraIssueBulk;
1212
import org.hibernate.infra.replicate.jira.service.jira.model.rest.JiraIssueBulkResponse;
1313
import org.hibernate.infra.replicate.jira.service.jira.model.rest.JiraIssues;
14+
import org.hibernate.infra.replicate.jira.service.jira.model.rest.JiraUser;
1415

1516
import io.quarkus.logging.Log;
1617

@@ -32,6 +33,7 @@ public final class HandlerProjectContext implements AutoCloseable {
3233
private final JiraIssueBulk bulk;
3334

3435
private final String projectKeyWithDash;
36+
private final JiraUser notMappedAssignee;
3537

3638
public HandlerProjectContext(String projectName, String projectGroupName, JiraRestClient sourceJiraClient,
3739
JiraRestClient destinationJiraClient, HandlerProjectGroupContext projectGroupContext) {
@@ -44,6 +46,9 @@ public HandlerProjectContext(String projectName, String projectGroupName, JiraRe
4446
this.currentIssueKeyNumber = new AtomicLong(getCurrentLatestJiraIssueKeyNumber());
4547
this.bulk = new JiraIssueBulk(createIssuePlaceholder(), ISSUES_PER_REQUEST);
4648
this.projectKeyWithDash = "%s-".formatted(project.projectKey());
49+
50+
this.notMappedAssignee = projectGroup().users().notMappedAssignee()
51+
.map(v -> new JiraUser(projectGroup().users().mappedPropertyName(), v)).orElse(null);
4752
}
4853

4954
public JiraConfig.JiraProject project() {
@@ -151,6 +156,10 @@ public void startProcessingEvent() throws InterruptedException {
151156
projectGroupContext.startProcessingEvent();
152157
}
153158

159+
public JiraUser notMappedAssignee() {
160+
return notMappedAssignee;
161+
}
162+
154163
private boolean requiredIssueKeyNumberShouldBeAvailable(Long key) {
155164
return currentIssueKeyNumber.get() >= key;
156165
}

src/main/java/org/hibernate/infra/replicate/jira/service/jira/handler/JiraIssueUpsertEventHandler.java

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,8 @@ protected void doRun() {
4343

4444
try {
4545
JiraIssue issue = issueToCreate(sourceIssue);
46-
try {
47-
context.destinationJiraClient().update(destinationKey, issue);
48-
} catch (JiraRestException e) {
49-
if (e.getMessage().contains("\"assignee\"")) {
50-
failureCollector.warning(
51-
"Unable to update issue %s with assignee, will try to update all but assignee field."
52-
.formatted(sourceIssue.key),
53-
e);
54-
issue.fields.assignee = null;
55-
context.destinationJiraClient().update(destinationKey, issue);
56-
}
57-
}
46+
47+
updateIssue(destinationKey, issue, sourceIssue, context.notMappedAssignee());
5848
// remote "aka web" links cannot be added in the same request and are also not
5949
// returned as part of the issue API.
6050
// We "upsert" the remote link pointing to the "original/source" issue that
@@ -72,6 +62,29 @@ protected void doRun() {
7262
}
7363
}
7464

65+
private void updateIssue(String destinationKey, JiraIssue issue, JiraIssue sourceIssue, JiraUser assignee) {
66+
try {
67+
context.destinationJiraClient().update(destinationKey, issue);
68+
} catch (JiraRestException e) {
69+
if (issue.fields.assignee == null) {
70+
// if we failed with no assignee then there's no point in retrying ...
71+
throw e;
72+
}
73+
if (e.getMessage().contains("\"assignee\"")) {
74+
// let's try updating with the assignee passed to the method (it may be the
75+
// "notMappedAssignee")
76+
failureCollector.warning(
77+
"Unable to update issue %s with assignee %s, will try to update one more time with assignee %s."
78+
.formatted(sourceIssue.key, issue.fields.assignee, assignee),
79+
e);
80+
issue.fields.assignee = assignee;
81+
updateIssue(destinationKey, issue, sourceIssue, null);
82+
} else {
83+
throw e;
84+
}
85+
}
86+
}
87+
7588
@Override
7689
public String toString() {
7790
return "JiraIssueUpsertEventHandler[" + "objectId=" + objectId + ", project=" + context.projectName() + ']';
@@ -135,7 +148,8 @@ private JiraIssue issueToCreate(JiraIssue sourceIssue) {
135148
// also the description is going to include a section mentioning who created and
136149
// who the issue is assigned to...
137150
if (context.projectGroup().canSetReporter()) {
138-
destinationIssue.fields.reporter = user(sourceIssue.fields.reporter).map(this::toUser).orElse(null);
151+
destinationIssue.fields.reporter = user(sourceIssue.fields.reporter).map(this::toUser)
152+
.orElseGet(context::notMappedAssignee);
139153
}
140154

141155
destinationIssue.fields.assignee = user(sourceIssue.fields.assignee).map(this::toUser).orElse(null);

src/main/resources/application.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ quarkus.scheduler.start-mode=forced
4545
# Just open a user profile and get the ID from the URl: https://hibernate.atlassian.net/jira/people/557058:18cf44bb-bc9b-4e8d-b1b7-882969ddc8e5
4646
#
4747
%prod,test.jira.project-group."hibernate".users.mapped-property-name=name
48+
%prod,test.jira.project-group."hibernate".users.not-mapped-assignee=[email protected]
4849
# Yoann:
4950
%dev.jira.project-group."hibernate".users.mapping."557058\:58fa1ced-171a-4c00-97e8-5d70d442cc4b"=557058:58fa1ced-171a-4c00-97e8-5d70d442cc4b
5051
%prod,test.jira.project-group."hibernate".users.mapping."557058\:58fa1ced-171a-4c00-97e8-5d70d442cc4b"=rh-ee-yrodiere

0 commit comments

Comments
 (0)