Manipulación de mensajes del dominio BLOB

Este apartado proporciona información específica para trabajar con mensajes que pertenezcan al dominio BLOB y que sean analizados por el analizador BLOB.

El contenido de un mensaje BLOB no se puede manipular debido a que no tiene una estructura predefinida. No obstante, puede hacer referencia a su contenido utilizando su posición conocida dentro de la corriente de bits, y procesar el mensaje con un conocimiento mínimo sobre su contenido.

El analizador del texto del mensaje BLOB no crea una estructura de árbol del mismo modo que otros analizadores de textos de mensajes. Tiene un elemento raíz BLOB, que tiene un elemento hijo llamado también BLOB, que contiene los datos.

Puede hacer referencia al contenido de un mensaje utilizando subseries si conoce la ubicación de una parte de la información dentro de los datos BLOB. Por ejemplo, la siguiente expresión identifica el décimo byte del texto del mensaje.

InputBody.BLOB.BLOB[10]

La siguiente expresión hace referencia a 10 bytes de datos del mensaje empezando en la posición 10:

SUBSTRING(InputBody.BLOB.BLOB from 10 for 10)

Ejemplo de manipulación de un mensaje BLOB

Este ejemplo explica cómo manipular un mensaje BLOB de longitud variable. En el ejemplo se supone que se ha configurado un flujo de mensajes que recibe un mensaje BLOB de longitud variable, analiza algunos de los campos invocando el analizador MRM y direcciona el mensaje de salida a la cola de mensajes correcta basándose en la información analizada.

El mensaje de entrada está en formato BLOB y se da por supuesto que contiene nulos NULL ('x00') insertados, por lo que no puede definirse como terminado por nulo.

Este ejemplo muestra el ESQL necesario para:

  • Calcular la longitud del mensaje BLOB
  • Convertirlo al formato hexadecimal
  • Añadirlo al principio del mensaje BLOB

De este modo, puede definir el modelo de mensaje con un campo de longitud de entero seguido del mensaje BLOB.

Este ejemplo también muestra cómo convertir el mensaje BLOB a CWF, procesar el mensaje y quitar el campo de longitud añadido.

En este ejemplo el registro de entrada tiene el siguiente formato:

  • Número de versión: serie de caracteres, 11 caracteres.
  • Número de almacén: serie de caracteres, 10 caracteres

    Este campo se utiliza como un entero para direccionar el mensaje a colas distintas, según criterios definidos por el cliente.

  • Dato de almacén: datos binarios de longitud variable

Definición de un nuevo mensaje

Defina un nuevo mensaje BLOB_Example que incluya los siguientes elementos y tipos:

  • B_LEN, xsd:integer
  • VERSION_NUM, xsd:string, Length 11
  • STORE_NUM, xsd:string, Length 10
  • BIN_BLOB, xsd:binary, Length Value B_LEN

Creación de un flujo de mensajes

