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

Claus Ibsen resolved CAMEL-25945.
---------------------------------
    Resolution: Fixed

> camel-azure-storage-queue - the consumer deletes the message named by the 
> headers at the end of the route, so a forwarded message, or a route that 
> removes the Camel headers, stays in the queue and is consumed again and again
> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25945
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25945
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-azure
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Major
>             Fix For: 4.24.0
>
>
> {{QueueConsumer}} deletes a message once its exchange completes 
> ({{processCommit}}, main 9f839f4bcc9d). It does so with 
> {{QueueOperations.deleteMessage(exchange)}}, which reads the message id and 
> the pop receipt from the {{CamelAzureStorageQueueMessageId}} and 
> {{CamelAzureStorageQueuePopReceipt}} headers as they are when the route ends, 
> not as the consumer set them. So:
> * a route that forwards the message to another queue, 
> {{from("azure-storage-queue://account/a").to("azure-storage-queue://account/b")}}:
>  the producer ({{sendMessage}}) sets both headers to the id and pop receipt 
> of the message it just added to queue b 
> ({{QueueOperationResponse.buildResponse}} copies the {{SendMessageResult}} of 
> {{QueueClient.sendMessageWithResponse}} into them). The consumer then calls 
> Delete Message on queue a with the id of the message in queue b. Queue 
> Storage answers 404 MessageNotFound, the SDK throws 
> {{QueueStorageException}}, and {{processCommit}} logs it as "This exception 
> is ignored";
> * a route that removes the Camel headers before it calls another system 
> ({{removeHeaders("Camel*")}}): {{deleteMessage}} throws 
> {{IllegalArgumentException: Message ID must be specified}}, which 
> {{processCommit}} does not catch either.
> In both cases the received message stays in queue a. It becomes visible again 
> when its visibility timeout ends (30 seconds by default) and is consumed 
> again, every time, until its time-to-live ends (7 days by default). With the 
> forwarding route, each round adds one more copy of the message to queue b.
> *Fix*: as CAMEL-16092 did, the consumer keeps the id and pop receipt it 
> received the message with (taken in {{processBatch}} before the exchange is 
> routed) and deletes that message. A route that updates the message 
> ({{operation=updateMessage}}, which gives the message a new pop receipt and 
> makes the old one invalid) sets the new receipt in the header, along with the 
> same message id. That receipt is used, so this case works as it does today. 
> The delete uses the endpoint's {{timeout}} option and no longer takes the 
> producer's {{CamelAzureStorageQueueTimeout}} header.
> *Tests*: new {{QueueConsumerDeleteMessageTest}}. Its fake {{QueueClient}} 
> answers like the Queue Storage REST API: Put Message returns the new id and 
> pop receipt, Update Message returns a new pop receipt and invalidates the old 
> one, and Delete Message throws {{QueueStorageException}} with 404 
> MessageNotFound for an unknown id and 400 PopReceiptMismatch for a stale 
> receipt. Two of its tests fail on main:
> * {{forwardedMessageIsDeletedFromTheSourceQueue}}: {{Argument(s) are 
> different! Wanted: deleteMessageWithResponse("a-1", "a-1-receipt-1", ...)}}, 
> but the actual call was {{deleteMessageWithResponse("b-1", ...)}};
> * {{messageIsDeletedWhenTheRouteRemovesTheCamelHeaders}}: {{Wanted but not 
> invoked: deleteMessageWithResponse(...)}}.
> {{updatedMessageIsDeletedWithItsNewPopReceipt}} is a control that passes on 
> main and with the fix.
> camel-azure-storage-queue unit tests with the fix: 14 run, 0 failures.
> *How it was found*: library-contract mining. I listed what the Azure Queue 
> SDK calls return on each path (the {{SendMessageResult}} of Put Message, the 
> new receipt of Update Message, the 404/400 of Delete Message), then checked 
> the consumer's commit against those results.
> *Affected*: main, camel-4.23.x and camel-4.22.x, since CAMEL-24158 
> (f6707ee43184). That change removed the save and restore of the message id, 
> pop receipt and timeout headers around {{processCommit}}, which CAMEL-16092 
> had added for this kind of header override. The removal was so that a route 
> that updates the message keeps its new pop receipt. camel-4.18.x and 
> camel-4.14.x still restore the received values, so forwarding works there, 
> but a route that updates the message deletes it with the stale receipt. The 
> fix covers both cases. I read the code on those branches but did not run the 
> tests there.
> Not changed: {{camel-aws2-sqs}} deletes with the {{CamelAwsSqsReceiptHandle}} 
> header in the same way. Its producer does not set that header, so only 
> {{removeHeaders("Camel*")}} makes it miss, and SQS stops redelivering after 
> the queue's {{maxReceiveCount}}. A separate follow-up if wanted.
> _Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to