Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

The JMS 2.0 specification adds support for shared subscriptions. QPIDJMS-220 outlines how the Qpid JMS client maps the JMS semantics to AMQP terms. This document outlines how the broker responds to those AMQP performatives.

Connection Open

“SHARED-SUB” capability should be set on offered capabilities.

Link Attach

Assumptions:

  • If source is set the address is specified as “exchange/binding” and exchange with name “exchange” exists. If exchange with name “exchange” does not exist the link is refused with error “not found”.
  • Link does not exist. for Link reattachment see below.
  • Terminus durability : NO means 0, YES means 1 or 2.
  • When creating a queue its life time policy will be derived from source expiry policy as follow:
    • “link-detach” becomes “delete on no outbound link”
    • “session-end” becomes “delete on session end”
    • “connection-close” becomes “delete on connection close”
    • “never” becomes “permanent"
  • SHARED and GLOBAL are derived from Source capabilities if Source is set and from Link capabilities otherwise

...

Not Null Source

SHARED

GLOBAL

TERMINUS DURABILITY

outcome

YES

NO

NO

NO

Create a non-durable queue with random name and exclusivity policy “link”. Bind queue to exchange “exchange” using binding key “binding”. Broker replies with attach having capability “topic” on a source and attach offered capability “SHARED_-SUB”.

YES

NO

NO

YES

Create a durable queue with name derived from link name, container id and source durability. Exclusivity policy is set to “link”. Bind queue to exchange. Broker replies with attach having capability “topic” on a source and attach offered capability “SHARED_-SUB”.

If queue already exists the link should be refused with error “resource locked”

YES

NO

YES

NO

The same as for SHARED=NO, GLOBAL=NO and DURABLE=NO

YES

NO

YES

YES

Create a durable queue with name derived from link name, global name space and source durability. Exclusivity policy is set to “link”. Bind queue to exchange. Broker replies with attach having capabilities “topic” and “global” on a source and attach offered capability “SHARED_-SUB”.

If queue already exists the link should be refused with error “resource locked”

YES

YES

NO

NO

Create a non-durable queue with name derived from link name (up to “|”), container id and source durability. Exclusivity policy is set to “shared”. Bind queue to exchange. Broker replies with attach having capabilities “topic” and “shared” on a source and attach offered capability “SHARED_SUB”.

If queue already exists and filters and/or binding key are not the same as derived from attach source, then:

    • if there is/are existing consumer(s), refuse the link with error “resource locked”

    • if there is no consumer, rebind delete queue and bind new queue using new filters and/or binding key

If existing queue exclusivity policy is not “shared”, then link creation is refused with error “resource locked”.

If existing queue lifetime and/or durability are different from expected, then link creation is allowed but the source fields in the reply should be modified accordingly.

YES

YES

NO

YES

Create a durable queue with name derived from link name (up to “|”), container id and source durability. Exclusivity policy is set to “shared”. Bind queue to exchange. Broker replies with attach having capabilities “topic” and “shared” on a source and attach offered capability “SHARED_SUB”.

See above, if queue exists

YES

YES

YES

NO

Create a non-durable queue with name derived from link name (up to “|”), global namespace and source durability. Exclusivity policy is set to “shared”. Bind queue to exchange. Broker replies with attach having capabilities “topic”, “shared” and “global” on a source and attach offered capability “SHARED_SUB”.

See above, if queue exists

YES

YES

YES

YES

Create a durable queue with name derived from link name (up to “|”), global name space and source durability. Exclusivity policy is set to “shared”. Bind queue to exchange. Broker replies with attach having capabilities “topic”, “shared” and “global” on a source and attach offered capability “SHARED_SUB”.

See above, if queue exists

NO

NO

NO

N/A

Look for queue with name derived from link name, container id and “true” durability.

If queue exists and there is no consumer, delete queue. Reply with attach having null source.If queue exists but there is/are consumer(s), refuse Attach the link with error “resource locked”the Source set.

If queue does not exist, refuse the link with error “not found”. TODO: This breaks the AMQP spec

NO

NO

YES

N/A

Look for queue with name derived from link name, global name space and “true” durability.

If queue exists and there is no consumer, delete queue. Reply with attach having null source.If queue exists but there is/are consumer(s), refuse Attach the link with error “resource locked”the Source set.

If queue does not exist, refuse the link with error “not found” . TODO: This breaks the AMQP spec 

NO

YES

NO

N/A

Look for queue with name derived from link name (up to “|”), container id and “true” durability.

If queue exists and there is no consumer, delete queue. Reply with attach having null source.If queue exists but there is/are consumer(s), refuse the link with error “resource locked”. Attach the link with the Source set.

If queue does not exist, refuse the link with error “not found”.

NO

YES

YES

N/A

Look for queue with name derived from link name (up to “|”), global name space and “true” durability.

