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.

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

      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 name “foo|bar”.
          Link does not exist.
          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 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 the link with error “resource locked”.

      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 the link with error “resource locked”.

      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”.

      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 the link with error “resource locked”.

      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 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

      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

      ...

      
              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

       

      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

       

      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.