[ 
https://issues.apache.org/jira/browse/CAMEL-25544?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Claus Ibsen updated CAMEL-25544:
--------------------------------
    Fix Version/s: 4.24.0

> camel-jira - the addComment, addIssueLink, addWorkLog, attach, deleteIssue, 
> transitionIssue and watchers producers do not wait for the answer of Jira, so 
> a rejected request is not noticed and the exchange completes as if it had 
> succeeded
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25544
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25544
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-jira
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Major
>             Fix For: 4.24.0
>
>
> The Jira REST client is asynchronous: the methods of {{IssueRestClient}} 
> return a {{Promise}}, and {{claim()}} waits for the answer and throws 
> {{RestClientException}} when Jira rejected the request. {{AddIssueProducer}} 
> ({{createIssue(...).claim()}}) and {{UpdateIssueProducer}} 
> ({{updateIssue(...).claim()}}) do that. The other producers that change an 
> issue drop the promise (lines at main 9432ba16d026):
> {code:java}
> issueClient.transition(issue, transitionInput);                    // 
> TransitionIssueProducer:57
> issueClient.addComment(commentsUri, Comment.valueOf(commentStr));  // 
> TransitionIssueProducer:63
> issueClient.addComment(commentsUri, comment);                      // 
> AddCommentProducer:57
> issueClient.linkIssue(linkIssuesInput);                            // 
> AddIssueLinkProducer:63
> issueClient.addWorklog(issue.getWorklogUri(), worklogInput);       // 
> AddWorkLogProducer:60
> issueClient.addAttachments(attachmentsUri, file);                  // 
> AttachFileProducer:70
> issueClient.addAttachment(attachmentsUri, is, name);               // 
> AttachFileProducer:72
> issueClient.deleteIssue(issueKey, true);                           // 
> DeleteIssueProducer:42
> issueClient.addWatcher(...); issueClient.removeWatcher(...);       // 
> WatcherProducer:57,66 and AddIssueProducer:125
> {code}
> So {{process()}} returns at once, and:
> * a request that Jira rejects (no permission, a transition that is not 
> allowed in the workflow, a missing mandatory field, an unknown link type or 
> user, an attachment that is too large, HTTP 401/403/5xx, a network error) is 
> not noticed: the exchange completes successfully, nothing is logged, and the 
> comment, link, work log, attachment, transition or deletion is missing in 
> Jira;
> * the route continues before Jira has done the work, so a following step 
> ({{fetchIssue}}, a second {{transitionIssue}}) can see the old state, and the 
> comment of {{transitionIssue}} is not ordered after the transition;
> * for {{attach}}, the route continues before the upload has finished.
> h3. Reproduction
> New {{DeleteIssueProducerFailureTest}} uses the real Jira client against a 
> local HTTP server that answers the {{DELETE}} with 403 and a Jira error body: 
> on main the exchange has no exception, and the request has not even reached 
> the server when the exchange is done:
> {noformat}
> DeleteIssueProducerFailureTest.failsTheExchangeWhenJiraRejectsTheRequest: 
> expected: <[DELETE /rest/api/latest/issue/TST-1]> but was: <[]>
> {noformat}
> New {{JiraProducerRejectedRequestTest}} (mocked {{IssueRestClient}} as in the 
> other producer tests; every request that changes the issue returns a rejected 
> promise): one test per producer ({{addComment}}, {{addIssueLink}}, 
> {{addWorkLog}}, {{attach}} with a file and with a stream, 
> {{transitionIssue}}, {{watchers}} add and remove, {{addIssue}} with a 
> watcher) expects the {{RestClientException}} on the exchange. On main, twice, 
> all 11 new tests fail (the 9 mocked ones with {{expected: 
> <RestClientException...> but was: <null>}}).
> h3. Proposed fix
> The producers claim the promise of each request, as {{AddIssueProducer}} and 
> {{UpdateIssueProducer}} do. A rejected request then fails the exchange with 
> the {{RestClientException}} of the client, and the route continues when Jira 
> has answered (for {{attach}}: when the upload has finished). 
> {{AddIssueProducer}} sets the created issue on the exchange before it adds 
> the watchers, so that it is there when adding a watcher fails. The mocks of 
> the existing producer tests returned {{null}} for these calls and now return 
> a completed promise. 4.23 upgrade guide note added (routes that relied on 
> failures being ignored must handle the exception). camel-jira with the fix: 
> 58 tests, 0 failures.
> Found by reading the producers next to each other ({{updateIssue}} claims, 
> {{transitionIssue}} does not) and with a small TLA+ model of one exchange 
> (send, answer by Jira, return of {{process()}}, close of the body): on main 
> "a successful exchange did not have its request rejected" is violated in 4 
> steps, "the route continues only when Jira has answered" in 3 steps; with the 
> fix both properties hold. Confirmed with the real client. (The model also has 
> a property about an attachment that is read after the exchange released it, 
> violated in 5 steps; no test with the real client shows it, so it is not 
> claimed here.)
> Affected: main, camel-4.22.x, camel-4.18.x, camel-4.14.x (same code, GitHub 
> contents API).
> Duplicate check (2026-10-11): JIRA component camel-jira with text "claim", 
> "Promise", "asynchronous", "silently" or "swallow" (2, unrelated), component 
> camel-jira since 2022 (15, none about producer results; CAMEL-23539, the open 
> upgrade of the Jira client, does not change these calls); GitHub pull 
> requests with "jira" in the title: none open. No open pull request changes 
> the camel-jira producers.
> _Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to