How to use the Java Message Service (JMS)-Agent Gateway

Author: Edward Curry (ECRG, NUI, Galway)

Date: March 29, 2004

JmsAgentGateway version 0.5

Java platform: Sun JDK 1.4 Linux

JADE version 3.1

The Java Message Service (JMS)-Agent Gateway is a utility designed to allow agents within a JADE platform to interact with a JMS provider. This tutorial describes how to install and use the gateway to interact with a JMS provider, using both the Point-to-Point and Publish/Subscribe messaging models. Users should be familiar with the FIPA-Subscribe interaction protocol and the JADE implementation of the protocol, see the JADE Programmers Guide for more information. Please note this Gateway only works on JDK 1.4

Installation

In order to install the JMS-Agent Gateway the following steps must be performed:
Common Support Libraries (Required)      

Location
Library Available From Notes
add-ons/jmsagentgateway/lib log4j-1.2.8.jar jakarta-log4j-1.2.8.zip Supports log4j-1.2.7 +
add-ons/jmsagentgateway/lib beangenerator.jar beangeneratorAddon-3.1.zip  

 

     
OpenJMS Support Libraries (Optional)      

Location
Library Available From Notes
add-ons/jmsagentgateway/lib openjms-client-X..jar http://openjms.sourceforge.net/ Download OpenJMS provider, files located in /lib
add-ons/jmsagentgateway/lib exolabcore-0.3.6.jar    
add-ons/jmsagentgateway/lib commons-logging-1.0.3.jar http://jakarta.apache.org/commons/logging  

 

     
JBossMQ Support Libraries (Optional)      

Location
Library Available From Notes
add-ons/jmsagentgateway/lib jbossall-client.jar http://www.jboss.org/ Download JBoss provider, files located in /client
add-ons/jmsagentgateway/lib jbossjmx-ant.jar   .
       
SonicMQ Support Libraries (Optional)      

Location
Library Available From Notes
add-ons/jmsagentgateway/lib jmxri.jar http://www.sonicmq.com/ Download SonicMQ, files located in /lib
add-ons/jmsagentgateway/lib jndi.jar    
add-ons/jmsagentgateway/lib mfcontext.jar    
add-ons/jmsagentgateway/lib mgmt_agent.jar    
add-ons/jmsagentgateway/lib mgmt_client.jar    
add-ons/jmsagentgateway/lib mgmt_config.jar    
add-ons/jmsagentgateway/lib sonic_Client.jar    
add-ons/jmsagentgateway/lib sonic_mgmt_client.jar    
add-ons/jmsagentgateway/lib sonic_mgmt.jar    
add-ons/jmsagentgateway/lib xercesImpl.jar   Must be file from SonicMQ distribution
add-ons/jmsagentgateway/lib xmlParserAPIs.jar   Must be file from SonicMQ distribution

 

Compiling

The Jade Makefile will not compile the JMS-Agent Gateway. To compile the JMS-Agent Gateway you have to use the 'build.xml' ant-file located in the jmsagentgateway directory. The following rules are available:

Usage

Important OpenJMS and JBossMQ Note:

When activating a JMS-Agent Gateway that uses a OpenJMS/JBossMQ provider you will need to change the port JADE runs on (1099) as this is the same port number used by the OpenJMS/JBoss JNDI service. To specify a port for JADE to run on, simple use the -port switch on startup.

In order to use the JMS-Agent Gateway, the jmsagentgateway.jar and jmsagentgateway.properties file must be on the classpath when starting( either by including it into the $CLASSPATH environment variable - %CLASSPATH% under windows or by specifying it on the command line ).

Activating the jmsagentgateway Agent

To activate the JMS-Agent Gateway utility simply create a new agent of type "ie.nuigalway.ecrg.jade.jmsagentgateway.JMS-Agent Gateway" on the JADE platform

Configuration

JMS-Agent Gateway Ontology Class Hierarchy

In order to interact with the JMS-Agent Gateway you need to use the ontology defined below, the following sections provide practical examples of using the ontology.

Interacting with the JMS-Agent Gateway

This section provides a brief overview of the main interactions with the JMS-Agent Gateway.

Locating the JmsProxyAgent
The JMS-Agent Gateway registers itself an Agent proxy in the DF as type "JmsProxyAgent". This type may be set in the agents configuration file.

