Search Results

TIBCO FTL® Java Quick Start

Contents

Getting Started

This quick start guide provides basic instructions for writing TIBCO FTL applications in Java for TIBCO Cloud Messaging.

Follow the steps below to use the sample applications:

Building and running samples

Follow the steps below to build and run the Java samples:

  • Unzip ftl-java-samples.zip
  • Change directories into ftl-java-samples/
  • Build project: gradle -DTIBCO_HOME=/opt/tibco build
  • Use -f option to specify the tcm-config.yaml.
  • Run sample: gradle -DTIBCO_HOME=/opt/tibco FtlProducer:run --args="-f <full-path-to>/tcm-config.yaml"

Description of sample applications

Producer

The producer demonstrates connecting an FTL Java application to Cloud Messaging and publishing FTL messages:

usage: FtlProducer [-c <count>] [-f <config-file>] [-h] [-i <interval>] [-id <client-id>] [-t <timeout>]
 -c,--count <count>          the number of messages to send before exiting
 -f,--config <config-file>   the path to a configuration yaml
 -h,--help                   this usage
 -i,--interval <interval>    the interval between sends (milliseconds)
 -id <client-id>             client identifier
 -t,--timeout <timeout>      the duration before exiting (seconds)

Consumer

The consumer demonstrates connecting an FTL Java application to Cloud Messaging, creating a subscription, and receiving FTL messages:

usage: FtlConsumer [-c <count>] [-durable <durable-name>] [-f <config-file>] [-h] [-id <client-id>] [-t <timeout>]
 -c,--count <count>          the number of messages to receive before exiting
 -durable <durable-name>     durable name
 -f,--config <config-file>   the path to a configuration yaml
 -h,--help                   this usage
 -id <client-id>             client identifier
 -t,--timeout <timeout>      the duration before exiting (seconds)

Run the consumer and producer at the same time to demonstrate real-time messaging. Stop the consumer, run the producer, and restart the consumer to demonstrate persistence.

Connecting to TIBCO Cloud Messaging

The client configuration file contains all the information client applications need to securely connect to TIBCO Cloud Messaging. Generate the client configuration file using the roles REST API or user interface. Generate as many configuration files as needed for each Role.

Note: TIBCO Cloud Messaging samples require a client configuration file to run.

TIBCO FTL Server Validation

TIBCO FTL applications cannot use their host’s certificate pool to automatically validate TIBCO Cloud Messaging servers. For server verification to work, TIBCO FTL applications must supply the value of ftl_certificate as the server certificate when connecting to TIBCO Cloud Messaging. The value of ftl_certificate can be found in the configuration file.

Connection Example

TibProperties props = FTL.createProperties();

props.set(Realm.PROPERTY_STRING_CLIENT_LABEL, "tcmdemopub.java");
props.set(Realm.PROPERTY_STRING_USERNAME, options.get("tcm_authentication_id"));
props.set(Realm.PROPERTY_STRING_USERPASSWORD, options.get("tcm_authentication_key"));
props.set(Realm.PROPERTY_LONG_TRUST_TYPE, Realm.HTTPS_CONNECTION_USE_SPECIFIED_TRUST_STRING);

String ftlCert = options.get("ftl_certificate");
ftlCert = ftlCert.replace("\\n", "\n");
props.set(Realm.PROPERTY_STRING_TRUST_PEM_STRING, ftlCert);

Realm realm = FTL.connectToRealmServer(options.get("ftl_url"), options.get("ftl_application"), props);

Publishing a message

Before a message can be published, the publisher must be created on the previously-created realm. Specify the endpoint onto which the messages will be published. In this example we are using the “default” endpoint.

Publisher pub = null;
pub = realm.createPublisher("default");

In order to send a message, the message object must first be created via a call to realm.CreateMessage. Specify the format name. Here the format “demo_tcm” is used. TCM only supports dynamic formats.

msg = realm.createMessage("demo_tcm");

A newly-created message is empty - it contains no fields. The next step is to add one or more fields to the message. msg.SetString adds a string field. In this example a string field named “demo_tcm” is added, with the value “message seq”.

