Ampliación de las posibilidades de un nodo de salida o de proceso de mensajes en Java

Antes de comenzar

Asegúrese de haber leído y comprendido el tema siguiente:

Acceso a los datos de mensaje

En muchos casos, el nodo definido por el usuario necesita acceder al contenido del mensaje recibido en el terminal de entrada. El mensaje se representa como un árbol de elementos de sintaxis. Se proporcionan grupos de funciones de programa de utilidad para la gestión de mensajes, el acceso al almacenamiento intermedio de mensajes, la navegación por los elementos de sintaxis y el acceso a los elementos de sintaxis.

La clase MbElement proporciona la interfaz a los elementos de sintaxis. Para obtener detalles adicionales de la API Java, consulte el Javadoc.

por ejemplo,

  1. Para navegar al elemento de sintaxis pertinente del mensaje XML:
        MbElement rootElement = assembly.getMessage().getRootElement();
        MbElement switchElement = 
    			rootElement.getLastChild().getFirstChild().getFirstChild();
  2. Para seleccionar el terminal indicado por el valor de este elemento:
        String terminalName;
        String elementValue = (String)switchElement.getValue();
        if(elementValue.equals("add"))
          terminalName = "add";
        else if(elementValue.equals("change"))
          terminalName = "change";
        else if(elementValue.equals("delete"))
          terminalName = "delete";
        else if(elementValue.equals("hold"))
          terminalName = "hold";
        else
          terminalName = "failure";
        
        MbOutputTerminal out = getOutputTerminal(terminalName);

Transformación de un objeto de mensaje

Dado que el mensaje de entrada recibido es de sólo lectura, para poder transformar el mensaje deberá escribirlo en un nuevo mensaje de salida. Puede copiar los elementos del mensaje de entrada o puede crear elementos nuevos y conectarlos al mensaje. Los elementos nuevos están generalmente en el dominio de un analizador.

La clase MbMessage proporciona los constructores de copia y los métodos para obtener el elemento raíz del mensaje. La clase MbElement proporciona la interfaz con los elementos de sintaxis.

Por ejemplo, cuando tenga un conjunto de mensajes de entrada con mensajes incorporados:
  1. Cree una copia nueva del conjunto de mensajes y de los mensajes incorporados:
        MbMessage newMsg = new MbMessage(assembly.getMessage());
        MbMessageAssembly newAssembly = new MbMessageAssembly(assembly, newMsg);
  2. Navegue al elemento de sintaxis pertinente del mensaje XML:
        MbElement rootElement = newAssembly.getMessage().getRootElement();
        MbElement switchElement = 
    			rootElement.getFirstElementByPath("/XML/data/action");
  3. Cambie el valor de un elemento existente:
      String elementValue = (String)switchElement.getValue();
        if(elementValue.equals("add"))
          switchElement.setValue("change");
        else if(elementValue.equals("change"))
          switchElement.setValue("delete");
        else if(elementValue.equals("delete"))
          switchElement.setValue("hold");
        else
          switchElement.setValue("failure");
  4. Añada un código nuevo como hijo del código de conmutación:
        MbElement tag = switchElement.createElementAsLastChild(MbElement.TYPE_NAME,
                                                               "PreviousValue",
                                                               elementValue);
  5. Añada un atributo a este nuevo código:
        tag.createElementAsFirstChild(MbElement.TYPE_NAME_VALUE,
                                      "NewValue",
                                      switchElement.getValue());
    
        MbOutputTerminal out = getOutputTerminal("out");
Como parte de la transformación, puede ser necesario crear un nuevo cuerpo de mensaje. Para crear un nuevo cuerpo de mensaje, están disponibles los siguientes métodos:
createElementAfter
createElementAsFirstChild
createElementAsLastChild
createElementBefore
createElementAsLastChildFromBitstream
Deben utilizarse estos métodos porque son específicos para asignar un analizador a una carpeta de árbol de mensaje.
Al crear un cuerpo de mensaje, no utilice los siguientes métodos porque no asocian un analizador propietario con la carpeta:
createElementAfter
createElementAfter
createElementAsFirstChild
createElementAsFirstChild
createElementAsLastChild
createElementAsLastChild
createElementBefore
createElementBefore 

Acceso a ESQL

