Ampliación de las posibilidades de un nodo de entrada en Java

Antes de comenzar

Asegúrese de haber leído y comprendido los temas siguientes:

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 conjunto de mensajes 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 conjunto de mensajes 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 conjunto de mensajes, puede propagarlo a continuación a uno de los terminales del nodo.

Por ejemplo, para propagar el conjunto de mensajes en el terminal "out":
MbOutputTerminal out = getOutputTerminal("out");
out.propagate(newAssembly);

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, si se utiliza un nodo definido por el usuario, el intermediario no puede confirmar automáticamente las actualizaciones de recurso.

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;
}

Manejo de excepciones

Utilice la clase mbException para captar excepciones y acceder a ellas. La clase mbException devuelve una matriz de objetos de excepción que representan los hijos de una excepción en la lista de excepciones de intermediario. Cada elemento devuelto especifica su tipo de excepción. Si una excepción no tiene hijos, se devuelve una matriz vacía. El siguiente ejemplo de código muestra el uso de la clase MbException.

public void evaluate(MbMessageAssembly assembly, MbInputTerminal inTerm) throws MbException
  {
    try
      {

        // funcionalidad de plug-in

      }
    catch(MbException ex)
      {
        traverse(ex, 0);

        throw ex; // si se vuelve a generar, debe ser la excepción original que se ha captado
      }
  }

  void traverse(MbException ex, int level)
  {
    if(ex != null)
      {
        // Aquí realizar cualquier acción
        System.out.println("Level: " + level);
        System.out.println(ex.toString());
        System.out.println("traceText:  " + ex.getTraceText());

        // atravesar la jerarquía
        MbException e[] = ex.getNestedExceptions();
        int size = e.length;
        for(int i = 0; i < size; i++)
          {
            traverse(e[i], level + 1);
          }
      }
  }

Consulte el javadoc si desea ver más información detallada de la utilización de la clase mbException.

Puede desarrollar un proceso de mensaje definido por el usuario o un nodo de salida de tal forma que éste pueda acceder a todas las excepciones actuales. Por ejemplo, para captar excepciones de base de datos, puede utilizar la clase MbSQLStatement. Esta clase establece el valor del atributo 'throwExceptionOnDatabaseError', que determina el comportamiento de intermediario cuando encuentra un error de base de datos. Si se establece en verdadero, cuando se genera una excepción la extensión definida por el usuario la puede captar y manejar.

El siguiente ejemplo de código muestra cómo utilizar la clase MbSQLStatement.

public void evaluate(MbMessageAssembly assembly, MbInputTerminal inTerm) throws MbException
  {
    MbMessage newMsg = new MbMessage(assembly.getMessage());
    MbMessageAssembly newAssembly = new MbMessageAssembly(assembly, newMsg);

    String table = 
       assembly.getMessage().getRootElement().getLastChild().getFirstChild().getName();

    MbSQLStatement state = createSQLStatement( "dbName", 
       "SET OutputRoot.XML.integer[] = PASSTHRU('SELECT * FROM " + table + "');" );

    state.setThrowExceptionOnDatabaseError(false);
    state.setTreatWarningsAsErrors(true);

    state.select( assembly, newAssembly );

    int sqlCode = state.getSQLCode();
    if(sqlCode != 0)
      {
        // Aquí realizar manejo de errores

        System.out.println("sqlCode = " + sqlCode);
        System.out.println("sqlNativeError = " + state.getSQLNativeError());
        System.out.println("sqlState = " + state.getSQLState());
        System.out.println("sqlErrorText = " + state.getSQLErrorText());
      }

    getOutputTerminal("out").propagate(assembly);
  }
Información relacionada
API Java
Avisos | Marcas registradas | Descargas | Biblioteca | Soporte | Su opinión
Copyright IBM Corporation 1999, 2005 Última actualización: 11/11/2005
as24987_