3. Your First AMPS Program

In this chapter, we will learn more about the structure and features of the AMPS Java client library, and build our first Java program using AMPS.

About the Client Library

The AMPS client is packaged as a single JAR file, amps_client.jar. You can find amps_client.jar in the dist/lib directory of the AMPS Java client installation. Every Java application you build will need to reference this JAR file, and the JAR file must be deployed along with your application in order for your application to function properly.

Connecting to AMPS

Let’s begin by writing a simple program that connects to an AMPS server and sends a single message to a topic:

import com.crankuptheamps.client.Client;
import com.crankuptheamps.client.exception.AMPSException;

public class TestPublisher
{
    public static void main(String[] args) {
        Client client = new Client("TestPublisher-Client");
        try {
            client.connect("tcp://127.0.0.1:9007/amps/json");
            client.logon();
            client.publish("messages", "{ \"message\" : \"Hello, world!\" } ");
        }
        catch (AMPSException aex) {
            System.err.println("TestListener caught exception.");
        } finally {
            client.close();
        }
    }
}

Example 3.1: Connecting to AMPS

In the preceding Example 3.1, we show the entire program; but future examples will isolate one or more specific portions of the code. The next section describes how to build and run the application and explains the code in further detail.

Build and Run with a Java Command Line

To build this program, you can run the following javac command, substituting the path to the amps_client.jar with the path where you have installed the AMPS Java Client:

javac -classpath /opt/AMPS/api/client/java/dist/lib/amps_client.jar ./TestPublisher.java

TestPublisher.class This will create the TestPublisher.class file. To run the class file and send your first message to AMPS, you can issue the following command:

java -cp .:/opt/AMPS/api/client/java/dist/lib/amps_client.jar TestPublisher

If the message is published successfully, there is no output to the console. We will demonstrate how to create a subscriber to receive messages in ` <#java-subscriptions-chapter>`_.

Build and Run in Eclipse

To include the JAR file in a standalone Eclipse environment:

  1. JAR files amps_client.jar amps_client.jar Right-click the project to which you would like to add amps_client.jar and select Properties to open the Properties configuration window.
  2. Click the Java Build Path item in the left menu, and then select the Libraries tab.
  3. Click the Add External JARS button and choose the location of your amps_client.jar.
  4. Click OK.

Your Eclipse build path should now include the amps_client.jar.

To run the project:

  1. Select the menu option Run #  Run Configuration, which opens the Run Configuration window.
  2. Right-click Java Application and select New from the menu.
  3. Fill in the Name field (for this example, you could use “Test Publisher”).
  4. Click the Search... button for the Main class field.
  5. Select the TestPublisher class.
  6. Finally, click the Run button to run the application.

If the message is published successfully, there is no output to the console. We will demonstrate how to create a subscriber to receive messages in Chapter 4.

Examining the Code

Let us now revisit the code we listed earlier.

/* The import statements add names into reference for convenience in typing later
 * on in the code. These import the names from the AMPS namespaces:
 *       com.crankuptheamps.client.Client — contains the
 *              methods for interacting with AMPS
 *       com.crankuptheamps.client.exception.AMPSException — the
 *              package contains the exception classes thrown by AMPS when
 *              errors occur.
 */
import com.crankuptheamps.client.Client;
import com.crankuptheamps.client.exception.AMPSException;

public class TestPublisher
{
    public static void main(String[] args) {

        /* This line creates a new Client object. Client encapsulates a single
         * connection to an AMPS server. Methods on Client allow for connecting,
         * disconnecting, publishing, and subscribing to an AMPS server. The
         * argument to the Client constructor, "TestPublisher-Client", is a name
         * chosen by the client to identify itself to the server. Errors
         * relating to this connection will be logged with reference to this
         * name, and AMPS will use this name to help detect duplicate messages.
         * AMPS enforces uniqueness for client names when a transaction log is
         * configured, and it is good practice to always use unique client names.
         */

        Client client = new Client("TestPublisher-Client");

        // Here, we open a try block that concludes with catch (AMPSException aex).
        try
        {
            /* This statement declares a connection to AMPS with the provided
             * URI. The URI consists of the transport, the address, and the
             * protocol to use for the AMPS connection. In this case, the
             * transport is tcp, the address is 127.0.0.1:9007, and the protocol
             * is amps. This connection will be used for JSON messages. Check
             * with the person who manages the AMPS instance to get the connection
             * string to use for your programs.
            */
            client.connect("tcp://127.0.0.1:9007/amps/json");

            /* The AMPS logon() command connects to AMPS and creates a named
             * connection. If we had provided logon credentials in the URI, the
             * command would pass those credentials to AMPS. Without credentials,
             * the client logs on to AMPS anonymously. AMPS versions 5.0 and
             * later require a logon() command in the default configuration.
             */
            client.logon();
            client.publish("messages", "{ \"message\" : \"Hello, world!\" } ");
        }

        // All caught exceptions in AMPS derive from AMPSException.
        catch (AMPSException aex)
        {
            System.err.println("TestListener caught exception.");

        }
        /* We close out the example with a finally block that closes the
         * Client connection and releases all accompanying resources, making
         * the connection eligible for garbage collection.
         */
        finally
        {
            client.close();
        }
    }
}