msg.setString("demo_tcm", "message " + seq);

Once the message is complete, it can be sent via pub.Send. Specify the message to be sent.

pub.send(msg);

Subscribing and receiving messages

For messages to be delivered to a client application, three things are required:

  • An event queue.
  • A subscriber object on an endpoint.
  • The created subscriber object must be added to an event queue to dispatch the received messages.

Event Queue

Before the subscriber object can be added to an event queue, the event queue must exist:

queue = realm.CreateEventQueue();

Subscriber

Create the subscriber object by specifying the endpoint name, an optional content matcher, and an optional properties object:

sub = realm.CreateSubscriber("default", contentMatcher, subscriberProps);

The last step is to add the subscriber object to the event queue. This allows the event queue to dispatch messages sent to that subscriber:

queue.addSubscriber(sub, this);

Endpoints

TIBCO Cloud Messaging only supports a fixed set of endpoints: default, shared, last-value and map. Each endpoint is associated with a durable type of the same name. If your application does not need persistence use the default endpoint.

Content Matcher

A content matcher is used to limit which messages are delivered to a client application based on the content of the message. The string passed to realm.CreateContentMatcher() contains JSON which specifies the field name in the message, and the required value of that field. In this case, {"demo_tcm":true} matches any message which contains the field demo_tcm.

contentMatcher = realm.CreateContentMatcher("{\"demo_tcm\":true}");

Subscriber Properties

A shared durable essentially acts like a queue. Messages are stored in the persistent server, and apportioned among active subscribers to the durable in a round-robin fashion. Each subscriber must specify the same durable name. The durable name is defined by properties specified when the subscriber is created. If your application does not need persistence do not supply a durable name.

subscriberProps = FTL.createProperties();
subscriberProps.set(Subscriber.PROPERTY_STRING_DURABLE_NAME, "tcmdemosub.java");

Dispatching

For an event queue to dispatch messages, it must be run on a thread. That thread may be separately created and managed, or it may be the main program thread - as it is in this sample. The dispatch method call on previously-created event queue is the FTL API function that actually dispatches messages. It should wait for messages to be available for dispatch before returning. Since messages arrive asynchronously, the dispatch method call is contained in a loop, which terminates only when the finished flag is true, indicating the message has been received.

Console.WriteLine("Waiting for message(s)");
while (!finished)
    queue.dispatch();

Message Callback

A message callback must have the signature messagesReceived(List<Message>, EventQueue) and be a method of a class which implements SubscriberListener:

public void messagesReceived(List<Message> messages, EventQueue eventQueue)
{
    int i;
    int msgNum = messages.size();

    for (i = 0;  i < msgNum;  i++)
    {
        if (messages.get(i) != null){
            System.out.print("Received message");
            System.out.println(" " + messages.get(i).toString());
        }
    }
}

Subscribing to Notifications

In some situation, FTL must notify a client application of a condition which cannot be delivered through an event queue. Register a notification handler which is invoked when an administrative action occurs which requires the client application to be notified:

realm.setNotificationHandler(this);

A notification handler callback must have the signature onNotification(int, String) and be a method of a class which implements NotificationHandler:

public void onNotification(int type, String reason)
{
    if (type == NotificationHandler.CLIENT_DISABLED)
    {
        System.out.println("Application administratively disabled: " + reason);
        finished = true;
    }
    else
    {
        // But just in case additional notification types are added, handle the rest of them.
        System.out.println("Notification type " + type + ": " + reason);
    }
}

Cleanup

Once objects are no longer needed, they should be disposed of - and generally in reverse order of creation.

Publisher

msg.destroy();
pub.close();
realm.close();
props.destroy();

Subscriber

// First remove the subscriber from the event queue.
queue.removeSubscriber(sub);
sub.close();
cm.destroy();
queue.destroy();
realm.close();
props.destroy();

To permanently destroy a durable subscription, including any messages stored by TIBCO Cloud Messaging for that durable, first close the subscription and then call unsubscribe using the realm object. Supply the unsubscribe call with the endpoint name and durable name used to create the durable subscription.

sub.close();
realm.unsubscribe("default", "tcmdemosub.java");