Utility Methods
In order to simplify the process of interacting with the JMS-Agent Gateway the following utility class has been supplied

public class Util {
/**
 *  Utility method for creating provider information
 *
 @param  providerURL  URL of the provider
 @param  providerICF  Initial Connection Factory Class
 @param  destType   Queue or Topic Destination
 @return            Returns a provider information object
 */
public static ProviderInfo createProviderInfo(boolean destType, String providerURL, String providerICF);

/**
 *  Utility method for creating a message
 *
 @param  destination    destination of message
 @param  payload        The messages payload (Any Serializable Java Object)
 @param  deliveryMode   Persistent setting of the message
 @return                Newly created Jms Message
 @exception  Exception  Error creating the message
 */
public static JmsMessage createMessage(String destination, java.io.Serializable payload, Boolean deliveryMode) throws Exception;

/**
 *  Utility method to create a Subscription
 *
 @param  destination  Topic or Queue to subscribe to
 @param  durable      Subsctiptions durability setting
 @return              Newley created subscription info
 */
public static Subscription createSubscription(String destination, Boolean durable);

/**
 *  Convert a BASE64 string payload to a serializable object
 *
 @param  payload        BASE64 message payload string
 @return                Serialized payload
 @exception  Exception  Error during conversion
 */
public static java.io.Serializable convertStringToObject(String payloadthrows Exception;

/**
 *  Convert an object to a BASE64 string
 *
 @param  obj            Payload object
 @return                Payload object converted to a BASE64 string
 @exception  Exception  Error during object to string conversion
 */
public static String convertObjectToString(java.io.Serializable objthrows Exception;
}

Publishing a Message
/**
 *  Utility method to publish a message
 *
 @param  payload  Payload of the message to be published
 */
private void publishMessage(String payload) {

  PublishMessage pm = new PublishMessage();

  // Using a connection with the openJMS provider
  pm.setProviderInfo(Util.createProviderInfo(Util.QUEUE, "rmi://localhost:1099/""org.exolab.jms.jndi.InitialContextFactory"));

  try {
    // Set Destination to "queue1"
    pm.setMessage(Util.createMessage("queue1", payload, Util.PERSISTENT));
  catch (Exception e) {
    System.out.println("Error creating message:" + e.toString());
  }

  System.out.println("Sending message: " + payload);
  sendMessage(ACLMessage.REQUEST, PM);
}


/**
 *  Utility method for sending a message
 *
 @param  performative  Performative for the message
 @param  action        The AgentAction of the message to be sent
 */
private void sendMessage(int performative, AgentAction action) {

  ACLMessage msg = new ACLMessage(performative);
  msg.setLanguage(codec.getName());
  msg.setOntology(ontology.getName());

  try {
    getContentManager().fillContent(MSGnew Action(JMS-Agent Gateway, action));
    msg.addReceiver(JMS-Agent Gateway);
    send(MSG);
  catch (Exception e) {
    System.out.println("Error sending message:" + e.toString());
  }
}

Subscribing to a Destination

addBehaviour(new JmsSubscriptionInitiator(this, getSubscriptionMsg()));

/**
 *  Create a subscription message
 *
 @return    The subscriptionMsg value
 */
private ACLMessage getSubscriptionMsg() {

  Subscribe sub = new Subscribe();

  // Using a queue connection with the openJMS provider
  sub.setProviderInfo(Util.createProviderInfo(Util.QUEUE, "rmi://localhost:1099/""org.exolab.jms.jndi.InitialContextFactory"));

  // Create a subscription to the destination "pingAgent/ping"
  sub.setSubscription(Util.createSubscription("pingAgent/ping", Util.NON_DURABLE));

  ACLMessage MSG = new ACLMessage(ACLMessage.SUBSCRIBE);
  msg.setLanguage(codec.getName());
  msg.setOntology(ontology.getName());

  try {
    getContentManager().fillContent(MSGnew Action(JMS-Agent Gateway, sub));
    msg.addReceiver(JMS-Agent Gateway);
  catch (Exception e) {
    System.out.println("Error populating subscription message:" + e.toString());
    e.printStackTrace();
  }

  return MSG;
}

/**
 *  Implementation of the SubscriptionInitiator interface
 *
 @author     Edward Curry
 @version 0.5 12 January 2004
 */
class JmsSubscriptionInitiator extends SubscriptionInitiator {

  private int counter = 0;
  Agent agent;

  /**
   *  Constructor for the JmsSubscriptionInitiator object
   *
   @param  a    Agent involved in this interaction
   @param  MSG  Subscription message to send
   */
  JmsSubscriptionInitiator(Agent a, ACLMessage MSG) {
    super(a, msg);
    agent = a;
  }

  /**
   *  Method called when a Agree message is received
   *
   @param  agree  Agree message received
   */
  protected void handleAgree(ACLMessage agree) {
    System.out.println("Handle Agree");
  }

  /**
   *  Method called when a Refuse message is received
   *
   @param  refuse  Refuse message received
   */
  protected void handleRefuse(ACLMessage refuse) {
    System.out.println("Handle Refuse");
  }

  /**
   *  Method called when a NotUnderstood message is recceived
   *
   @param  notUnderstood  NotUnderstood message received
   */
  protected void handleNotUnderstood(ACLMessage notUnderstood) {
    System.out.println("Handle not understood");
  }

  /**
   *  Method called when a Inform message is received
   *
   @param  inform  Inform message received
   */
  protected void handleInform(ACLMessage inform) {
    System.out.println("Handle Inform");

    try {

      ContentElement content = getContentManager().extractContent(inform);
      OnMessage om = (OnMessage) ((Actioncontent).getAction();
      JmsMessage jmsMsg = om.getMessage();

      counter++;
      System.out.println("Message Received: Payload:" ((StringUtil.convertStringToObject(jmsMsg.getPayload())));

      // Send pong message
      publishPong("Pong" + counter);

    catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   *  Method called when a Failure message is received
   *
   @param  failure  Failure message received
   */
  protected void handleFailure(ACLMessage failure) {
    System.out.println("Handle Failure");
  }
}

Description of JMS-Agent Gateway Example

Name: Client Agent - ie.nuigalway.ecrg.jade.jmsagentgateway.examples.ClientAgent
Purpose:
Demonstrates the sending and receiving of messages from a JADE --> JMS --> JADE interaction.
Description: This JADE Agent listens to a destination and then sends a defined (default 10) number of messages to that destination.

Name: Ping Agent - ie.nuigalway.ecrg.jade.jmsagentgateway.examples.PingAgent
Purpose:
Demonstrates a JADE Agent interacting with a Queue and Topic.
Description: This agent listens a queue "pingAgent/ping" and replies to any "ping" messages by publishing a message to the "pingAgent/pong" topic. To run this example you must setup the"pingAgent/ping" queue and the "pingAgent/pong" topic.

Name: Ping Client - ie.nuigalway.ecrg.jade.jmsagentgateway.examples.PingClient
Purpose:
Illustrates how a regular Java object can interact with a JADE agent using the JMS-Agent Gateway.
Description: This regular Java class sends a ping to the "pingAgent/ping" queue and listens to the "pingAgent/pong" topic for a response. To run this example you must setup the"pingAgent/ping" queue and the "pingAgent/pong" topic.

Configuration File

The JMS-Agent Gateway is configurable by altering its jmsagentgateway.properties file. From this file it is possible to enable the Agents GUI, set the Agents Type and the Agents Owner.

jmsagentgateway.properties

### JMS-Agent GatewayConfiguration
#############################################

### Default Settings
############################
ie.nuigalway.ecrg.jade.jmsagentgateway.gui=false
ie.nuigalway.ecrg.jade.jmsagentgateway.agentType=JmsProxyAgent
ie.nuigalway.ecrg.jade.jmsagentgateway.agentOwner=ecrg.it.nuigalway.ie

Known Issues

 


JADE is a trademark of CSELT.
SonicMQ is a trademark of Sonic Software.
JBoss and JBoss Group are a registered trademark and servicemark of Marc Fleury under operation by The JBoss Group, LLC.
JADE has been developed jointly by CSELT and the Computer Engineering Group of the University of Parma.

The jmsagentgateway Agent was developed in the Enterprise Computing Research Group (ECRG) at the National University of Ireland, Galway by Edward Curry.
The support of the Informatics Research Initiative of Enterprise Ireland is gratefully acknowledged.
Copyright 2002/2003/2004 Enterprise Computing Research Group.