Bug 1059786 - [amqp1.0] missing first-acquirer property support
Summary: [amqp1.0] missing first-acquirer property support
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise MRG
Classification: Red Hat
Component: qpid-cpp
Version: Development
Hardware: Unspecified
OS: Unspecified
medium
medium
Target Milestone: 3.1
: ---
Assignee: Pavel Moravec
QA Contact: Petr Matousek
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2014-01-30 16:14 UTC by Petr Matousek
Modified: 2015-04-14 13:47 UTC (History)
4 users (show)

Fixed In Version: qpid-cpp-0.30-2
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2015-04-14 13:47:23 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)
Reproducer (974 bytes, text/x-c++src)
2014-02-16 14:25 UTC, Pavel Moravec
no flags Details
Trivial patch proposal (499 bytes, patch)
2014-02-16 14:29 UTC, Pavel Moravec
no flags Details | Diff


Links
System ID Private Priority Status Summary Last Updated
Apache JIRA QPID-5594 0 None None None Never
Red Hat Bugzilla 975444 0 high CLOSED provide access to all properties in an AMQP 1.0 message 2021-02-22 00:41:40 UTC
Red Hat Bugzilla 1126525 0 medium CLOSED [AMQP 1.0] Can't read content endoding property 2021-02-22 00:41:40 UTC
Red Hat Bugzilla 1183140 0 low NEW Do not reset delivery count and first acquirer fields on rejected and rerouted messages 2021-02-22 00:41:40 UTC
Red Hat Product Errata RHEA-2015:0805 0 normal SHIPPED_LIVE Red Hat Enterprise MRG Messaging 3.1 Release 2015-04-14 17:45:54 UTC

Internal Links: 975444 1126525 1183140

Description Petr Matousek 2014-01-30 16:14:22 UTC
Description of problem:

There is a defined standard amqp1.0 property: first-acquirer. The broker shall support setting this property accordingly.

If this value is true, then this message has not been acquired by any other link. If this value is false, then this message MAY have previously been acquired by another link or links.

Version-Release number of selected component (if applicable):
qpid-cpp-*-0.22-33

How reproducible:
100%

Steps to Reproduce:
n/a

Actual results:
first-acquirer property is not set by the broker

Expected results:
first-acquirer property is set by the broker

Additional info:

Comment 1 Pavel Moravec 2014-02-16 14:25:34 UTC
Created attachment 863747 [details]
Reproducer

Reproducer program.

To compile:
g++ -lqpidclient -lqpidcommon -lqpidmessaging -lqpidtypes acquire_message_and_disconnect.cpp -o acquire_message_and_disconnect

To run:
service qpidd restart
./acquire_message_and_disconnect

The program:
- sends a message to address "q; {create:always}" (or to 1st program argument)
- acquires the message from the queue q
- disconnects from the broker
- acquires and disconnects again

Actual results:
Properties: {}
Properties: {x-amqp-delivery-count:1}

Expected results:
Properties: {x-amqp-first-acquirer:True}
Properties: {x-amqp-delivery-count:1}

Comment 2 Pavel Moravec 2014-02-16 14:29:14 UTC
Created attachment 863748 [details]
Trivial patch proposal

Until I miss something, the first acquirer of a message is the one who gets the message with delivery count = 0. So isFirstAcquirer() call should return "getDeliveryCount() == 0".

(please let me provide a scenario when first-acquirer = (delivery-count != 0), if I am wrong)