Este apartado explica las características del flujo de mensajes. Si desea implementar este flujo de ejemplo, deberá completar la definición del flujo de mensajes (por ejemplo, creando los tres subflujos para sustituir los nodos de salida utilizados aquí para gestionar casos de falsedad, desconocimiento y anomalía) y proporcionar el soporte necesario para su despliegue y ejecución (por ejemplo, creando las colas de entrada y de salida en el gestor de colas correspondiente al intermediario para el que se despliega el flujo).

  1. Cree el subflujo LESS_THAN. Esta tarea está descrita en el apartado Crear subflujo LESS_THAN.
  2. Cree un nuevo flujo de mensajes. Añada nodos a la vista del editor del flujo de mensajes: un nodo MQInput, un nodo Compute, un nodo ResetContentDescriptor, un nodo Filter, nodos MQOutput de árbol y el subflujo LESS_THAN.
  3. Cambie el nombre del nodo MQInput por INQUEUE y establezca su propiedad Queue name en INQUEUE.
  4. Conecte el terminal de salida en el nodo Compute.
  5. Cambie el nombre del nodo Compute de su valor por omisión a Add_length. Configure el nodo de cálculo para calcular la longitud de BIN_BLOB y añádala al principio del mensaje BLOB_Example en el campo B_LEN:
    1. Pulse el botón derecho del ratón sobre el nodo y pulse en Abrir ESQL.
    2. Codifique el siguiente ESQL en el módulo para este nodo:
      -- Declare variables locales
      DECLARE I      INTEGER 1;
      DECLARE J      INTEGER CARDINALITY(InputRoot.*[]);
      DECLARE MSGLEN CHARACTER; 
      DECLARE NUMBER INTEGER; 
      DECLARE RESULT INTEGER; 
      DECLARE REM    INTEGER; 
      
      -- Copie cabeceras de mensajes
      WHILE I < J DO
        SET OutputRoot.*[I] = InputRoot.*[I];
        SET I = I + 1;
      END WHILE;
      -- 
      -- Establezca MSGLEN en NULL para evitar errores cuando efectúe la concatenación por primera vez -- 
      SET MSGLEN = 'X'; 
      -- 
      -- Obtenga la longitud del BLOB y reste la longitud de VERSION_NUM y STORE_NUM (11+10) 
      SET NUMBER = LENGTH("InputRoot"."BLOB"."BLOB")-21; 
      -- 
      -- Convierta NUMBER en hexadecimal. El resto de dividir por 16 se calcula repetidamente. -- 
      WHILE NUMBER > 15 DO      
         SET RESULT = NUMBER/16;      
         SET REM    = NUMBER - RESULT*16;      
         SET MSGLEN = 
          CASE
            WHEN REM < 10  THEN CAST(REM AS CHARACTER) || MSGLEN               
            WHEN REM = 10  THEN 'A' || MSGLEN              
            WHEN REM = 11  THEN 'B' || MSGLEN              
            WHEN REM = 12  THEN 'C' || MSGLEN              
            WHEN REM = 13  THEN 'D' || MSGLEN               
            WHEN REM = 14  THEN 'E' || MSGLEN              
            ELSE                'F' || MSGLEN          
          END;      
         SET NUMBER = RESULT; 
      END WHILE; 
      SET REM = NUMBER;     
      SET MSGLEN =           
         CASE                
           WHEN REM < 10  THEN CAST(REM AS CHARACTER) || MSGLEN               
           WHEN REM = 10  THEN 'A' || MSGLEN              
           WHEN REM = 11  THEN 'B' || MSGLEN              
           WHEN REM = 12  THEN 'C' || MSGLEN              
           WHEN REM = 13  THEN 'D' || MSGLEN               
           WHEN REM = 14  THEN 'E' || MSGLEN              
           ELSE                'F' || MSGLEN          
         END; 
      -- 
      -- Añada ceros ('0') de cabecera hasta llegar a una longitud de 9 para poder efectuar una transformación CAST como BLOB. 
      -- Recuerde que empezó con MSGLEN establecido en X (longitud 1) 
      WHILE LENGTH(MSGLEN) < 9 DO       
         SET MSGLEN = '0' || MSGLEN; END WHILE; 
      -- 
      -- Cambie por el endian adecuado (PLATFORM DEPENDENT) 
      -- Si no es necesario un intercambio de endian, acuérdese de deshacerse del último carácter, como se indica a continuación -- 
      SET MSGLEN = SUBSTRING(MSGLEN FROM 1 FOR 8); 
      -- 
      SET MSGLEN = SUBSTRING(MSGLEN FROM 7 FOR 2) || SUBSTRING(MSGLEN FROM 5 FOR 2) ||
                   SUBSTRING(MSGLEN FROM 3 FOR 2) || SUBSTRING(MSGLEN FROM 1 FOR 2);
      SET "OutputRoot"."BLOB"."BLOB" = CAST(MSGLEN AS BLOB) || "InputRoot"."BLOB"."BLOB"; 
      
  6. Conecte el terminal out (de salida) del nodo Compute al nodo ResetContentDescriptor.
  7. Cambie el nombre del nodo ResetContentDescriptor por ResetContent_2_MRM. Configure el nodo como sigue:
    1. Establezca Message Domain en MRM.
    2. Seleccione el recuadro de selección Reset Message Domain.
    3. Establezca Message Set en el identificador del conjunto de mensajes en el que definió el mensaje BLOB_Example.
    4. Seleccione el recuadro de selección Reset Message Set.
    5. Establezca Message Type en BLOB_Example.
    6. Seleccione el recuadro de selección Reset Message Type.
    7. Establezca en el nombre del formato físico CWF que ha definido (por ejemplo, el valor por omisión CWF1).
    8. Seleccione el recuadro de selección Reset Message Format.
  8. Conecte el terminal out (de salida) del nodo ResetContentDescriptor al nodo Filter.
  9. Cambie el nombre del nodo Filter por Route_2_QUEUE. Configure el nodo como sigue:
    1. Pulse el botón derecho del ratón sobre el nodo y pulse en Abrir ESQL.
    2. Codifique la siguiente sentencia ESQL en el módulo ESQL para este nodo:
      CAST("Body"."e_STORE_NUM" AS INTEGER) < 151    

      Esta sentencia se basa en presuposición de que un mensaje entrante de un número de almacén (Store Number) es menor que 151 y se direcciona a una cola específica. Puede codificar cualquier otra prueba adecuada.

  10. Conecte los terminales de salida de Filter como sigue:
    1. Terminal verdadero para un nodo de subflujo (ver abajo) llamado LESS_THAN.
    2. Terminal falso para un nodo MQOutput llamado GREATER_THAN con la propiedad Queue Name establecida en GREATER_THAN.
    3. Terminal desconocido para un nodo MQOutput llamado INVALID con la propiedad Queue Name establecida en INVALID.
    4. Error en un nodo MQOutput llamado ERROR con la propiedad Queue Name establecida en ERROR.

