Creación de un nodo de entrada en Java

Antes de empezar

Creación de un proyecto Java nuevo

Puede crear nodos Java desde el entorno de trabajo. Para realizar esta tarea, deberá crear un proyecto Java nuevo, como se indica a continuación:
  1. Vaya a la perspectiva Java.
  2. Pulse Archivo > Nuevo > Proyecto. Seleccione Java en el menú de la izquierda y, a continuación, seleccione Proyecto Java en el menú de la derecha.
  3. Déle un nombre al proyecto.

    Se visualiza el panel Valores Java.

  4. Seleccione el separador Bibliotecas y pulse Añadir JAR externos.
  5. Seleccione dir_instalación\classes\jplugin2.jar.
  6. Siga las solicitudes de los demás separadores para definir otros valores de creación.
  7. Pulse Finalizar.
Entonces puede desarrollar el origen del nodo Java en este proyecto.

Declaración de la clase de nodo de entrada

Cualquier clase que implemente MbInputNodeInterface y esté contenida en la vía de acceso de LIL del intermediario se registra en el intermediario como un nodo de entrada. Cuando implemente MbInputNodeInterface, también necesitará implementar un método run para esta clase. El método run representa el inicio del flujo de mensajes, contiene los datos que formulan el mensaje y los propaga por el flujo. El intermediario invoca el método run cuando quedan hebras disponibles de acuerdo con el modelo de trabajo de hebras especificado.

Por ejemplo, para declarar la clase de nodo de entrada:

package com.ibm.jplugins;

import com.ibm.broker.plugin.*;

public class BasicInputNode extends MbInputNode implements MbInputNodeInterface
{
...
Puede realizar esta tarea en el entorno de trabajo como se indica a continuación:
  1. Pulse Archivo > Nuevo > Clase.
  2. Establezca los campos de nombre de paquete y clase en los valores apropiados.
  3. Suprima el texto del campo de texto de superclase y pulse el botón Examinar
  4. Seleccione MbInputNode.
  5. Pulse el botón Añadir junto al campo de texto de interfaces y seleccione MbInputNodeInterface.
  6. Pulse Finalizar.

Definición del constructor de nodos

Cuando se crea una instancia del nodo, se invoca el constructor de la clase de nodo del usuario. Aquí es donde creará los terminales del nodo e inicializará los valores por omisión para los atributos.

Un nodo de entrada tiene asociados varios terminales de salida pero normalmente no tiene ningún terminal de entrada. Utilice el método createOutputTerminal para añadir terminales de salida a un nodo cuando se crea una instancia del nodo. Por ejemplo, para crear un nodo con tres terminales de salida:

public BasicInputNode() throws MbException
{
createOutputTerminal ("out");
createOutputTerminal ("failure");
createOutputTerminal ("catch");
setAttribute ("firstParserClassName","myParser");
attributeVariable = "none"; 
}

Recepción de datos externos en un almacenamiento intermedio

Un nodo de entrada puede recibir datos de cualquier tipo de origen externo, por ejemplo un sistema de archivos, una cola o una base de datos, del mismo modo que cualquier otro programa Java, a condición que la salida del nodo esté en el formato correcto.

Proporcione un almacenamiento intermedio de entrada (o corriente de bits) para incluir los datos de entrada y asócielo con un objeto de mensaje. Cree un mensaje a partir de una matriz de bytes utilizando el método createMessage de la clase MbInputNode y, a continuación, genere un mensaje ensamblado válido desde este mensaje. Para obtener información detallada acerca de estos métodos, consulte la API Java. Por ejemplo, para leer la entrada de un archivo:

  1. Cree una corriente de datos de entrada para leerla en el archivo:
    FileInputStream inputStream = new FileInputStream("myfile.msg");
  2. Cree una matriz de bytes del tamaño del archivo de entrada:
    byte[] buffer = new byte[inputStream.available()];
  3. Lea del archivo en la matriz de bytes:
    inputStream.read(buffer);
  4. Cierre la corriente de datos de entrada:
    inputStream.close();
  5. Cree un mensaje para ponerlo en la cola:
    MbMessage msg = createMessage(buffer);
  6. Cree un mensaje ensamblado nuevo para que contenga en este mensaje:
    msg.finalizeMessage(MbMessage.FINALIZE_VALIDATE);
    MbMessageAssembly newAssembly =
         new MbMessageAssembly(assembly, msg);

Propagación del mensaje

Cuando haya creado un mensaje ensamblado, puede propagarlo a continuación a uno de los terminales del nodo.

Por ejemplo, para propagar el mensaje ensamblado en el terminal "out":
MbOutputTerminal out = getOutputTerminal("out");
out.propagate(newAssembly);
Para suprimir el mensaje:
msg.clearMessage();

Para borrar la memoria que está asignada para el árbol de mensajes, llame a la función clearMessage() dentro del bloque try/catch final.

Control del trabajo con hebras y transacciones

La infraestructura del intermediario maneja las cuestiones relacionadas con las transacciones como, por ejemplo, el control de la confirmación de cualquier unidad de trabajo de base de datos o WebSphere MQ o cuando se ha completado el proceso de mensajes. Sin embargo, los recursos modificados desde dentro de un nodo definido por el usuario no estarán necesariamente bajo el control transaccional del intermediario.

Cada hebra de flujo de mensajes se asigna de una agrupación de hebras mantenidas para cada flujo de mensajes e inicia la ejecución en el método run.

El nodo definido por el usuario utiliza los valores de retorno para indicar si una transacción se ha ejecutado satisfactoriamente, para controlar si las transacciones se han confirmado o restituido y para controlar cuándo se devuelve la hebra a la agrupación. La infraestructura del intermediario captura las excepciones no manejadas y se restituye la transacción.

Determine el comportamiento de las transacciones y las hebras utilizando un valor de retorno apropiado de los siguientes:

MbInputNode.SUCCESS_CONTINUE
La transacción se confirma y el intermediario invoca el método run otra vez utilizando la misma hebra.
MbInputNode.SUCCESS_RETURN
La transacción se confirma y se devuelve la hebra a la agrupación de hebras, suponiendo que no sea la única hebra para este flujo de mensajes.
MbInputNode.FAILURE_CONTINUE
La transacción se restituye y el intermediario invoca el método run otra vez utilizando la misma hebra.
MbInputNode.FAILURE_RETURN
La transacción se restituye y se devuelve la hebra a la agrupación de hebras, suponiendo que no sea la única hebra para este flujo de mensajes.
MbInputNode.TIMEOUT
El método run no debe bloquearse de forma indefinida mientras espera a que lleguen datos de entrada. Mientras el código de usuario bloquea el flujo, no puede concluir o reconfigurar el intermediario. El método run debe entregar periódicamente el control al intermediario volviendo del método run. Si no se han recibido datos de entrada después de un determinado periodo (por ejemplo 5 segundos), el método deberá volver con el código de retorno TIMEOUT. Suponiendo que no sea necesario reconfigurar o concluir el intermediario, se volverá a invocar inmediatamente el método run del nodo de entrada.
Para crear flujos de mensajes de varias hebras, invoque el método dispatchThread después de que se haya creado un mensaje pero antes de que se propague el mensaje a un terminal de salida. Esto asegura que sólo haya una hebra esperando datos mientras otras hebras están procesando el mensaje. Se obtienen hebras nuevas de la agrupación de hebras hasta el límite máximo especificado por el atributo additionalInstances del flujo de mensajes. Por ejemplo:
public int run( MbMessageAssembly assembly ) throws MbException
{
  byte[] data = getDataWithTimeout();  // el método proporcionado por el usuario
                                       // devuelve nulo si se excede el tiempo de espera
  if( data == null )
    return TIMEOUT;

  MbMessage msg = createMessage( data );
  msg.finalizeMessage( MbMessage.FINALIZE_VALIDATE );
  MbMessageAssembly newAssembly =
       new MbMessageAssembly( assembly, msg );

  dispatchThread();

  getOutputTerminal( "out" ).propagate( newAssembly );

  return SUCCESS_RETURN;
}

Declaración del nombre de nodo

Necesita declarar el nombre del nodo tal como lo identificará el entorno de trabajo. Todos los nombres de nodo deben terminar por "Node". Declare el nombre utilizando el método siguiente:

public static String getNodeName()
{
   return "BasicInputNode";
}
Si no se declara este método, la infraestructura de API Java crea un nombre de nodo por omisión utilizando las normas siguientes:
  • El nombre de clase se añade el nombre de paquete.
  • Los puntos se eliminan y la primera letra de cada parte del nombre de paquete y clase se escriben en mayúsculas.
Por ejemplo, por omisión se asigna a la clase siguiente el nombre de nodo "ComIbmPluginsamplesBasicInputNode":
package com.ibm.pluginsamples;
public class BasicInputNode extends MbInputNode implements MbInputNodeInterface
{
   ...

Declaración de atributos

Declare los atributos de nodo del mismo modo que las propiedades de bean Java. Es responsable de escribir los métodos getter y setter para los atributos y la infraestructura de API deducirá los nombres de atributo utilizando las normas de introspección de bean Java. Por ejemplo, si declara los dos métodos siguientes:

private String attributeVariable;

public String getFirstAttribute()
{
  return attributeVariable;
}

publc void setFirstAttribute(String value)
{
  attributeVariable = value;
}

El intermediario deduce que este nodo tiene un atributo denominado firstAttribute. Este nombre se deriva de los nombres de los métodos get o set, no de los nombres de variables de miembros de clase internos. Dado que los atributos sólo se puede exponer como series de caracteres, los tipos numéricos se deben convertir a las series de caracteres o de las series de caracteres en los métodos get o set. Por ejemplo, el método siguiente define un atributo denominado timeInSeconds:

int seconds;

public String getTimeInSeconds()
{
  return Integer.toString(seconds);
}

public void setTimeInSeconds(String value)
{
  seconds = Integer.parseInt(value);
}

Implementación de la funcionalidad de nodo

Como ya se ha descrito, el intermediario invoca el método run para crear el mensaje de entrada. Este método debe proporcionar la función de proceso completa para el nodo de entrada.

Alteración temporal de los atributos de analizador de mensajes por omisión (opcional)

Normalmente una implementación de nodo de entrada determina qué analizador de mensajes analiza inicialmente un mensaje de entrada. Por ejemplo, el nodo MQInput primitivo indica que se necesita un analizador MQMD para analizar la cabecera MQMD. Un nodo de entrada definido por el usuario puede seleccionar un analizador de mensajes o cabeceras apropiado y la modalidad en la que se controla el análisis, utilizando los atributos siguiente que se incluyen como valores por omisión y que se pueden alterar temporalmente:

rootParserClassName
Define el nombre del analizador raíz que analiza los formatos de mensaje soportados por el nodo de entrada definido por el usuario. Toma por omisión GenericRoot, un analizador raíz proporcionado que hace que el intermediario asigne y encadene analizadores. Es improbable que un nodo necesite modificar este valor de atributo.
firstParserClassName
Define el nombre del primer analizador, de lo que puede ser una cadena de analizadores responsables de analizar la corriente de bits. Toma por omisión XML.
messageDomainProperty
Atributo opcional que define el nombre del analizador de mensajes necesario para analizar el mensaje de entrada. Los valores soportados son los mismos que los soportados por el nodo MQInput. (Consulte el apartado Nodo MQInput si desea ver más información sobre el nodo MQInput.)
messageSetProperty
Atributo opcional que define el identificador de conjunto de mensajes o el nombre de conjunto de mensajes, en el campo Conjunto de mensajes, sólo si el atributo messageDomainProperty especificaba el analizador MRM.
messageTypeProperty
Atributo opcional que define el identificador del mensaje en el campo Tipo de mensaje, sólo si el atributo messageDomainProperty especificaba el analizador MRM.
messageFormatProperty
Atributo opcional que define el formato del mensaje en el campo Formato del mensaje, sólo si el atributo messageDomainProperty especificaba el analizador MRM.

Supresión de una instancia del nodo

Se suprime una instancia del nodo cuando se realiza una de las acciones siguientes:
  • Se concluye el intermediario.
  • Se elimina el nodo o el flujo de mensajes que contiene el nodo y se vuelve a desplegar la configuración.
Durante la supresión de nodo, es posible que el nodo desee que se le informe a fin de poder realizar las operaciones de limpieza, por ejemplo cerrar los sockets. Si el nodo implementa el método onDelete opcional, el intermediario invoca este método justo antes de que se suprima el nodo.

Implemente el método onDelete como se indica a continuación:

public void onDelete()
{
  // realizar limpieza de nodo si es necesario
}
Información relacionada
API Java
Avisos | Marcas registradas | Descargas | Biblioteca | Soporte | Su opinión
Copyright IBM Corporation 1999, 2006 Última actualización: 22/08/2006
as09950_