If queue exists and there is no consumer, delete queue. Reply with attach having null source.

If queue exists but there is/are consumer(s), refuse

Attach the link with

error “resource locked”

the Source set.

If queue does not exist, refuse the link with error “not found”.

 

TODO: Attach with null Source from an AMQP perspective should not error with resource-locked or not-found. The JMS mapping seems to require this.

Link Link re-Attach

If link exists and the queue exists see the instructions for the existing queue for SHARED=YES.  
If link exists and the queue does not exist, recreate a queue as described in corresponding instructions above.

Pseudo Code

...

Link Detach

If the Detach has close=true

  • If Link Source has capability "topic" and queue has no consumers, the queue is deleted and the Link is Detached
  • If Link Source has capability "topic" and queue has consumers, the Link is detached with error(resource-locked)
  • if Link Source does not have capability "topic", the Link is detached

Pseudo Code

The above described behaviour results in the following pseudo code. Where the below differs from the above the above is considered normative:

No Format
if Link does not exists
 
No Format
if Link does not exists
        if Source is set
                if Source has SHARED capability
                        subscription_name = Link name up to (excluding) “|”
                        exclusivity_policy = “SHARED”
                else
                        subscription_name = Link name
                        exclusivity_policy = “LINK”
                if Source has GLOBAL capability
                        name_space = global name space
                else
                        name_space = name space derived from container-id name space
                queue_name = get_queue_name(
                                name_space,
                                subscription_name,
                                Source Durability)
                if queue with name exists
                        if has same exclusivity_policy
                                if different binding key or filter
                                        if no consumer
                                                rebind queue
                                        else
                                                error(resource-locked)
                        else
                                error(resource-locked)
                else
                        create_queue(
                                queue_name
                                exclusivity_policy,
                                Source Durability,
                                Source Expiry Policy)
                        bind queue
                send Attach
        else
                // name_space and subscription_name are derived as above just from Link capabilities instead of Source capabilities
                queue_name = get_queue_name(
                                        name_space,
                                        subscription_name,
                                        TRUE_DURABILITY)
                if queue exists
                        if queue has consumers
Attach Link with correct Source set
                else
                        error(resourcenot-lockedfound) // This breaks the AMQP spec
                     
else
   else
     queue_name = get_queue_name(
                         delete queue
      name_space,
                          Attach Link with null Source   subscription_name,
                else
                TRUE_DURABILITY)
        error(not-found) // This breaks the AMQP specif queue exists
                if has same exclusivity_policy
            
else
        queue_name = get_queue_name(
  if different binding key or filter
                         name_space,
       if no consumer
                       subscription_name,
                 rebind queue
              TRUE_DURABILITY)
        if queue exists
        else
        if has same exclusivity_policy
                        if different binding key or filter error(resource-locked)
                else
                if no consumer
      error(resource-locked)
        else
                create_queue(
          rebind queue
             queue_name
                   else
     exclusivity_policy,
                        Source Durability,
          error(resource-locked)
              Source Expiry elsePolicy)
                        error(resource-locked)bind queue
        else
                create_queue(
                        queue_name
                        exclusivity_policy,
                        Source Durability,
                        Source Expiry Policy)
                bind queue
        send Attach

 

If link exists and the queue exists see the instructions for the existing queue for SHARED=YES.

If link exists and the queue does not exist, recreate a queue as described in corresponding instructions above.

 

 

The above described behaviour results in the following pseudo code. Where the below differs from the above the above is considered normative:

 

if Link does not exists

if Source is set

if Source has SHARED capability

subscription_name = Link name up to (excluding) “|”

exclusivity_policy = “SHARED”

else

subscription_name = Link name

exclusivity_policy = “LINK”

if Source has GLOBAL capability

name_space = global name space

else

name_space = container-id name space

name = get_queue_name(

name_space,

subscription_name,

Source Durability)

if queue with name exists

if has same exclusivity_policy

if different binding key or filter

if no consumer

rebind queue

else

error(resource-locked)

else

error(resource-locked)

else

create_queue(

queue_name

exclusivity_policy,

Source Durability,

Source Expiry Policy)

bind queue

send Attach

else

queue_name = get_queue_name(

name_space,

subscription_name,

TRUE_DURABILITY)

if queue exists

if queue has consumers

error(resource-locked) // This breaks the AMQP spec

else

delete queue

Attach Link with null Source

else

error(not-found) // This breaks the AMQP spec

else

queue_name = get_queue_name(

name_space,

subscription_name,

TRUE_DURABILITY)

if queue exists

if has same exclusivity_policy

if different binding key or filter

if no consumer

rebind queue

else

error(resource-locked)

else

error(resource-locked)

else

 create_queue(

queue_name

exclusivity_policy,

Source Durability,

Source Expiry Policy)

bind queue

send Attach

 

...

send Attach