14 Event Notification Service API Reference

This chapter details the ENS API reference.

ENS C API Overview

The ENS C API, ens.h, is located in the MessagingServer_home/examples/enssdk/ directory. The ens_pub.c sample publisher and ens_sub.c sample subscriber demonstrate use of the ENS C API.

Here is the API header (ens.h):

====
// ens.h -- ENS C client API
//
// Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.

ifndef ENS_HEADER_INCLUDED
define ENS_HEADER_INCLUDED 1

ifdef __cplusplus
extern "C" {
endif

//
// Connecting
//

// an ENS client
struct ensclient_t;
typedef struct ensclient_t ensclient_t;

// callback invoked if the ENS connection dies
// subscriptions are no longer valid but must not be unsubscribed
typedef void (*lost_cnx_cb_t)(void*);

ensclient_t* ens_open(const char* host, int port, lost_cnx_cb_t
lost_cnx_cb, void* lost_cnx_arg);

// automatically cleans up all existing subscription handles
void ens_close(ensclient_t*);


//
// Publishing events
//

typedef void (*destructor_t)(void*);            // cleanup function

void ens_publish(ensclient_t*, const char* evt, char* body, size_t
bodysz, destructor_t body_delete);


//
// Receiving events
//

// a subscription handle
struct sub_t;
typedef struct sub_t subscription_t;

// handler called when a subscribed event is received
typedef void (*notify_cb_t)(void *rock, char *event, char *body, size_t
body_len);

subscription_t* ens_subscribe(ensclient_t*, const char* evt, notify_cb_t
cb, void* rock);
void ens_unsubscribe(ensclient_t*, subscription_t*);

ifdef __cplusplus
}
endif

endif // ENS_HEADER_INCLUDED
====

API Basic Usage

The client calls ens_open() to start a connection. If reliability across ENS connection outages is important, the client should provide a lost connection handler callback. The lost connection handler normally marks any client-specific subscription information as invalid, calls ens_close, and triggers a task to attempt a reconnect by using ens_open (possibly after a delay).

The client calls ens_close() on shut down.

The client calls ens_subscribe() to subscribe to events and gets a callback when a matching event is received. The client calls ens_unsubscribe() to unsubscribe from an event (usually not necessary as a client can just call ens_close).

To publish an event, use ens_publish. (In general, you do not need to do so and the sample code should be sufficient.)

To build the sample programs, link against the libens library, which is normally installed in /opt/sun/comms/messaging64/lib/libens.so.

The ens_sub.c sample program is helpful to see what events are generated and how the event strings and message payloads are formatted.

Both Oracle Communications Messaging Server publishers (that is, imapd) and the ENS server (enpd) are designed to drop events if an overload situation occurs.

Client API ens_sopen

The client API, ens_sopen, can connect to the ENS broker with authentication.

Customers who want to connect to the ENS broker use the API ens_open declared in ens.h to create a new client connection to the ENS broker. The API, ens_open, does not support authentication and TLS/SSL.

So we added a new API, ens_sopen, to create a secure connection to the ENS broker that supports authentication and TLS/SSL. The arguments to the API, ens_sopen, include all the arguments to the API, ens_open, and also includes arguments to accept an username and a password for authentication. It also includes an argument to specify whether to use TLS/SSL while making an connection to the ENS Broker specified.

The new API declared in lib/ens/ens.h is:

ensclient_t* ens_sopen (const char* host, int port, int use_ssl, const char* auth_user, const char* auth_secret, lost_cnx_cb_t lost_cnx_cb, void* lost_cnx_arg);

In order to connect to the ENS brokers that support TLS/SSL and authentication, you must use the new API, ens_sopen. The API accepts the arguments auth_user and auth_secret, but it may or may not use them depending on whether or not the ENS broker it is connecting to requires authentication.

If the connection is made to the SSL port, then the value for the argument, use_ssl, must be 1. If the connection is made to the non-SSL port, then the value for the argument, use_ssl, must be 0.

API Usage Notes

The ENS C API is presently the recommended API for C-based software that needs to subscribe to Messaging Server events. Use of the Glassfish Message Queue, OpenMQ, or Java Enterprise System Message Queue C API is not recommended.

Event Notification Service Java (JMS) API

The ENS Java API is included with Messaging Server. The Java API conforms to the Java Message Service specification (JMS).

ENS acts as a provider to Java Message Service. Thus, it provides a Java API to ENS. The software consists of the base library plus a demo program.

The ENS-JMS API provides a way for Java programs to consume the messages generated by the Messaging Server. An application using JMS can either use the point-to-point approach (queues) or Publish/Subscribe (topic) approach.

