AMQP Messages

AMQP Types

AMQP defines a set of commonly used primitive types aimed towards a cross-platform interoperable data representation. These primitive types are divided into the following categories:

  • Primitive
  • Described
  • Composite
  • Restricted

NOTE: In Universal Messaging, an embedded Apache Qpid Proton-J protocol engine is used for type marshalling so all type mappings occur as defined by the Proton-J API. See the Qpid Proton page at https://qpid.apache.org/proton/index.html for details.

AMQP Message Format

AMQP offers a standard message format (default) which can be overridden by an AMQP node. It consists of a bare message (immutable end-end) and an annotated message which may be altered by peer / intermediate nodes.

The following figure illustrates the default AMQP message format:

NOTE: Universal Messaging supports the default message format and provides a transformation layer based on it. Currently no tests have been performed with a custom AMQP message format, at the very least transformers would fail.

Transfer Headers

AMQP header UM Header AMQP Type Java Type UM
durable nPublished.isPersistent boolean boolean (tick)
priority nHeader.Priority ubyte (Default: 4) byte (tick)
ttl nHeader.TTL milliseconds (uint) long (tick)
first-acquirer nEventProperties.JMS_AMQP_FirstAcquirer boolean boolean (tick)
delivery-count nHeader.RedeliveredCount uint (Default: 0) long (tick)
Note: Transfer headers are always mapped irrespective of whether an AMQP transformer is used or not.

Delivery Annotations

AMQP Delivery annotations offer an optional non-normative section for AMQP vendor defined recipients by typically providing delivery related information from the sending node to the receiving node.

AMQP Delivery Annotation UM Header Key AMQP Key/Value Type Java Key/Value Type UM
SomeDeliveryAnnotation JMS_AMQP_DA_<AMQP_SYMBOL_NAME(SomeDeliveryAnnotation)> AMQP Symbol / AMQP Value String / nEventProperties Value (tick)

Universal Messaging currently does not make use of any delivery annotations but will preserve any received. The naming convention used is <JMS_AMQP_DA_><delivery annotation symbol>

Message Annotations

AMQP Message annotations offer an optional section for AMQP properties aimed at AMQP infrastructure nodes. The following table illustrates the mappings to Universal Messaging:

AMQP Message Annotation UM Header Key AMQP Key/Value Type Java Key/Value Type UM
SomeMessageAnnotation JMS_AMQP_MA_<AMQP SYMBOL_NAME(SomeMessageAnnotation)> AMQP Symbol / AMQP Value String / nEventProperties Value
x-opt-jms-msg-type JMS_AMQP_MA_x-opt-jms-msg-type x-opt-jms-msg-type / AMQP byte String / byte (nHeader.MessageType) (tick)
x-opt-jms-dest JMS_AMQP_MA_x-opt-jms-dest x-opt-jms-dest / AMQP String String / byte[] (nHeader.Type) (tick)
x-opt-reply-type JMS_AMQP_MA_x-opt-reply-type x-opt-reply-type / AMQP byte String / byte (nHeader.ReplyType) (tick)
Note: Only applies when using the Complete AMQP Transformer.

Standard Message Properties

AMQP standard message properties is a section used for a defined set of immutable standard properties of the message. The section is part of the bare message; therefore, if retransmitted by an intermediary, it must remain unaltered.

The following table illustrates how these standard message properties are mapped to Universal Messaging:

AMQP Standard Property UM Header Mapping AMQP Type Java Value Type UM
message-id nHeader.MessageId AMQP String byte[] (tick)
user-id nHeader.UserId AMQP Binary byte[] (tick)
to nHeader.Destination AMQP String byte[] (tick)
subject nEventProperties.JMS_AMQP_SUBJECT AMQP String String (tick)
reply-to nHeader.ReplyToName AMQP String byte[] (tick)
correlation-id nHeader.CorrelationId AMQP Value byte[] (tick)
content-type nEventProperties.JMS_AMQP_CONTENT_TYPE AMQP Symbol String (tick)
content-encoding nEventProperties.JMS_AMQP_CONTENT_ENCODING AMQP Symbol String (tick)
absolute-expiry-time N/A (Currently unsupported) AMQP Date long (error)
creation-time nHeader.Timestamp AMQP Date long (tick)
group-id nEventProperties.JMSXGroupID AMQP String String (tick)
group-sequence nEventProperties.JMS_AMQP_GROUP_SEQUENCE AMQP uint int (tick)
reply-to-group-id nEventPropties.JMS_AMQP_ReplyToGroupID AMQP String String (tick)
Note: Only applies when using the Complete AMQP Transformer.

Application Message Properties

AMQP offers an optional application-properties section, part of the bare message used for structured application data. Intermediaries can use the data within this structure for the purposes of filtering or routing.

The keys of this map are restricted to be of type string (which excludes the possibility of a null key) and the values are restricted to be of simple types only, that is, excluding map, list, and array types. The following table illustrates how these are mapped to Universal Messaging:

AMQP Application Message Properties UM Dictionary Key AMQP Key/Value Type Java Key/Value Type UM
MAP < STRING, SIMPLE VALUE > AMQP String / AMQP Value String / nEventProperties Value (tick)
example_application_key1 example_application_key1 AMQP String / AMQP Value String / nEventProperties Value (tick)
Note: In Universal Messaging the nEventProperties and nHeader objects are mapped to a few AMQP message format sections. Therefore there will be property keys mappable to different sections stored in the same structure, implying that this section refers to all keys that do not fall in the other sections.

Message Body

The AMQP message body is defined in three ways:

  • One or more AMQP Data sections
  • One or more AMQP Sequence sections
  • A single AMQP Value section

Universal Messaging currently aims to offer support for JMS 1.1 use cases via AMQP and therefore has implemented some mappings via the Complete AMQP transformer.

The mappings are based on the following UM constants:

UM nHeader.MessageType UM Dictionary Key (transformed) Value (byte) UM
JMS_BASE_MESSAGE_TYPE AMQP_Type 0 (tick)
JMS_MAP_MESSAGE_TYPE AMQP_Type 1 (tick)
JMS_BYTES_MESSAGE_TYPE AMQP_Type 2 (tick)
JMS_OBJECT_MESSAGE_TYPE AMQP_Type 3 (tick)
JMS_STREAM_MESSAGE_TYPE AMQP_Type 4 (tick)
JMS_TEXT_MESSAGE_TYPE AMQP_Type 5 (tick)

Universal Messaging extended message types, such as protobuf, are not supported by the transformation framework.

Additionally, mappings (depending on the direction) are based on the following UM AMQP Transformation constants:

UM AMQP transformation Constant UM Dictionary Key (transformed) Value (int) UM
sAMQPData AMQP_Type 0 (tick)
sAMQPValue AMQP_Type 1 (tick)
sAMQPList AMQP_Type 2 (tick)
sAMQPEmpty AMQP_Type 3 (tick)
sAMQPUnknown AMQP_Type -1 (tick)

Message Body: AMQP payloads to UM Native payloads

Initially, the Universal Messaging realm will check for an AMQP message annotation x-opt-jms-msg-type on the AMQP message. If detected and within the range of the above mentioned table, then the following conversions are performed:

x-opt-jms-msg-type Message Annotation AMQP Body UM Stamping UM payload UM
JMS_BASE_MESSAGE_TYPE Any AMQP_Type=sAMQPEmpty byte[0] (tick)
JMS_BYTES_MESSAGE_TYPE null byte[0] (tick)
JMS_BYTES_MESSAGE_TYPE Data AMQP_Type=sAMQPData Binary.Array (tick)
JMS_BYTES_MESSAGE_TYPE AMQP Value <Binary> AMQP_Type=sAMQPValue Binary.Array (tick)
JMS_TEXT_MESSAGE_TYPE null byte[0] (tick)
JMS_TEXT_MESSAGE_TYPE Data AMQP_Type=sAMQPData Binary.Array (UTF-8) (tick)
JMS_TEXT_MESSAGE_TYPE AMQP Value <Binary> AMQP_Type=sAMQPValue Binary.Array (UTF-8) (tick)
JMS_OBJECT_MESSAGE_TYPE null AMQP_Type=sAMQPData byte[0] (tick)
JMS_OBJECT_MESSAGE_TYPE Data AMQP_Type=sAMQPData Binary.Array (tick)
JMS_STREAM_MESSAGE_TYPE null byte[0] (tick)
JMS_STREAM_MESSAGE_TYPE AMQP Value <List> AMQP_Type=sAMQPValue byte[](Serialized Vector<Binary>) (tick)
JMS_STREAM_MESSAGE_TYPE AMQP Sequence AMQP_Type=sAMQPList byte[](Serialized Vector<Binary>) (tick)
JMS_MAP_MESSAGE_TYPE null byte[0] (tick)
JMS_MAP_MESSAGE_TYPE AMQP Value <Map> AMQP_Type=sAMQPValue byte[](Externalized fEventDictionary) (tick)
Note: Only applies when using the Complete AMQP Transformer

If the message annotation is not present, then the mapping starts looking for payload hints in message properties as follows:

AMQP Message Property AMQP Body UM nHeader.MessageType UM payload UM
content-type
text/plain null JMS_TEXT_MESSAGE_TYPE byte[0] (tick)
application/x-java-serialized-object null JMS_OBJECT_MESSAGE_TYPE byte[0] (tick)
application/octet-stream null JMS_BYTES_MESSAGE_TYPE byte[0] (tick)
null or other null JMS_BASE_MESSAGE_TYPE byte[0] (tick)
text/plain Data JMS_TEXT_MESSAGE_TYPE Binary.Array(UTF-8) (tick)
application/x-java-serialized-object Data JMS_OBJECT_MESSAGE_TYPE Binary.Array (tick)
application/octet-stream or null Data JMS_BYTES_MESSAGE_TYPE Binary.Array (tick)
other Data JMS_BYTES_MESSAGE_TYPE Binary.Array (tick)
AMQP Value <Type> body
null AMQP Value <null> JMS_BASE_MESSAGE_TYPE byte[0] (tick)
String AMQP Value <String> JMS_TEXT_MESSAGE_TYPE Binary.Array (UTF-8) (tick)
Binary AMQP Value <Binary> JMS_BYTES_MESSAGE_TYPE Binary.Array (tick)
List AMQP Value <List> JMS_STREAM_MESSAGE_TYPE byte[](Serialized Vector<Binary>) (tick)
Map AMQP Value <Map> JMS_MAP_MESSAGE_TYPE byte[](Externalized fEventDictionary) (tick)
other AMQP Value <Object> JMS_OBJECT_MESSAGE_TYPE Binary.Array (tick)
AMQP Sequence <Object> body
Binary AMQP Sequence<Binary> JMS_OBJECT_MESSAGE_TYPE Binary.Array (tick)
Note: Only applies when using the Complete AMQP Transformer.

Message Body: UM Native Payloads to AMQP payloads

Initially, the Universal Messaging realm will check for an nEventProperties keys called AMQP_Type which is expected to be within the range defined by the AMQP Transformation Constants table. Typically these are AMQP messages previously transformed to native but as there are multiple possibilities with regard to the type of payload this should be transformed to, this value gives us a hint. If not present, it defaults to sAMQPUnknown.

Based on the UM nHeader.MessageType values the following conversions are performed:

UM nHeader.MessageType UM Dictionary Key AMQP_Type AMQP Payload UM
JMS_BASE_MESSAGE_TYPE sAMQPEmpty or sAMQPUnknown or sAMQPData Data(byte[0]) (tick)
JMS_BASE_MESSAGE_TYPE sAMQPValue AMQPValue(null) (tick)
JMS_BASE_MESSAGE_TYPE sAMQPList (error)
JMS_MAP_MESSAGE_TYPE sAMQPEmpty Data(byte[0]) (tick)
JMS_MAP_MESSAGE_TYPE sAMQPValue or sAMQPUnknown AMQPValue<Map> (from byte[](Externalized fEventDictionary) (tick)
JMS_MAP_MESSAGE_TYPE sAMQPList or sAMQPData (error)
JMS_BYTES_MESSAGE_TYPE sAMQPEmpty Data(byte[0]) (tick)
JMS_BYTES_MESSAGE_TYPE sAMQPData orsAMQPUnknown Data(Binary(byte[])) (from UM native payload) (tick)
JMS_BYTES_MESSAGE_TYPE sAMQPValue AMQPValue(Binary(byte[])) (from UM native payload) (tick)
JMS_BYTES_MESSAGE_TYPE sAMQPList (error)
JMS_OBJECT_MESSAGE_TYPE sAMQPEmpty Data(byte[0]) (tick)
JMS_OBJECT_MESSAGE_TYPE sAMQPData orsAMQPUnknown Data(Binary(byte[])) (from UM native payload) (tick)
JMS_OBJECT_MESSAGE_TYPE sAMQPList or sAMQPValue (error)
JMS_STREAM_MESSAGE_TYPE sAMQPEmpty Data(byte[0]) (tick)
JMS_STREAM_MESSAGE_TYPE sAMQPList AMQPSequence<Vector> (byte[](Serialized Vector<Binary>) (tick)
JMS_STREAM_MESSAGE_TYPE sAMQPValue or sAMQPUnknown AMQPValue<Vector> (byte[](Serialized Vector<Binary>) (tick)
JMS_STREAM_MESSAGE_TYPE sAMQPData (error)
JMS_TEXT_MESSAGE_TYPE sAMQPEmpty Data(byte[0]) (tick)
JMS_TEXT_MESSAGE_TYPE sAMQPData Data(Binary(byte[])) (from UM native payload) (tick)
JMS_TEXT_MESSAGE_TYPE sAMQPValue orsAMQPUnknown AMQPValue<String> (from UM native payload) (tick)
JMS_TEXT_MESSAGE_TYPE sAMQPList (error)
Note: Only applies when using the Complete AMQP Transformer.

Message Footer

AMQP Message footer offers an optional non-normative section for delivery or message metadata that can be calculated / validated only after the whole message has been processed (e.g digital signature verification, encryption etc).

The following table shows how these are mapped in Universal Messaging:

AMQP Message Footer UM Sub Dictionary Key AMQP Key/Value Type Java Key/Value Type UM
MAP < SYMBOL, VALUE > Footer AMQP Symbol / AMQP Value String / nEventProperties Value (tick)
example_footer_key1 Footer.example_footer_key1 AMQP Symbol / AMQP Value String / nEventProperties Value (tick)
Note: Only applies when using the Complete AMQP Transformer.