IBM WebSphere MQ 7.5 - Cliente JMS stand alone utilizando MS Active Directory como JNDI

...

En esta entrada se describen los pasos para desarrollar un cliente JMS stand alone (Java SE) que se comunique con un servidor IBM WebSphere MQ remoto utilizando Microsoft Active Directory como servicio de nombres (JNDI).

Motivación

Los servidores de aplicaciones Java EE facilitan el acceso a recursos JMS, en estos entornos se vuelve trivial configurar y luego utilizar -por ejemplo- una fábrica de conexiones (Connection Factory) o un destino JMS.

Los inconvenientes surgen cuando queremos acceder a los recursos de un servidos JMS desde un modesto programa "stand alone" utilizando la edición estándar de Java (Java SE).

El servidor IBM WebSphere MQ (WMQ) es uno de los middlewares orientados a mensajes (MOM) mas completos y fiables del mercado, y como no podría ser de otra manera, facilita el acceso a sus recursos a través del protocolo JMS incluso cuando el cliente no se aloja en un servidor Java EE.

Existen varias formas de conectarse con un servidor WMQ para enviar y/o recibir mensajes desde un programa Java SE, a continuación se describirán los pasos que se deben seguir para iniciar una conexión JMS con un servidor WMQ desde un programa Java SE utilizando un servicio de AD para inicializar el contexto JNDI y obtener los recursos JMS alojados en el servidor.

Configuración de AD para almacenar objetos Java

Para almacenar las referencias a los objetos JMS administrados por el servidor WebSphere MQ en Microsoft Active Directory (AD) es necesario que este tenga el esquema correspondiente al RFC 2713.

Para adecuar el AD de acuerdo al RFC mencionado se debe completar la tarea de la sección "Configuración de AD para almacenar objetos Java" incluida en la siguiente entrada de nuestro blog: Almacenamiento de objetos Java en Active Directory utilizando LDAP y JNDI.

Configuración de JMS en IBM WebSphere MQ

A continuación se describen los pasos de configuración necesarios para acceder al servidor WMQ de un cliente Java SE stand alone utilizando JMS.

1.- Identificación del administrador de colas (Queue Manager)

Los objetos JMS que serán definidos luego estarán asociados al queue manager JmsTestQM en el caso de la fábrica de conexiones JMS y a la cola local JmsLocalQ en el caso del destino JMS.

Queue Manager y Local Queue

2.- Pasos para la creación del contexto inicial (Intital Context) asociado al AD

Ir a la carpeta JMS Administered Objects, presionar el botón derecho y seleccionar la opción Add Inicial Context.

Agregar un nuevo contexto inicial

Seleccionar la opción LDAP server, especificar el nombre de host del Active Directory en el campo Host, especificar el nombre distinguido correspondiente a la ubicación dentro del directorio donde se almacenarán los objetos JMS administrados en el campo Distinguished name, luego presionar Next.

Detalles de conexion

Seleccionar la opción simple de la lista de opciones de seguridad, luego presionar Next.

Seguridad AD

Especificar un nombre representativo para el contexto inicial en el campo Context nickname, luego presionar Finish.

Nick name

En el diálogo de credenciales especificar el nombre distinguido de un usuario con privilegios para crear objetos en el AD y su respectiva contraseña, luego presionar OK.

Credenciales AD

3.- Pasos para la creación de una fábrica de conexiones (Connection Factory)

Ir a la carpeta Connection Factories dentro del contexto creado previamente, presionar el botón derecho y seleccionar la opción New -> Connection Factory....

Aregar nueva fabrica de conexiones

Seleccionar la opción WebSphere MQ en la lista de proveedores y especificar defaultCF como nombre en el campo Name, luego presionar Next.

Nombre de la fabrica de conexiones

Seleccionar la opción Connection Factory en la lista de tipos, luego presionar Next.

Tipo de fabrica de conexiones

Seleccionar la opción MQ Client en la lista de transportes para permitir que un cliente remoto pueda establecer una conexión con el servidor WMQ, luego presionar Next.

Tipo de transporte de la fabrica de conexiones

Presionar Next para modificar las propiedades de la fábrica de conexiones que se intenta crear.

Propiedades de la fabrica de conexiones

Seleccionar la opción Connection para modificar las propiedades de conexión.

Propiedades generales de la fabrica de conexiones

Seleccionar JmsTestQM en los campos Base queue manager y Broker queue manager, especificar el nombre de host y el puerto en el campo Connection list, luego presionar Finish.

Propiedades de conexión de la fabrica de conexiones

Finalizado el proceso de creación se debe visualizar el objeto creado en lista de fábrica de conexiones.

Lista de fabricas de conexiones

4.- Pasos para la creción de un nuevo destino (Destination)

Ir a la carpeta Destinations dentro del contexto creado previamente, presionar el botón derecho y seleccionar la opción New -> Destination....

Nuevo destino

Seleccionar la opción Queue en la lista de tipos de destinos y especificar defaultQ como nombre del destino en el campo Name, luego presionar Next.