The messaging server generates events and publish them to the ENS broker called "enpd". The ENS broker support the topic approach only and not the queue approach. It supports non-durable subcriptions only. With topics, multiple subscribers can subscribe to a single topic.

Note:

The bundled ens-jms.jar and jms.jar should be on classpath.

Sample ENS-JMS Consumer Program

To use Sample ENS-JMS consumer program, the messaging server should be configured for ENS. See "Administering Event Notification Service" and "Messaging Server Specific Event Notification Service Information" for more information on ENS.

Below is the sample JMS consumer of ENS messages which consumes the messages from the default topic and prints the messages.

/**
* A consumer that can connect to a ENS Server and printMessages as JMS messages.
*/
public class JMSConsumer {
 
String hostname = "localhost";
int port = 7997;
boolean printMessages = true;
private String topicName = "store";
 
/**
* Constructor for creating a JMS consumer.
*/
JMSConsumer() {
}
 
/**
* start - starts the JMS consumer which waits to receive a event from the
* messaging server. This waits for the event and prints the message got.
*
* @throws JMSException
*/
public void start() throws JMSException {
/**
* Create a EnsTopicConnFactory which creates a connection to the ENS
* Broker. If you want to use the Same code for a different JMS
* provider, all you have to do is to change the ConnectionFactory to
* that of the corresponding broker.
* eg. TopicConnectionFactory connFactory = new newcom.sun.messaging.ConnectionFactory();
* can be replaced by
* TopicConnectionFactory connFactory = new EnsTopicConnectionFactory("ens-conn-factory", hostname, port);
* to use the OpenMQ as a broker to receive JMS Messages. 
*/
TopicConnectionFactory connFactory = new EnsTopicConnectionFactory("ens-conn-factory", hostname, port);
TopicConnection topicConn = connFactory.createTopicConnection();
TopicSession topicSession = topicConn.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);
Topic topic = topicSession.createTopic(topicName);
TopicSubscriber topicSubscriber = topicSession.createSubscriber(topic);
topicConn.start();
TextMessage message = (TextMessage) topicSubscriber.receive();
if (printMessages) {
printMessage(message);
}
topicSession.close();
topicConn.close();
}
 
public static void main(String[] args) throws JMSException {
JMSConsumer cons = new JMSConsumer();
cons.start();
}
 
/**
* printMessage - prints the Contents of the JMS messages received.
*
* @param message
* @throws JMSException
*/
private void printMessage(TextMessage message) throws JMSException {
system.out.println("----Start of Message------ \n");
System.out.println("JMSCorrelationID:+" + message.getJMSCorrelationID() + "\n");
System.out.println("JMSMessageID:+" + message.getJMSMessageID() + "\n");
System.out.println("JMSType:+" + message.getJMSType() + "\n");
System.out.println("JMSDeliveryMode:+" + message.getJMSDeliveryMode() + "\n");
System.out.println("JMSDestination:+" + message.getJMSDestination() + "\n");
System.out.println("JMSExpiration:+" + message.getJMSExpiration() + "\n");
System.out.println("JMSPriority:+" + message.getJMSPriority() + "\n");
System.out.println("JMSRedelivered:+" + message.getJMSRedelivered() + "\n");
System.out.println("JMSReplyTo:+" + message.getJMSReplyTo() + "\n");
System.out.println("JMSTimestamp:+" + message.getJMSTimestamp() + "\n");
System.out.println("Properties:\n");
// Print the Properties
Enumeration keys = message.getPropertyNames();
while (keys.hasMoreElements()) {
String key = (String) keys.nextElement();
System.out.println(key + "  -> " + message.getStringProperty(key) + "\n");
}
System.out.println("----End of Properties----\n");
System.out.println("Body:+" + message.getBody(String.class) + "\n");
System.out.println("----End of Message------ \n");
System.out.println("received: " + message.getText());
}

Sample ENS-JMS Consumer Using Automatic Failover and Properties File

Below is the file that has the mapping from the logical hostname to a list of physical hostnames:

bash-3.2$ cat /local/harokias/hostmap.properties
 
# The mapping from logical mailhost name to a list of physical hostnames
# mailhost1 mapping
mailhost1.hostlist = host1 host2 host3
 
# mailhost2 mapping
mailhost2.hostlist = host4 host5 host6

If automatic failover and properties file are to be used then you should made following change in the sample ENS-JMS consumer program:

TopicConnectionFactory connFactory = new EnsTopicConnectionFactory("ens-conn-factory", <"mailhost1">,<"local/harokias/hostmap.properties">, port);