TANA Communication Protocol

TANA protocol is a simple message based communication convention for sending and receiving data via TCP network. Inside source code any received TANA messages are ordinary hashes with key-value pairs. For Java programs it means that any TANA message appears as Map<String, byte[]> interface. Program can send any hash as TANA message and client on the other side will receive the same hash.

Installation and system requirements

Download and unpack the latest distribution of the TANA package. You need Java Runtime Environment (jre) 1.5 or higher installed and configured in your system (tested on Windows and Linux).

User manual

There is a TanaSend.jar utility in the package distribution. It can serve you as a simple program to send and receive messages via network.
Open you command line shell and cd to the directory where the TanaSend.jar file is located. There are three ways you can use it:

  1. Send a simple message to some TANA server (to start a server see case 3):

      shell> java -jar TanaSend.jar 12345 cmd:start msg:"Start message"

    This way you will send a message with two key-value pairs to a server on localhost:12345.
    To send a message to some other host use this format of the command:

      shell> java -jar TanaSend.jar some_host:12345 cmd:start msg:"Start message"

  2. Send a message that has been stored in a file to a TANA server:

      shell> java -jar TanaSend.jar 12345 -f msg_filename

    This command is an equivalent to the previous one except that the message itself was saved in a file beforehand.
    To save a message into a file, start an echo server (see case 3) and do something like this:

      shell> java -jar TanaSend.jar some_host:12345 cmd:start msg:"Start message" > msg_filename

  3. Bind a simple echo TANA server:

      shell> java -jar TanaSend.jar 12345 -echoserver

    This will start a TANA echo server. This server will mirror all incoming messages back to the sender.

TANA message definition

Structure of a TANA message is simple. Formally, we can define it this way:
TANA_MESSAGE := HEADER\nBODY
HEADER := fix number_of_pairs
BODY := PAIR*
PAIR := key_length key: value_length value\n
Here '\n' denotes a new line, number_of_pairs is a positive number of key-value pairs in the message body. key_length and value_length are lengths in bytes of the corresponded key and value. Finally, a key and a value are just any sequence of bytes you want to send.
Following this definition, a sample TANA message is: “
fix 1\n3 cmd: 5 start\n”. It will appear in a server side as a hash with one entry with “cmd” string as a key and “start” as a value.

Developer manual

Source code is located in the package distribution. Here I will give you instructions how to create a TANA server and send/receive message inside your Java source code.

Let us start with a simple echo server:

public class EchoServer
{
  private int port;
  private EchoServerHandler echoServerHandler;
  private TanaServer tanaServer;
  private static final Log logger = LogFactory.getLog(EchoServer.class);

  public EchoServer(int port, boolean verbose) {
    this.port = port;
    echoServerHandler = new EchoServerHandler();
    tanaServer = new TanaServer(this.port, echoServerHandler, verbose); // 3.
  }

  public void shutdown() throws IOException {
    tanaServer.shutdown();
  }

  public void start() {
    tanaServer.start();
  }
// 1. Implement your EchoServerHandler
  private static class EchoServerHandler extends DefaultServerHandler {
    EchoServerHandler() {
      super(logger, "Echo");
    }

    public Map<String, byte[]> handleClientMsg(Map<String, byte[]> clientMsg)
    {
      // 2. echo reply
      return clientMsg;
    }
  }

  public static void main(String[] args) {
    EchoServer echoServer = new EchoServer(12345, true); // 4. Allocate
    echoServer.start(); // 5. Start an echo server
  }
}

Creating a new TANA server is easy. First, you need to write you own server handler (1). EchoServerHandler in our case just sends all received messages back to the client without any additional preprocessings (2). If you need more control over the TanaServer you should consider implementation of ServerHandler interface by your own instead of extending its default implementation DefaultServerHandler. Next, allocate a new instance of TanaServer (3) and wrap its start() and shutdown() methods. Now our echo server is ready to be created (4) and started (5). Note also that TanaServer processes each connected client in a separate thread class ClientHandleThread. Therefore, several clients can access the same instance of the server simultaneously.

These are ways to send TANA messages to a server:

// 1. allocate a new client with host and port of a server
TanaSend tanaSend = new TanaSend("localhost"12345);

// 2. send several TANA messages as a byte stream
tanaSend.send("fix 1\n1 a: 1 b\nfix 0\n2 xx: 3 abc\n".getBytes());

// 3. send a TANA message as map
Map<String, byte[]> map = new HashMap<String, byte[]>();
map.put(“a”, “b”.getBytes());
tanaSend.send(map);

// 4. send a TANA message as TanaMessage instance
TanaMessage tanaMessage = new TanaMessage(TanaMessageType.FIX, map);
tanaSend.send(tanaMessage);

// 5. receive a TANA message 
Map<String,byte[]> recMap = tanaSend.receive();

// 6. send and receive a TANA message
Map<String,byte[]> recMap2 = tanaSend.sendAndReceiveMap(map);

As you can read from comments, TanaSend class can send TANA messages in three formats: as byte stream (1), as map (2) or as instance of TanaMessage class (3). To receive a reply from the server just call receive() method. To combine send and receive operations in one use sendAndReceiveMap() method (6). It will send and then receive a reply from the server.

Other implementations

There is a Perl implementation of this protocol. Check Alvis::Saa and Alvis::Tana Perl modules on ALVIS project home page http://www.alvis.info/alvis/Software?action=show&redirect=software
You may also install this module via CPAN network:
shell> sudo perl -MCPAN -e "install Alvis::Saa"

License

Copyright (c) 2005 by Vladimir Poroshin. All Rights Reserved.

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.