Nombre del nuevo destino

Presionar Next para modificar las propiedades del destino que se intenta crear.

Propiedades del nuevo destino

Seleccionar JmsTestQM en el campo Queue manager y JmsLocalQ en el campo Queue, luego presionar Finish.

Propiedades generales del nuevo destino

Finalizado el proceso de creación se debe visualizar el objeto creado en lista de destinos.

Lista de destinos

Codificación del cliente JMS stand alone utilizando Java SE

Luego de completar los pasos precedentes, la codificación de un cliente JMS stand alone utilizando Java SE es una tarea sencilla, mas aún si nos apoyamos en un IDE como Eclipse.

1.- Creación y preparación de un nuevo proyecto Java

Copiar a una ubicación local las siguientes librerías ubicadas en el directorio java\lib del servidor WMQ:

  • jms.jar
  • com.ibm.mq.commonservices.jar
  • com.ibm.mq.headers.jar
  • com.ibm.mq.jar
  • com.ibm.mq.jmqi.jar
  • com.ibm.mq.pcf.jar
  • com.ibm.mqjms.jar
  • connector.jar
  • dhbcore.jar

Iniciar el IDE, seleccionar un workspace, y crear un nuevo proyecto Java con el nombre WMQJmsClient, luego presionar Next.

Nuevo proyecto Java

Incorporar como dependencias las librerías copiadas al principio y presionar Finish.

2.- Creación del cliente JMS

Crear una clase denominada StandAloneJmsClient con el siguiente código:

package com.microgestion.mgdevelopers.blog;

import java.util.Properties;
import java.util.logging.Logger;
import javax.jms.ConnectionFactory;
import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class  StandAloneJmsClient{
	
	private static Logger logger = Logger.getLogger("com.microgestion.mgdevelopers.blog");
	private static String baseDN = ",DC=intra,DC=microgestion,DC=com";
	
	private InitialContext jndi_ctx;
	private Session jms_session;
	private ConnectionFactory jms_factory;
	private Connection jms_connection;
	Destination jms_destination = null;
	MessageProducer jms_producer = null;
	
	public StandAloneJmsClient(String cf_name) throws NamingException, JMSException {
		super();
		logger.entering(this.getClass().getName(), "LdapJavaStore");
		Properties properties = new Properties();
		properties.setProperty(Context.INITIAL_CONTEXT_FACTORY,	"com.sun.jndi.ldap.LdapCtxFactory");
		properties.setProperty(Context.PROVIDER_URL, "ldap://ad.intra.microgestion.com/OU=WMQ" + baseDN);
		properties.setProperty(Context.SECURITY_AUTHENTICATION, "simple");
		properties.setProperty(Context.SECURITY_PRINCIPAL, "CN=Administrator,CN=Users" + baseDN);
		properties.setProperty(Context.SECURITY_CREDENTIALS, "MiAdminPassword");

		/* Objetos JMS */
		jndi_ctx = new InitialContext(properties);
		jms_factory = (ConnectionFactory) jndi_ctx.lookup(cf_name);
		jms_connection = jms_factory.createConnection();
		jms_connection.start();
		jms_session= jms_connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
		
		logger.exiting(this.getClass().getName(), "LdapJavaStore");
	}

	public void sendStringMessage(String detination_name, String message) throws NamingException, JMSException{
		logger.entering(this.getClass().getName(), "sendStringMessage");
		Destination jms_destination = null;
		MessageProducer jms_producer = null;
		TextMessage txtMsg = null;
		
		jms_destination = (Destination) jndi_ctx.lookup(detination_name);
		try {
			jms_producer = jms_session.createProducer(jms_destination);
			
			txtMsg = jms_session.createTextMessage();
			txtMsg.setText(message);
			jms_producer.send(txtMsg);
				
		} catch (JMSException e) {
			throw e;
		} finally{
			jms_producer.close();
		}
		
		logger.exiting(this.getClass().getName(), "sendStringMessage");
	}
	
	public void close() throws JMSException{
		jms_session.close();
		jms_connection.close();
	}
	
	public static void main(String[] args) {
		try {
			StandAloneJmsClient app = new StandAloneJmsClient("cn=defaultCF");
			app.sendStringMessage("cn=defaultQ", "Mensaje de prueba");
			app.close();

		} catch (NamingException|JMSException e) {
			logger.throwing(StandAloneJmsClient.class.getName(), "main", e);
			e.printStackTrace();
		} 
	}
}

3.- Ejecución y verificación

Ejecutar la clase anterior y verificar que llega el mensaje a la cola ubicada en el servidor WMQ.

Mensaje en la cola

Referencias


Modificado por última vez en Lunes, 18 Noviembre 2013 14:11

Acerca del autor

Diego E. Mendoza

Diego se desempeña como arquitecto de software en MicroGestion participando en el proceso de análisis y diseño de soluciones que tengan requerimientos de alta disponibilidad, integración de ambientes heterogéneos, orientación a servicios, gestión de procesos de negocio, etc.