2.11. Maps in Message Content

Many messaging applications need to exchange data across languages and platforms, using the native datatypes of each programming language.

The Qpid Messaging API supports maps in message content. [8] These maps are supported in each language using the conventions of the language. In Java, we implement the MapMessage interface [9] ; in Python, we support dict and list in message content; in C++, we provide the Variant::Map and Variant::List classes to represent maps and lists. In all languages, messages are encoded using AMQP's portable datatypes.

Tip

Because of the differences in type systems among languages, the simplest way to provide portable messages is to rely on maps, lists, strings, 64 bit signed integers, and doubles for messages that need to be exchanged across languages and platforms.

2.11.1. Qpid Maps in Python

In Python, Qpid supports the dict and list types directly in message content. The following code shows how to send these structures in a message:

Example 2.15. Sending Qpid Maps in Python

from qpid.messaging import *
# !!! SNIP !!!

content = {'Id' : 987654321, 'name' : 'Widget', 'percent' : 0.99}
content['colours'] = ['red', 'green', 'white']
content['dimensions'] = {'length' : 10.2, 'width' : 5.1,'depth' : 2.0};
content['parts'] = [ [1,2,5], [8,2,5] ]
content['specs'] = {'colors' : content['colours'], 
                    'dimensions' : content['dimensions'], 
                    'parts' : content['parts'] }
message = Message(content=content)
sender.send(message)
       

The following table shows the datatypes that can be sent in a Python map message, and the corresponding datatypes that will be received by clients in Java or C++.

Table 2.5. Python Datatypes in Maps

Python Datatype→ C++→ Java
boolboolboolean
intint64long
longint64long
floatdoubledouble
unicodestringjava.lang.String
uuidqpid::types::Uuidjava.util.UUID
dictVariant::Mapjava.util.Map
listVariant::Listjava.util.List

2.11.2. Qpid Maps in C++

In C++, Qpid defines the the Variant::Map and Variant::List types, which can be encoded into message content. The following code shows how to send these structures in a message:

Example 2.16. Sending Qpid Maps in C++

using namespace qpid::types;

// !!! SNIP !!!

Message message;
Variant::Map content;
content["id"] = 987654321;
content["name"] = "Widget";
content["percent"] = 0.99;
Variant::List colours;
colours.push_back(Variant("red"));
colours.push_back(Variant("green"));
colours.push_back(Variant("white"));
content["colours"] = colours;

Variant::Map dimensions;
dimensions["length"] = 10.2;
dimensions["width"] = 5.1;
dimensions["depth"] = 2.0;
content["dimensions"]= dimensions; 

Variant::List part1;
part1.push_back(Variant(1));
part1.push_back(Variant(2));
part1.push_back(Variant(5));
 
Variant::List part2;
part2.push_back(Variant(8));
part2.push_back(Variant(2));
part2.push_back(Variant(5));
 
Variant::List parts;
parts.push_back(part1);
parts.push_back(part2);
content["parts"]= parts; 

Variant::Map specs;
specs["colours"] = colours; 
specs["dimensions"] = dimensions; 
specs["parts"] = parts; 
content["specs"] = specs;

encode(content, message);
sender.send(message, true);
     

The following table shows the datatypes that can be sent in a C++ map message, and the corresponding datatypes that will be received by clients in Java and Python.

Table 2.6. C++ Datatypes in Maps

C++ Datatype→ Python→ Java
boolboolboolean
uint16int | longshort
uint32int | longint
uint64int | longlong
int16int | longshort
int32int | longint
int64int | longlong
floatfloatfloat
doublefloatdouble
stringunicodejava.lang.String
qpid::types::Uuiduuidjava.util.UUID
Variant::Mapdictjava.util.Map
Variant::Listlistjava.util.List

2.11.3. Qpid Maps in .NET

The .NET binding for the Qpid Messaging API binds .NET managed data types to C++ Variant data types. The following code shows how to send Map and List structures in a message:

Example 2.17. Sending Qpid Maps in .NET C#

using System;
using Org.Apache.Qpid.Messaging;

// !!! SNIP !!!

Dictionary<string, object> content = new Dictionary<string, object>();
Dictionary<string, object> subMap = new Dictionary<string, object>();
Collection<object> colors = new Collection<object>();

// add simple types
content["id"] = 987654321;
content["name"] = "Widget";
content["percent"] = 0.99;

// add nested amqp/map
subMap["name"] = "Smith";
subMap["number"] = 354;
content["nestedMap"] = subMap;

// add an amqp/list
colors.Add("red");
colors.Add("green");
colors.Add("white");
content["colorsList"] = colors;

// add one of each supported amqp data type
bool mybool = true;
content["mybool"] = mybool;

byte mybyte = 4;
content["mybyte"] = mybyte;

UInt16 myUInt16 = 5;
content["myUInt16"] = myUInt16;

UInt32 myUInt32 = 6;
content["myUInt32"] = myUInt32;

UInt64 myUInt64 = 7;
content["myUInt64"] = myUInt64;

char mychar = 'h';
content["mychar"] = mychar;

Int16 myInt16 = 9;
content["myInt16"] = myInt16;

Int32 myInt32 = 10;
content["myInt32"] = myInt32;

Int64 myInt64 = 11;
content["myInt64"] = myInt64;

Single mySingle = (Single)12.12;
content["mySingle"] = mySingle;

Double myDouble = 13.13;
content["myDouble"] = myDouble;

Guid myGuid = new Guid("000102030405060708090a0b0c0d0e0f");
content["myGuid"] = myGuid;

Message message = new Message(content);
Send(message, true);
     

The following table shows the mapping between datatypes in .NET and C++.

Table 2.7. Datatype Mapping between C++ and .NET binding

C++ Datatype→ .NET binding
voidnullptr
boolbool
uint8byte
uint16UInt16
uint32UInt32
uint64UInt64
uint8char
int16Int16
int32Int32
int64Int64
floatSingle
doubleDouble
stringstring (1)
qpid::types::UuidGuid
Variant::MapDictionary<string, object> (2)
Variant::ListCollection<object> (3)

(1)

Strings are currently interpreted only with UTF-8 encoding.



[8] Unlike JMS, there is not a specific message type for map messages.

[9] Note that the Qpid JMS client supports MapMessages whose values can be nested maps or lists. This is not standard JMS behaviour.