Comment 3 Gordon Sim 2014-02-17 09:34:34 UTC
(In reply to Pavel Moravec from comment #2)
> Until I miss something, the first acquirer of a message is the one who gets
> the message with delivery count = 0. So isFirstAcquirer() call should return
> "getDeliveryCount() == 0".

I would say it is the first consumer who gets the message with delivery count == 0. If an acquired message is released, its delivery count will be decremented (so may return to 0 if being released from the only delivery attempt), however - in my opinion - the first-acquirer flag should never be reset.

So while a delivery count of 0 means the message has never been (even partially) 'processed' by an application, first-acquirer == true is an even stronger guarantee that this is the first time it is ever being acquired (and has never been released).

Comment 4 Pavel Moravec 2014-03-03 12:47:37 UTC
Committed to upstream as r1573546.

Comment 6 Petr Matousek 2014-12-17 13:37:06 UTC
According to amqp1.0 specification[1] (3.4.3 Rejected, 3.4.4 Release):

"The rejected outcome when applied to a message will cause the delivery-count to be incremented in the header of the rejected message"
"The delivery-count of the header of the released message MUST NOT be incremented"

The qpid::messaging api behaves exactly the opposite way:
The delivery-count is increased when message is released.
The delivery-count is not increased when message is rejected and first-acquirer field value remains set to true.

Expected result:
Delivery-count header field is increased when message is rejected.
Delivery-count header field is not increased when message is released.
Both the rejected and released message have first-acquirer header field set to false.

So in fact, the reproducer expected results are wrong and shall be the following:
Properties: {x-amqp-first-acquirer:True}
Properties: {}

I believe that is a bug, right?

[1] http://docs.oasis-open.org/amqp/core/v1.0/amqp-core-complete-v1.0.pdf

Comment 7 Gordon Sim 2014-12-17 14:14:52 UTC
(In reply to Petr Matousek from comment #6)
> According to amqp1.0 specification[1] (3.4.3 Rejected, 3.4.4 Release):
> 
> "The rejected outcome when applied to a message will cause the
> delivery-count to be incremented in the header of the rejected message"
> "The delivery-count of the header of the released message MUST NOT be
> incremented"
> 
> The qpid::messaging api behaves exactly the opposite way:
> The delivery-count is increased when message is released.
> The delivery-count is not increased when message is rejected and
> first-acquirer field value remains set to true.
> 
> Expected result:
> Delivery-count header field is increased when message is rejected.
> Delivery-count header field is not increased when message is released.
> Both the rejected and released message have first-acquirer header field set
> to false.
> 
> So in fact, the reproducer expected results are wrong and shall be the
> following:
> Properties: {x-amqp-first-acquirer:True}
> Properties: {}

The reproducer neither rejects nor releases the message. It is unacknowledged at the point the connection is closed, so I think the reproducer expected results as stated in comment #1 are correct.

The Session::release() method will actually set the outcome as MODIFIED, since the application has seen the message. The RELEASED outcome is used for prefetched messages. This means that messages the application fetched then released will have the delivery count incremented, whereas those that were prefetched but released without being seen will not. That matches the 0-10 behaviour (with the set-redelivered flag on message release being true for explicit release and false for implicit release of prefetched messages).

A rejected messages is removed from the queue entirely. It may be routed to the alternate-exchange, but in this case it has its delivery count reset on any  new queue (delivery count is tracked per queue).

Comment 8 Petr Matousek 2014-12-17 15:44:28 UTC
(In reply to Gordon Sim from comment #7)
> (In reply to Petr Matousek from comment #6)
> > According to amqp1.0 specification[1] (3.4.3 Rejected, 3.4.4 Release):
> > 
> > "The rejected outcome when applied to a message will cause the
> > delivery-count to be incremented in the header of the rejected message"
> > "The delivery-count of the header of the released message MUST NOT be
> > incremented"
> > 
> > The qpid::messaging api behaves exactly the opposite way:
> > The delivery-count is increased when message is released.
> > The delivery-count is not increased when message is rejected and
> > first-acquirer field value remains set to true.
> > 
> > Expected result:
> > Delivery-count header field is increased when message is rejected.
> > Delivery-count header field is not increased when message is released.
> > Both the rejected and released message have first-acquirer header field set
> > to false.
> > 
> > So in fact, the reproducer expected results are wrong and shall be the
> > following:
> > Properties: {x-amqp-first-acquirer:True}
> > Properties: {}
> 
> The reproducer neither rejects nor releases the message. It is
> unacknowledged at the point the connection is closed, so I think the
> reproducer expected results as stated in comment #1 are correct.

Agreed, I thought that unacknowledged messages shall behaves the same way as released messages. 

> 
> The Session::release() method will actually set the outcome as MODIFIED,
> since the application has seen the message. The RELEASED outcome is used for
> prefetched messages. This means that messages the application fetched then
> released will have the delivery count incremented, whereas those that were
> prefetched but released without being seen will not. That matches the 0-10
> behaviour (with the set-redelivered flag on message release being true for
> explicit release and false for implicit release of prefetched messages).

Ok, I'd expected released outcome to be applied when message is released, thanks for explanation.

> 
> A rejected messages is removed from the queue entirely. It may be routed to
> the alternate-exchange, but in this case it has its delivery count reset on
> any  new queue (delivery count is tracked per queue).

I didn't know about the fact that delivery count reset is done when routing to another node, ie.: alt-ex (I haven't found that in spec.). Again, thanks for explanation. So, it's also expected the first-acquirer is set to true on the rejected message that is routed to alternate-exchange? I wouldn't expect that in this case.

Comment 9 Gordon Sim 2015-01-02 12:53:58 UTC
(In reply to Petr Matousek from comment #8)
> (In reply to Gordon Sim from comment #7)
> > (In reply to Petr Matousek from comment #6)
> > > According to amqp1.0 specification[1] (3.4.3 Rejected, 3.4.4 Release):
> > > 
> > > "The rejected outcome when applied to a message will cause the
> > > delivery-count to be incremented in the header of the rejected message"
> > > "The delivery-count of the header of the released message MUST NOT be
> > > incremented"
> > > 
> > > The qpid::messaging api behaves exactly the opposite way:
> > > The delivery-count is increased when message is released.
> > > The delivery-count is not increased when message is rejected and
> > > first-acquirer field value remains set to true.
> > > 
> > > Expected result:
> > > Delivery-count header field is increased when message is rejected.
> > > Delivery-count header field is not increased when message is released.
> > > Both the rejected and released message have first-acquirer header field set
> > > to false.
> > > 
> > > So in fact, the reproducer expected results are wrong and shall be the
> > > following:
> > > Properties: {x-amqp-first-acquirer:True}
> > > Properties: {}
> > 
> > The reproducer neither rejects nor releases the message. It is
> > unacknowledged at the point the connection is closed, so I think the
> > reproducer expected results as stated in comment #1 are correct.
> 
> Agreed, I thought that unacknowledged messages shall behaves the same way as
> released messages. 

Yes, they do. The release() method on the API is just a way of immediately returning the message to the queue rather than waiting for the session to end.

> > The Session::release() method will actually set the outcome as MODIFIED,
> > since the application has seen the message. The RELEASED outcome is used for
> > prefetched messages. This means that messages the application fetched then
> > released will have the delivery count incremented, whereas those that were
> > prefetched but released without being seen will not. That matches the 0-10
> > behaviour (with the set-redelivered flag on message release being true for
> > explicit release and false for implicit release of prefetched messages).
> 
> Ok, I'd expected released outcome to be applied when message is released,
> thanks for explanation.

Not an unreasonable expectation :-) 

> > A rejected messages is removed from the queue entirely. It may be routed to
> > the alternate-exchange, but in this case it has its delivery count reset on
> > any  new queue (delivery count is tracked per queue).
> 
> I didn't know about the fact that delivery count reset is done when routing
> to another node, ie.: alt-ex (I haven't found that in spec.). Again, thanks
> for explanation. So, it's also expected the first-acquirer is set to true on
> the rejected message that is routed to alternate-exchange? I wouldn't expect
> that in this case.

It isn't explicitly covered in any spec from my reading.

It is 'expected' in the sense that there is a explicit line in the code that resets the delivery count and the first-acquired flag. However this is only done for rejected message, not for messages rerouted for other reason (e.g. orphaned, or explicit qmf reroute request). I can't see any reason why reject should behave differently here.

There is one test that fails when the reset is not done (qpid.tests.messaging.endpoints.SessionTests.testReject), and I suspect that the explicit reset was added just to avoid that failure. However on reflection, perhaps it is the test that is wrong there.

I'd be happy to treat that as a bug, but probably simplest to treat it as a a distinct issue from this BZ. (It affects both 0-10 and 1.0)

Comment 10 Petr Matousek 2015-01-16 19:37:44 UTC
The issue from comment 9 above is now tracked as bug 1183140.

Comment 11 Petr Matousek 2015-01-19 12:34:53 UTC
AMQP 1.0 defined 'first acquirer' header is now accessible via 'x-amqp-first-acquirer' flag in the message properties map using qpid::messaging API.

Verified on rhel6.6 (x86_64 and i386)

Packages:
qpid-cpp-*-0.30-5

-> VERIFIED

Comment 12 Petr Matousek 2015-02-09 17:42:22 UTC
(In reply to Petr Matousek from comment #11)
correction: 

Packages:
qpid-cpp-*-0.30-5 (reproducible) -> qpid-cpp-*-0.30-6 (fixed)

Comment 14 errata-xmlrpc 2015-04-14 13:47:23 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://rhn.redhat.com/errata/RHEA-2015-0805.html


Note You need to log in before you can comment on or make changes to this bug.