Alex Rudyy created QPIDJMS-349:
----------------------------------

             Summary: JMS transactions should fail when messages are published 
into non-existinng destinations using anonymous producer
                 Key: QPIDJMS-349
                 URL: https://issues.apache.org/jira/browse/QPIDJMS-349
             Project: Qpid JMS
          Issue Type: Bug
          Components: qpid-jms-client
    Affects Versions: 0.27.0, 0.26.0, 0.25.0, 0.24.0
            Reporter: Alex Rudyy


The current client implementation allows to commit JMS transaction 
successfully, when message is published into non-existing destination over 
anonymous relay within a transaction. Though, only part of the messages within 
the transaction reaches their destinations. This situation can potentially 
result in message loss, as the client application would consider such 
transaction successful. The exception {{"javax.jms.InvalidDestinationException: 
Unknown destination 'nonExistingQueue' [condition = amqp:not-found]"}} is 
reported into {{ExceptionListener}} but client allows to commit the JMS 
transaction successfully. If no {{ExceptionListener}} is set, the exception is 
logged. 

It seems, the JMS client is failing to deliver JMS transaction contract, when 
publishing messages using anonymous producer.  Atomicity (all or nothing) is 
not guaranteed in this case.

The following code snippet demonstrate the problem:
{code}
try( Connection connection =
connectionFactory.createConnection(username, password))
{
    Session session = connection.createSession(true,
Session.SESSION_TRANSACTED);
    MessageProducer messageProducer = session.createProducer(null);
    Queue nonExistingQueue = session.createQueue("nonExistingQueue");
    messageProducer.send(nonExistingQueue,
session.createTextMessage("testMessage"));
    session.commit();
}
{code}

>From AMQP point of view both broker and client behaviours are fully AMQP 
>compliant.
The implementations conform the requirements of specification "Using the 
Anonymous Terminus for Message Routing" [1] as per section "2.2.2 Routing 
Errors" :
{quote}
If the source of the link supports the rejected outcome, and the message has 
not already been settled by the sender, then the routing node MUST reject the 
message.
{quote}

On attach, the client specifies the following outcomes on the source:
{noformat}
outcomes=[amqp:accepted:list,amqp:rejected:list,amqp:released:list,amqp:modified:list]}
{noformat}

When Broker receives a message for non-existing destination, the anonymous
relay implementation returns rejected outcome, as 'rejected' outcome is in the 
list of source supported outcomes. The Broker replies with settled disposition 
having rejected outcome and error 'not-found'. Here is an example of disposition
{noformat}
Disposition{role=receiver,first=1,last=1,settled=true,state=TransactionalState{txnId=\x00\x00\x00\x00,outcome=Rejected{error=Error{condition=not-found,description=Unknown
destination 'nonExistingQueue'}}}}
{noformat}

Thus, the AMQP transaction can be committed successfully in this case, as the 
message is settled and has final outcome.

I am wondering whether a better approach  would be to stop supporting 
"rejected" outcome for anonymous producer on transacted sessions. That would 
cause the broker to detach the link with an error and mark the transaction as 
rollback only. Thus, any commit issued from the client will fail in this case.

[1] 
https://www.oasis-open.org/apps/org/workgroup/amqp/download.php/61723/amqp-anonterm-v1.0-wd03.pdf



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to