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

Antes de empezar

Asegúrese de haber leído y comprendido el tema siguiente:
Después de crear un nodo definido por el usuario, están disponibles las siguientes opciones:
  1. Acceso a los datos de mensaje
  2. Transformación de un objeto de mensaje
  3. Acceso a ESQL
  4. Propagación de un mensaje
  5. Grabación en un dispositivo de salida

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. (Consulte el apartado Funciones de programa de utilidad de nodo en C si desea ver información detallada sobre las funciones de programa de utilidad.)

Los tipos de consulta que probablemente realizará incluyen:
  • Obtención del elemento raíz del objeto de mensaje necesario
  • Acceso a la representación de corriente de bits de un árbol de elementos
  • Navegación por el árbol o consulta del árbol solicitando elementos hijo o hermano por el nombre
  • Obtención del tipo del elemento
  • Obtención del valor del elemento

Por ejemplo, para consultar el nombre y el tipo del primer hijo del cuerpo:

void cniEvaluate( ...               
){                                    
  ...
/* Navegar hasta el elemento de destino */ 
  rootElement = cniRootElement(&rc, message);
  bodyElement = cniLastChild(&rc, rootElement);
  bodyFirstChild = cniFirstChild(&rc, bodyElement);

/* Consultar el nombre y el valor del elemento de destino */
  cniElementName(&rc, bodyFirstChild, (CciChar*)&elementname, sizeof(elementName)); 
  bytes = cniElementCharacterValue(
		&rc, bodyfirstChild, (CciChar*)&eValue, sizeof(eValue));
  ...    
}

Para acceder a la representación de corriente de bits de un árbol de elementos, puede utilizar la función cniElementAsBitstream. Utilizando esta función, puede obtener la representación de corriente de bits de cualquier elemento en un mensaje. Consulte cniElementAsBitstream para obtener detalles sobre cómo utilizar esta función y código de ejemplo.

Transformación de un objeto de mensaje

Dado que el mensaje de entrada recibido es de sólo lectura, para poder transformar un mensaje deberá escribirlo en un mensaje de salida nuevo utilizando la función cniCreateMessage. 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.

Por ejemplo:
  1. Para escribir el mensaje de entrada en un mensaje nuevo:
    {
      ...
      context = cniGetMessageContext(&rc, message)); 
      outMsg = cniCreateMessage(&rc, context)); 
      ...
    }
  2. Para hacer una copia del mensaje nuevo:
    cniCopyElementTree(&rc, sourceElement, targetElement);
  3. Para modificar el valor de un elemento de destino:
      cniSetElementIntegerValue(&rc, targetElement, L"newValue", 8); 
  4. Después de finalizar y propagar el mensaje, deberá suprimir el mensaje de salida utilizando la función cniDeleteMessage:
     cniDeleteMessage(&rc, outMsg);
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 las siguientes funciones:
cniCreateElementAsFirstChildUsingParser
cniCreateElementAsLastChildUsingParser
cniCreateElementAfterUsingParser
cniCreateElementBeforeUsingParser
Deben utilizarse estas funciones porque son específicas para asignar un analizador a una carpeta de árbol de mensaje.
Al crear un cuerpo de mensaje, no utilice las siguientes funciones porque no asocian un analizador propietario con la carpeta:
cniCreateElementAsFirstChild
cniCreateElementAsLastChild
cniCreateElementAfter
cniCreateElementBefore

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 utilizando las funciones cniSqlCreateStatement, cniSqlSelect, cniSqlDeleteStatement y cniSqlExecute.

Por ejemplo, para llenar el elemento de resultado a partir del contenido de una columna de una tabla de base de datos:

{
  ...
  sqlExpr = cniSqlCreateStatement(&rc, 
   (NODE_CONTEXT_ST *)context->nodeObject,
   L"DB", CCI_SQL_TRANSACTION_AUTO,
   L"SET OutputRoot.XML.Result[] = (SELECT T.C1 AS Col1 FROM Database.TABLE AS T;");
  ...
  cniSqlSelect(&rc, sqlExpr, destinationList, exceptionList, message, outMsg);
  cniSqlDeleteStatement(&rc, sqlExpr);
  ...                                                               
}

Para obtener más información sobre ESQL, consulte el apartado Visión general de ESQL.

Si su nodo definido por el usuario utiliza principalmente ESQL, piense en utilizar un nodo Compute, consulte Nodo Compute.

Propagación de un mensaje

Antes de propagar el mensaje, tiene que decidir qué datos de flujo de mensaje desea propagar y qué terminal debe recibir los datos.
  1. Si el mensaje ha cambiado, deberá finalizar el mensaje antes de propagarlo utilizando la función cniFinalize. Por ejemplo:
          cniFinalize(&rc, outMsg, CCI_FINALIZE_NONE);
  2. El objeto de terminal (terminalObject) se deriva de una lista mantenida por el propio nodo definido por el usuario. Para propagar el mensaje al terminal de salida, utilice la función cniPropagate:
      if (terminalObject) {
        if (cniIsTerminalAttached(&rc, terminalObject)) {
          if (rc == CCI_SUCCESS) {
            cniPropagate(&rc, terminalObject, destinationList, exceptionList, outMsg);
          }
        }

    En el ejemplo anterior, se utiliza la función cniIsTerminalAttached para probar si se puede propagar el mensaje al terminal especificado. Si no utiliza la función cniIsTerminalAttached y el terminal no está conectado a otro nodo por un conector, el mensaje no se propaga y no se devuelve ningún mensaje de aviso. Utilice la función cniIsTerminalAttached para evitar que esto suceda.

  3. Si ha creado un mensaje de salida nuevo utilizando cniCreateMessage, después de propagar el mensaje, deberá suprimir el mensaje de salida utilizando la función cniDeleteMessage:
     cniDeleteMessage(&rc, outMsg);

Grabación en un dispositivo de salida

Un mensaje transformado necesita serializarse en una corriente de bits. Entonces se puede acceder a la corriente de bits y ésta se puede grabar en un dispositivo de salida. El mensaje se graba en una corriente de bits utilizando la función cniWriteBuffer. Por ejemplo:
{
  ...
  cniWriteBuffer(&rc, message);
  writeToDevice(cniBufferPointer(&rc, message), cniBufferSize(&rc, message));
  ...                                                               
}
En este ejemplo, el método writeToDevice es un método escrito por el usuario que escribe una corriente de bits en un dispositivo de salida.

Tenga en cuenta que un mensaje sólo se puede serializar una vez.

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, 2006 Última actualización: 22/08/2006
as24989_