11. Utilities

The AMPS Java client includes a set of utilities and helper classes to make working with AMPS easier.

Composite Message Types

The client provides a pair of classes for creating and parsing composite message types.

  • CompositeMessageBuilder allows you to assemble the parts of a composite message and then serialize them in a format suitable for AMPS.
  • CompositeMessageParser extracts the individual parts of a composite message type

For more information regarding composite message types, refer to Chapter 4.3.

Building Composite Messages

To build a composite message, create an instance of CompositeMessageBuilder, and populate the parts. The CompositeMessageBuilder copies the parts provided, in order, to the underlying message. The builder simply writes to an internal buffer with the appropriate formatting, and does not allow you to update or change the individual parts of a message once they’ve been added to the builder.

The snippet below shows how to build a composite message that includes a JSON part, constructed as a string, and a binary part consisting of the bytes from an ArrayList.

StringBuilder sb = new StringBuilder();
sb.append("{\"data\":\"sample\"}");

List<Double> theData = new ArrayList<Double>();
// populate theData
...

// Create a byte array from the data: this is
// what the program will send.
ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
ObjectOutputStream listWriter = new ObjectOutputStream(outBytes);
listWriter.writeObject(theData);


// Create the payload for the composite message.
CompositeMessageBuilder builder;

// Construct the composite
CompositeMessageBuilder builder = new CompositeMessageBuilder();
builder.append(sb.toString());
builder.append(outBytes.toByteArray(), 0, outBytes.size());

// send the message
String topic = "messages";

Field outMessage = new Field();
builder.setField(outMessage);
client.publish(topic.getBytes(), 0, topic.getBytes().length, outMessage.buffer, 0, outMessage.length);

Parsing Composite Messages

To parse a composite message, create an instance of CompositeMessageParser, then use the parse() method to parse the message provided by the AMPS client. The CompositeMessageParser gives you access to each part of the message as a sequence of bytes.

For example, the following snippet parses and prints messages that contain a JSON part and a binary part that contains an array of doubles.

try (MessageStream stream = client.subscribe("messages")) {
    for (Message message : stream) {
        int parts = parser.parse(message);
        String json = parser.getString(0);
        Field binary = new Field();
        parser.getField(1, binary);

        ByteArrayInputStream inBytes =
            new ByteArrayInputStream(binary.buffer, binary.position, binary.length);
        ObjectInputStream listReader =
            new ObjectInputStream(inBytes);
        List<Double> theData = (List<Double>)listReader.readObject();

        System.out.println("Received message with " + parts + " parts.");
        System.out.println(json);
        for (Double d : theData) {
            System.out.print(d + " ");
        }
        System.out.print("\n");
    }
}

Notice that the receiving application is written with explicit knowledge of the structure and content of the composite message type.

NVFIX Messages

The client provides a pair of classes for creating and parsing NVFIX messages.

  • NVFIXBuilder allows you to assemble a NVFIX message and then serialize it in a format suitable for AMPS.
  • NVFIXShredder extracts the individual fields of a NVFIX message.

Building NVFIX Messages

To build a NVFIX message, create an instance of NVFIXBuilder, then add the fields of the message using append(). NVFIXBuilder copies the fields provided, in order, to the underlying message. The builder simply writes to an internal buffer with the appropriate formatting, and does not allow you to update or change the individual fields of a message once they’ve been added to the builder.

The snippet below shows how to build an NVFIX message and publish it to the AMPS client.

// Build the message payload

// Create a builder with 1024 bytes of initial capacity,
// using the default 0x01 delimiter.
NVFIXBuilder builder = new NVFIXBuilder(1024, (byte)1);

// Add fields
builder.append("test-field", "24");
builder.append("another", "Here's another field");
builder.append("data", "1234567890");

// Create a string for the topic
String topic = "test-topic";

client.connect(uri_);
System.out.println("connected..");
client.logon();

// publish the message, using the overload that takes a byte array and
// length for the topic and payload.

client.publish(topic.getBytes(), 0, topic.length(), builder.getBytes(), 0, builder.getSize());

Parsing NVFIX Messages

To parse a NVFIX message, create an instance of NVFIXShredder, then use the toNVMap() method to parse the message provided by the AMPS client. The NVFIXShredder gives you access to each field of the message in a map.

The snippet below shows how to parse and print an NVFIX message.

Client client = new Client("ConsoleSubscriber");

try {
    // connect to the AMPS server and logon
    client.connect(uri_);

    // subscribe to the test-topic topic.
    // when a message arrives, print the message.

    MessageStream ms = client.subscribe("test-topic");
    try {
        // Create a shredder -- since this just returns
        // the Map, we can reuse the same shredder.
        NVFIXShredder shredder = new NVFIXShredder((byte)1);

        for (Message m : ms) {
            // Skip messages with no data.
            if (m.getCommand() != Message.Command.SOW && m.getCommand() != Message.Command.Publish) continue;

            System.out.println("Got a message");

            // Shred the message into a Map
            Map<CharSequence,CharSequence> fields = shredder.toNVMap(m.getData());

            // Iterate over the keys in the map and print the key and data
            for (CharSequence key : fields.keySet()) {
                System.out.println("  " +key + "=" + fields.get(key));
            }
        }
    }
    finally  {  // close the message stream to release the subscription
        ms.close();
    }
}

FIX Messages

The client provides a pair of classes for creating and parsing FIX messages.

  • FIXBuilder allows you to assemble a FIX message and then serialize it in a format suitable for AMPS.
  • FIXShredder extracts the individual fields of a FIX message.

Building FIX Messages

To build a FIX message, create an instance of FIXBuilder, then add the fields of the message using append(). FIXBuilder copies the fields provided, in order, to the underlying message. The builder simply writes to an internal buffer with the appropriate formatting, and does not allow you to update or change the individual fields of a message once they’ve been added to the builder.

The snippet below shows how to build a FIX message and publish it to the AMPS client.

// Build the message payload

// Create a builder with 1024 bytes of initial capacity,
// using the default 0x01 delimiter.
FIXBuilder builder = new FIXBuilder(1024, (byte)1);

// Add fields
builder.append("test-field", "24");
builder.append("another", "Here's another field");
builder.append("data", "1234567890");

// Create a string for the topic
String topic = "test-topic";

client.connect(uri_);
System.out.println("connected..");
client.logon();

// publish the message, using the overload that takes a byte array and
// length for the topic and payload.

client.publish(topic.getBytes(), 0, topic.length(), builder.getBytes(), 0, builder.getSize());

Parsing FIX Messages

To parse a FIX message, create an instance of FIXShredder, then use the toMap() method to parse the message provided by the AMPS client. The FIXShredder gives you access to each field of the message in a map.

The snippet below shows how to parse and print a FIX message.

Client client = new Client("ConsoleSubscriber");

try {
    // connect to the AMPS server and logon
    client.connect(uri_);

    // subscribe to the test-topic topic.
    // when a message arrives, print the message.

    MessageStream ms = client.subscribe("test-topic");
    try {
        // Create a shredder -- since this just returns
        // the Map, we can reuse the same shredder.
        FIXShredder shredder = new FIXShredder((byte)1);

        for (Message m : ms) {
            // Skip messages with no data.
            if (m.getCommand() != Message.Command.SOW && m.getCommand() != Message.Command.Publish) continue;

            System.out.println("Got a message");

            // Shred the message into a Map
            Map<Integer,CharSequence> fields = shredder.toMap(m.getData());

            // Iterate over the keys in the map and print the key and data
            for (Integer key : fields.keySet()) {
                System.out.println("  " +key + "=" + fields.get(key));
            }
        }
    }
}