Bug 1283637

Summary: [C++ broker] AMQP 1.0 released message, delivery-count cant be incremented
Product: Red Hat Enterprise MRG Reporter: Pavel Moravec <pmoravec>
Component: qpid-cppAssignee: messaging-bugs <messaging-bugs>
Status: CLOSED NOTABUG QA Contact: Messaging QE <messaging-qe-bugs>
Severity: medium Docs Contact:
Priority: medium    
Version: 3.2CC: gsim, jross
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2015-11-22 22:00:40 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Pavel Moravec 2015-11-19 13:38:39 UTC
Description of problem:
When an AMQP 1.0 consumer releases back a message, the broker increases delivery-count and removes first-acquirer flag for the message. That violates AMQP 1.0 specification:

3.4.4 Released:

"The message is unchanged at the node (i.e., the delivery-count of the header of the released message MUST NOT be incremented)."


Version-Release number of selected component (if applicable):
qpid-cpp-server-0.34-5.el6.x86_64


How reproducible:
100%


Steps to Reproduce:
1. Compile below program:

    const char* url = "amqp:localhost:5672";
    std::string connectionOptions = "{ transport: 'tcp', protocol: 'amqp1.0' }";
    Address address("testQueue; { node: { type: queue }, create: always, assert: never }");

    Message msg;

    Connection connection(url, connectionOptions);
    Session session;
    Sender sender;
    Receiver receiver;

    connection.open();
    session = connection.createSession();
    receiver = session.createReceiver(address);
    while (receiver.fetch(msg, Duration::IMMEDIATE))
    {}
    sender = session.createSender(address);
    sender.send(Message());
    for (int i=0; i<5; i++) {
        receiver = session.createReceiver(address);
      	receiver.fetch(msg, Duration::FOREVER);
	std::cout << "Received message: redelivered=" << ((msg.getRedelivered())?"true":"false")
                  << " Properties: " << msg.getProperties() << std::endl;
	session.release(msg);
	receiver.close();
    }

    sender.close();
    session.close();
    connection.close();
    

2. Run it against a broker


Actual results:
Received message: redelivered=false Properties: {x-amqp-first-acquirer:True}
Received message: redelivered=true Properties: {x-amqp-delivery-count:1}
Received message: redelivered=true Properties: {x-amqp-delivery-count:2}
Received message: redelivered=true Properties: {x-amqp-delivery-count:3}
Received message: redelivered=true Properties: {x-amqp-delivery-count:4}


Expected results:
Received message: redelivered=false Properties: {x-amqp-first-acquirer:True}
Received message: redelivered=false Properties: {x-amqp-first-acquirer:True}
Received message: redelivered=false Properties: {x-amqp-first-acquirer:True}
Received message: redelivered=false Properties: {x-amqp-first-acquirer:True}
Received message: redelivered=false Properties: {x-amqp-first-acquirer:True}


Additional info:
qpid/cpp/src/qpid/broker/amqp/Outgoing.cpp:

            switch (r.disposition) {
..
              case PN_RELEASED:
                if (preAcquires()) queue->release(r.cursor, false);//for PN_RELEASED, delivery count should not be incremented
                outgoingMessageRejected();//TODO: not quite true...
                break;

Comment 1 Gordon Sim 2015-11-19 14:24:59 UTC
Session::release() does not send an AMQP RELEASED disposition, it sends an AMQP MODIFIED disposition.

Comment 2 Pavel Moravec 2015-11-22 22:00:40 UTC
(In reply to Gordon Sim from comment #1)
> Session::release() does not send an AMQP RELEASED disposition, it sends an
> AMQP MODIFIED disposition.

Agreed, and sending real RELEASED disposition does not lead to the observation above - the message remains unchanged. Closing as not a bug.