Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

This page describes the requirements and initial design of the new Qpid JMS Client that supports AMQP 1.0 (simply referred to as the "Qpid JMS Client" below).

Table of Contents

Requirements

Functional requirements

...

  • Project folder structure
  • Build tool configuration
  • CI server job
  • Automated HTML documentation generation.
Phase 1
  • Synchronous, Auto-Ack style 'simple client'
  • All Message types.
  • Main operations on JMS Connections, Sessions, Consumers, Producers, Queues, Message (Text?).
    • Include closing/stopping/deleting where applicable.
  • Configuration
    • Ability to configure settings such as pre-fetch etc
      • TODO per connection or per consumer or both? If the latter then not sure how to pass this setting in (address options?), given that JMS API doesn't offer an obvious way to do it.
      TODO define how JNDI configuration will work
  • Basic JNDI
  • SASL
  • Correct handling of non-happy path scenarios, namely:
    • Unexpected errors
    • Failures that are nevertheless AMQP-compliant, e.g. the Broker spontaneously sends a Close or End frame.
    • Timeouts due to connectivity failure etc. Necessary because of the asynchronous nature of AMQP.
    • Interruption of application-owned threads.

...

  • SSL
  • Transactions
  • Client Ack
  • SelectorsJNDI
  • MessageListener.onMessage()
  • Durable Subscriptions
  • JMS 2.0 features:
    • Asynchronous send
    • Shared Topic Subscriptions
  • Enhanced JNDI

 

Non-functional requirements

...

  • AMQP 0-x
  • ADDR and BURL addressing formats
  • Failover. Instead, this will be implemented in the future either entirely below or entirely above the client code.
  • Accepting legacy system properties (unelss they happen to match what we would choose now).

Design

Layers

No Format

+================================+
|
| JMS
|
| Implementations of javax.jms
|
+================================+
               |
               |
              \|/
+================================+
|
| AMQP
|
| Wrappers around Proton's engine
| classes, primarily to add locking
|
+================================+
            |                 |
            |                 |
           \|/                |
+======================+      |
|       Proton         |      |
|                      |      |
| Message |  Engine    |      |
|         |            |      |
+=========+============+      |
                    /|\       |
                     |        |
                     |       \|/
                   +====================
                   |
                   | JMS Driver interface
                   |
                   +=====================
                            /|\
                             |
                        +--------------+
                        |              |
                        |              |
                        |              |
                  +===========+        +==============
                  |                    |
                  |  Socket            |
                  |  driver            | Another driver,
                  |  (might use        | e.g. in-VM
                  |  Proton's Driver)  |
                  |                    |
                  +===========+        +==============
                    |
                    | TCP/IP
                    |
                   \|/
+================================+
|
| Broker
|
+================================+

...

  • Goals:
    • Minimise the number of locks
    • Define the correct locking order
    • Document what application behaviour is legal (e.g. what can be done inside MessageListener.onMessage?)
    • Make the JMS client thread-safe when used legally.

Threads fall into two three categories:

  1. Application threads using the JMS API. Only use the top half of the Proton API.
  2. One or more driver threads for I/O. Managed by the JMS client. Only use the bottom half of the Proton API.
  3. Threads managed by the JMS client that call application code (e.g. MessageListener.onMessage, ExceptionListener.onException and CompletionListener.xxx).

For a given connection:

  1. State shared by multiple application threads (namely the state of the objects in the JMS layer) is guarded by the JMS ConnectionLock.
  2. State shared by the application and driver threads is guarded by the AmqpConnection lock. This shared state is:
    1. A small number of flags the application and driver threads use to indicate to each other that "something has changed".
    2. The Proton objects. This sharing occurs inside Proton but needs to be guarded by the JMS client because Proton itself is not thread-safe.

TODO extend the locking scheme to include the JMS Client-owned threads that call application code.

Synchronous operations must follow the locking scheme indicated by the following pseudo-code:

...

The following diagram shows how module tests will work:

No Format

+================================+
|
| JUnit test
|
| 1. Create an in-process TestAmqpPeer
| 2. Set up TestAmqpPeer behaviour and expectations
| 3. Call some JMS methods
| 
+================================+
   |       |             |
   |       |             |
   |       |            \|/
   |       |    +================================+
   |       |    |
   |       |    | JMS client
   |       |    |
   |       |    +================================+
   |       |                |                 |
   |    latch/              |                 |
   |     unlatch etc        |                 |
   |       |               \|/                |
   |       |    +======================+      |
   |       |    |       Proton         |      |
expect/    |    |                      |      |
 assert    |    | Message |  Engine    |      |
   |       |    |         |            |      |
   |       |    +=========+============+      |
   |       |                /|\               |
   |       |                 |                |
   |      \|/               \|/              \|/
   |    +=======================================
   |    |
   |    | In-process Driver
   |    |
   |    +=======================================
   |                      /|\
   |                       |
   |                       | Bytes
   |                       |
  \|/                     \|/
+===================================+
|
| TestAmqpPeer
|
+===================================+

...