Crear subflujo LESS_THAN

Este subflujo maneja un mensaje que tiene el formato esperado (la prueba realizada en el nodo Filter ha devuelto el valor true (verdadero)). El mensaje satisfactorio se graba en la cola de salida en su formato original; el mensaje vuelve a convertirse en BLOB desde MRM y los cuatro bytes que se añadieron (campo B_LEN) se eliminan.

Para este subflujo:

  1. Cree un nuevo flujo de mensajes llamado LESS_THAN.
  2. En la vista del editor, añada un nodo Input, un nodo ResetContentDescriptor, un nodo Compute y un nodo MQOutput.
  3. Cambie el nombre del nodo Input por InputTerminal1 y conecte su terminal de salida (out terminal) por el nodo ResetContentDescriptor.
  4. Cambie el nombre de ResetContentDescriptor por ResetContent_2_BLOB y configure el nodo:
    1. Establezca Message Domain en BLOB
    2. Seleccione el recuadro de selección Reset Message Domain.
  5. Conecte el terminal out (de salida) del nodo ResetContentDescriptor al nodo Compute.
  6. Cambie el nombre del nodo Compute por Remove_length_BLOB y configure el nodo:
    1. Pulse el botón derecho del ratón sobre el nodo y pulse en Abrir ESQL.
    2. Codifique el siguiente ESQL en el módulo para este nodo:
      -- Copie cabeceras de mensajes
      DECLARE I      INTEGER 1;
      DECLARE J      INTEGER CARDINALITY(InputRoot.*[]);
      
      WHILE I < J DO
        SET OutputRoot.*[I] = InputRoot.*[I];
        SET I = I + 1;
      END WHILE;
      -- 
      -- Elimine el campo de longitud de 4 bytes que añadió anteriormente -- 
      SET "OutputRoot"."BLOB"."BLOB" = SUBSTRING("InputRoot"."BLOB"."BLOB" FROM 5);

      Este nodo Compute elimina los cuatro bytes que se añadieron al principio del mensaje BLOB para soportar su manipulación.

      Tenga en cuenta la utilización de una variable, J, inicializada para el valor de la cardinalidad de las cabeceras existentes en el mensaje. Esto es más eficaz que calcular la cardinalidad en cada iteración del bucle, cosa que sucede si se codifica la siguiente sentencia WHILE:

      WHILE I < CARDINALITY(InputRoot.*[]) DO
  7. Conecte el terminal out (de salida) del nodo Compute al nodo MQOutput.
  8. Cambie el nombre del nodo MQOutput por Output_success y configure el nodo, estableciendo Queue Manager Name y Queue Name. Puede resultar útil promocionar estas propiedades del nodo MQOutput de forma que pueda especificarlas a nivel del flujo de mensajes.
Avisos | Marcas registradas | Descargas | Biblioteca | Soporte | Su opinión
Copyright IBM Corporation 1999, 2005 Última actualización: 11/11/2005
ac11640_