Client Names

AMPS uses the name of the client as a session identifier and as part of the identifier for a message. For this reason, when a transaction log is enabled in the AMPS instance (that is, when the instance is recording a sequence of publishes and attempting to eliminate duplicate publishes), an AMPS instance will only allow one application with a given client name to connect to the instance.

When a transaction log is present, AMPS requires the Client Name for a publisher to be:

  • Unique within a set of replicated AMPS instances
  • Consistent from invocation to invocation if the publisher will be publishing the same logical stream of messages

60East recommends always using consistent, unique client names. For example, the client name could be formed by combining the application name, an identifier for the host system, and the id of the user running the application. A strategy like this provides a name that will be different for different users or on different systems, but consistent for instances of the application that should be treated as equivalent to the AMPS system.

Connection Strings

The AMPS clients use connection strings to determine the server, port, transport, and protocol to use to connect to AMPS. When the connection point in AMPS accepts multiple message types, the connection string also specifies the precise message type to use for this connection. Connection strings have a number of elements.

elements of a connection string

Figure 3.1: elements of a connection string

As shown in the figure above, connection strings have the following elements:

  • Transport defines the network used to send and receive messages from AMPS. In this case, the transport is tcp. For connections to transports that use the Secure Sockets Layer (SSL), use tcps.

  • Host address defines the destination on the network where the AMPS instance receives messages. The format of the address is dependent on the transport. For tcp and tcps, the address consists of a host name and port number. In this case, the host address is localhost:9007.

  • Protocol sets the format in which AMPS receives commands from the client. Most code uses the default amps protocol, which sends header information in JSON format. AMPS supports the ability to develop custom protocols as extension modules, and AMPS also supports legacy protocols for backward compatibility.

  • MessageType specifies the message type that this connection uses. This component of the connection string is required if the protocol accepts multiple message types and the transport is configured to accept multiple message types. If the protocol does not accept multiple message types, this component of the connection string is optional, and defaults to the message type specified in the transport.

    Legacy protocols such as fix, nvfix and xml only accept a single message type, and therefore do not require or accept a message type in the connection string.

As an example, a connection string such as

tcp://localhost:9007/amps/json

would work for programs connecting from the local host to a Transport configured as follows:

<AMPSConfig>
    ...

    <!-- This transport accepts any known message type for the instance: the
         client must specify the message type. -->
    <Transport>
        <Name>any-tcp</Name>
        <Type>tcp</Type>
        <InetAddr>9007</InetAddr>
        <Protocol>amps</Protocol>
    </Transport>

    ...
</AMPSConfig>

See the AMPS Configuration Guide for more information on configuring transports.

Providing Credentials in a Connection String

When using the default authenticator, the AMPS clients support the standard format for including a username and password in a URI, as shown below:

tcp://user:password@host:port/protocol/message_type

When provided in this form, the default authenticator provides the username and password specified in the URI. If you have implemented another authenticator, that authenticator controls how passwords are provided to the AMPS server.

Connection Parameters

When specifying a URI for connection to an AMPS server, you may specify a number of transport-specific options in the parameters section of the URIconnection parameters. Here is an example:

tcp://localhost:9007/amps/json?tcp_nodelay=true&tcp_sndbuf=100000

In this example, we have specified the AMPS instance on localhost, port 9007, connecting to a transport that uses the amps protocol and sending JSON messages. We have also set two parameters, tcp_nodelay tcp_nodelay, a Boolean (true/false) parameter, and tcp_sndbuf tcp_sndbuf, an integer parameter. Multiple parameters may be combined to finely tune settings available on the transport. Normally, you’ll want to stick with the defaults on your platform, but there may be some cases where experimentation and fine-tuning will yield higher or more efficient performance.

AMPS supports the value of tcp in the connection string for TCP/IP connections, and the value of tcps in the connection string for SSL encrypted connections.

Transport options

The following transport options are available for TCP connections:

bind (ip address) Sets the interface to bind the outgoing socket to.
tcp_rcvbuf (integer) Sets the socket receive buffer size. This defaults to the system default size. (On Linux, you can find the system default size in /proc/sys/net/core/rmem_default.)
tcp_sndbuf (integer) Sets the socket send buffer size. This defaults to the system default size. (On Linux, you can find the system default size in /proc/sys/net/core/wmem_default.)
tcp_nodelay (boolean) Enables or disables the TCP_NODELAY setting on the socket. By default TCP_NODELAY is disabled.
tcp_linger (integer) Enables and sets the SO_LINGER value for the socket. By default, SO_LINGER is enabled with a value of 10, which specifies that the socket will linger for 10 seconds.
tcp_keepalive (boolean) . Enables or disables the SO_KEEPALIVE value for the socket. The default value for this option is true.

AMPS additional logon options

The connection string can also be used to pass logon parameters to AMPS. AMPS supports the following additional logon option:

pretty Provide formatted representations of binary messages rather than the original message contents.

Next Steps

You are now able to develop and deploy an application in Java that publishes messages to AMPS. In the following chapters, you will learn how to subscribe to messages, use content filters, work with SOW caches, and fine-tune messages that you send.