Los nodos pueden invocar expresiones ESQL utilizando la sintaxis ESQL del nodo Compute. Puede crear y modificar los componentes del mensaje utilizando expresiones ESQL y puede hacer referencia a los elementos del mensaje de entrada y de los datos de una base de datos externa.

El procedimiento siguiente muestra cómo controlar las transacciones en el nodo definido por el usuario utilizando ESQL:
  1. Establezca el nombre del origen de datos ODBC que se debe utilizar. Por ejemplo:
    String dataSourceName = "miOrigenDatos";
  2. Establezca la sentencia ESQL que se debe ejecutar:
    String statement = 
       "SET OutputRoot.XML.data = 
              (SELECT Field2 FROM Database.Table1 WHERE Field1 = 1);";
    O, si desea ejecutar una sentencia que no devuelva ningún resultado:
    String statement = "PASSTHRU(
                            'INSERT INTO Database.Table1 VALUES(
                                 InputRoot.XML.DataField1,
                                 InputRoot.XML.DataField2)');";
  3. Seleccione el tipo de transacción que desea entre las siguientes:
    MbSQLStatement.SQL_TRANSACTION_COMMIT
    Confirmar inmediatamente la transacción cuando se haya ejecutado la sentencia ESQL.
    MbSQLStatement.SQL_TRANSACTION_AUTO
    Confirmar la transacción cuando se haya completado el flujo de mensajes. (Si es necesario se realizan restituciones.)
    Por ejemplo:
    int transactionType = MbSQLStatement.SQL_TRANSACTION_AUTO;
  4. Obtenga la sentencia ESQL. Por ejemplo:
    MbSQLStatement sql = 
           createSQLStatement(dataSourceName, statement, transactionType);
    Puede utilizar el método createSQLStatement(dataSource, statement) para tomar por omisión el tipo de transacción MbSQLStatement.SQL_TRANSACTION_AUTO).
  5. Cree el conjunto de mensajes nuevos que se debe propagar:
    MbMessageAssembly newAssembly = 
           new MbMessageAssembly(assembly, assembly.getMessage());
  6. Ejecute la sentencia ESQL:
    sql.select(assembly, newAssembly);
    O, si desea ejecutar una sentencia ESQL que no devuelva ningún resultado:
    sql.execute(assembly);

Si desea ver más información sobre ESQL, consulte el apartado Visión general de ESQL.

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

Propagación del mensaje

Antes de propagar un mensaje, tiene que decidir qué datos de flujo de mensajes desea propagar y cuál de los terminales del nodo debe recibir los datos. Debe finalizar el mensaje antes de propagarlo. Después de propagar un mensaje, deberá suprimir el mensaje de salida.

Por ejemplo:
  1. Para propagar el mensaje al terminal de salida "out":
    MbOutputTerminal out = getOutputTerminal("out");
            out.propagate(newAssembly);
  2. Para suprimir el mensaje de salida:
      newMsg.clearMessage();	

Grabación en un dispositivo de salida

Para grabar en un dispositivo de salida, es necesario volver a convertir el mensaje lógico (jerárquico) a una corriente de bits. Para realizar esta tarea utilice el método getBuffer en MbMessage, como se indica a continuación:

public void evaluate( MbMessageAssembly assembly, MbInputTerminal in)
                                                     throws MbException
{
  MbMessage msg = assembly.getMessage();
  byte[] bitstream = msg.getBuffer();

  // grabar la corriente de bits en algún lugar
  writeBitstream( bitstream );   // método de usuario

 }

Normalmente, dado que para un nodo de salida el mensaje no se propaga a ningún terminal de salida, simplemente puede volver a este punto.

Nota: Debe utilizar el nodo MQOutput proporcionado cuando grabe en las colas de WebSphere MQ, porque el intermediario mantiene internamente una conexión de WebSphere MQ y manejadores de cola abiertos de hebra en hebra, y éstas se colocan en la memoria caché para optimizar el rendimiento. Además, el intermediario maneja escenarios de recuperación cuando se producen determinados sucesos de WebSphere MQ y esto se verá afectado de forma adversa si se utilizan llamadas de WebSphere MQ MQI en un nodo de salida definido por el usuario.
Avisos | Marcas registradas | Descargas | Biblioteca | Soporte | Su opinión
Copyright IBM Corporation 1999, 2005 Última actualización: 11/11/2005
as24990_