Manipulando Mensagens no Domínio BLOB

Este tópico fornece informações específicas para tratar mensagens que pertencem ao domínio BLOB e que são analisadas pelo analisador BLOB.

Você não pode manipular o conteúdo de uma mensagem BLOB porque ela não possui estrutura predefinida. No entanto, é possível fazer referência a seu conteúdo utilizando sua posição conhecida no fluxo de bits e processar a mensagem com um mínimo de conhecimento de seu conteúdo.

O analisador do corpo da mensagem BLOB não cria uma estrutura de árvore da mesma forma que outros analisadores do corpo da mensagem criam. Ele possui um elemento raiz BLOB, que possui um elemento filho, também chamado de BLOB, que contém os dados.

Você pode fazer referência ao conteúdo da mensagem utilizando subcadeias se souber a localização de um determinado bloco de informações nos dados BLOB. Por exemplo, a expressão a seguir identifica o décimo byte do corpo da mensagem:

InputBody.BLOB.BLOB[10]

A expressão a seguir faz referência a 10 bytes dos dados de mensagens começando no deslocamento 10:

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

Exemplo de Manipulação de Mensagem do BLOB

Este exemplo mostra como é possível manipular uma mensagem BLOB de comprimento variável. O exemplo assume que você configurou um fluxo de mensagens que recebe uma mensagem BLOB de comprimento variável, analisa alguns dos campos chamando o analisador MRM e roteia a mensagem de saída para a fila de saída correta, com base nas informações analisadas.

A mensagem de entrada está em formato BLOB e supõe-se que ela contenha NULLs ('x00') incorporados, e portanto não pode ser definida como terminada em nulo.

Este exemplo mostra o ESQL necessário para:

  • Compute o comprimento da mensagem BLOB
  • Convertê-lo em formato hexadecimal
  • Adicioná-lo ao início da mensagem BLOB

Fazendo isso, você pode definir o modelo de mensagem com um campo de comprimento inteiro, seguido pela mensagem BLOB.

Este exemplo também mostra como converter a mensagem BLOB em CWF, processar a mensagem e remover o campo de comprimento adicionado.

Neste exemplo, o registro de entrada possui o seguinte formato:

  • Número de Versão: cadeia, 11 caracteres
  • Número do Armazenamento: cadeia, 10 caracteres

    Este campo deve ser utilizado como um inteiro para rotear a mensagem para filas diferentes, dependendo dos critérios definidos pelo cliente.

  • Dados de armazenamento: dados binários de comprimento variável

Definir uma Nova Mensagem

Defina uma nova mensagem BLOB_Example que inclua os seguintes elementos e tipos:

  • B_LEN, xsd:integer
  • VERSION_NUM, xsd:string, Comprimento 11
  • STORE_NUM, xsd:string, Comprimento 10
  • BIN_BLOB, xsd:binary, Valor de Comprimento B_LEN

Criar um Fluxo de Mensagens

Esta seção descreve as características do fluxo de mensagens. Se desejar implementar este fluxo de exemplo, será necessário concluir a definição do fluxo de mensagens (por exemplo, criando os três subfluxos para substituir os nós de saída utilizados aqui para tratar casos falsos, desconhecidos e com falha) e fornecer suporte requerido para sua implementação e execução (por exemplo, criação de filas de entrada e de transmissão no gerenciador de filas para o intermediário no qual você implementa o fluxo).

  1. Criar o Subfluxo LESS_THAN. Esta tarefa é descrita em Criar Subfluxo LESS_THAN.
  2. Criar um novo fluxo de mensagens. Inclua nós à visualização do editor do fluxo de mensagens: um nó MQInput, um nó Compute, um nó ResetContentDescriptor, um nó Filter, três nós MQOutput e o subfluxo LESS_THAN.
  3. altere o nome do nó MQInput para INQUEUE e defina sua propriedade Queue Name para INQUEUE.
  4. Conecte o terminal de saída ao nó Compute.
  5. Altere o nome de nó Compute de seu valor padrão para Add_length. Configure o nó Compute para calcular o comprimento de BIN_BLOB e para inclui-lo ao início da mensagem BLOB_Example no campo B_LEN:
    1. Clique com o botão direito no nó e clique em Abrir ESQL.
    2. Codifique o seguinte ESQL no módulo para este código:
      -- Declarar variáveis locais
                               DECLARE I INTEGER 1;
      DECLARE J INTEGER CARDINALITY(InputRoot.*[]);
      DECLARE MSGLEN CHARACTER; 
      DECLARE NUMBER INTEGER; 
      DECLARE RESULT INTEGER; 
      DECLARE REM    INTEGER; 
      
      -- Copiar cabeçalho de mensagens
                               WHILE I < J DO
        SET OutputRoot.*[I] = InputRoot.*[I];
                SET I = I + 1;END WHILE;
      -- 
      -- Definir MSGLEN para não-NULL de forma a evitar erros durante a primeira concatenação --
      SET MSGLEN = 'X'; 
      -- 
      -- Obter o comprimento de BLOB e subtrair o comprimento de VERSION_NUM e STORE_NUM (11+10)
      SET NUMBER = LENGTH("InputRoot"."BLOB"."BLOB")-21; 
      -- 
      -- Converter NUMBER para hexadecimal. O restante de divisão por 16 é calculado repetitivamente.
      -- 
      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;
      -- 
      -- Incluir '0's iniciais até o comprimento de 9, para ser possível lançar como BLOB.
      -- Lembre-se que começou com MSGLEN definido como X (comprimento 1)
      WHILE LENGTH(MSGLEN) < 9 DO       
         SET MSGLEN = '0' || MSGLEN; END WHILE; 
      -- 
      -- Alterar para endian apropriado (PLATFORM DEPENDENT)
      -- Caso não seja necessário alterar o endian, lembre-se de livrar-se do último caractere abaixo --
      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 o terminal de saída do nó Compute ao nó ResetContentDescriptor.
  7. Altere o nome do nó ResetContentDescriptor para ResetContent_2_MRM. Configure o nó da seguinte maneira:
    1. Defina Domínio de Mensagens como MRM.
    2. Selecione a caixa de opções Redefinir Domínio de Mensagem.
    3. Defina Conjunto de Menagens como o identificador do conjunto de mensagens no qual definiu a mensagem BLOB_Example.
    4. Selecione a caixa de opções Redefinir Conjunto de Mensagens.
    5. Defina Tipo de Mensagens como BLOB_Example.
    6. Selecione a caixa de opções Redefinir Tipo da Mensagem.
    7. Defina para o nome do formato físico CWF definido (por exemplo, o valor padrão CWF1).
    8. Selecione a caixa de opções Redefinir Formato da Mensagem.
  8. Conecte o terminal de saída do nó ResetContentDescriptor para o nó Filter.
  9. Altere o nome do nó Filter para Route_2_QUEUE. Configure o nó da seguinte maneira:
    1. Clique com o botão direito no nó e clique em Abrir ESQL.
    2. Codifique a seguinte instrução ESQL no módulo ESQL para este nó:
      CAST("Body"."e_STORE_NUM" AS INTEGER) < 151    

      Esta instrução é baseada na suposição arbitrária de que uma mensagem de entrada de um Número de Armazenamento é menor que 151 e é roteada para uma fila específica. Você pode codificar qualquer outro teste adequado.

  10. Conecte os terminais de saída Filter da seguinte forma:
    1. Terminal True a um nó de subfluxo (consulte abaixo) denominado LESS_THAN.
    2. Terminal False para um nó MQOutput chamado GREATER_THAN com a propriedade Nome da Fila definida como GREATER_THAN.
    3. Terminal Unknown para um nome de nó MQOutput denominado INVALID com a propriedade Nome de Fila definida como INVALID.
    4. Falha para abrir um nó MQOutput denominado ERROR com a propriedade Nome de Fila definida como ERROR.

Criar Subfluxo LESS_THAN

Esse subfluxo trata uma mensagem que tem o formato esperado (o teste executado no nó Filter retornou true). A mensagem bem-sucedida é gravada na fila de saída em seu formato original; a mensagem é convertida novamente em BLOB a partir de MRM e os quatro bytes que foram incluídos (campo B_LEN) são removidos.

Para esse subfluxo:

  1. Crie um novo fluxo de mensagens denominado LESS_THAN.
  2. Na visualização do editor, adicione um nó Input, um nó ResetContentDescriptor, um nó Compute e um nó MQOutput.
  3. Altere o nome do nó Input para InputTerminal1 e conecte seu terminal de saída ao nó ResetContentDescriptor.
  4. Altere o nome do ResetContentDescriptor para ResetContent_2_BLOB e configure o nó:
    1. Defina Domínio de Mensagens como BLOB
    2. Selecione a caixa de opções Redefinir Domínio de Mensagem.
  5. Conecte o terminal de saída do ResetContentDescriptor ao nó Compute.
  6. Altere o nome do nó Compute para Remove_length e configure o nó:
    1. Clique com o botão direito no nó e clique em Abrir ESQL.
    2. Codifique o seguinte ESQL no módulo para este código:
      -- Copiar cabeçalho de mensagens
                               DECLARE I INTEGER 1;
      DECLARE J INTEGER CARDINALITY(InputRoot.*[]);
      
                               WHILE I < J DO
        SET OutputRoot.*[I] = InputRoot.*[I];
                SET I = I + 1;END WHILE;
      -- 
      -- Remover o campo com comprimento de 4 bytes incluído anteriormente --
      SET "OutputRoot"."BLOB"."BLOB"
      = SUBSTRING("InputRoot"."BLOB"."BLOB" FROM 5);

      Este nó Compute remove os quatro bytes que foram adicionados ao início da mensagem BLOB para suportar sua manipulação.

      Observe a utilização de uma variável J, inicializada para o valor da cardinalidade dos cabeçalhos existentes na mensagem. Isso é mais eficiente do que calcular a cardinalidade em cada iteração do loop, que ocorre se você codificar a seguinte instrução WHILE:

      WHILE I < CARDINALITY(InputRoot.*[]) DO
  7. Conecte o terminal de saída do nó Compute ao nó MQOutput.
  8. Altere o nome do nó MQOutput para Output_success e configure o o nó, definindo Nome do Gerenciador de Filas e Nome da Fila. Você pode achar útil promover estas propriedades do nó MQOutput para que seja possível especificá-las no nível do fluxo de mensagens.

Conceitos relacionados
Fluxos de Mensagem
Domínio e Analisador BLOB
Propriedades Promovidas
ESQL
Modelagem de Mensagens

Tarefas relacionadas
Projetando um Fluxo de Mensagens
Definindo o Conteúdo do Fluxo de Mensagens
Configurando um Nó
Gerenciando Arquivos ESQL
Definindo Propriedades Promovidas

Referências relacionadas
Nó Compute
Nó Database
Nó Filter
Nó MQInput
Nó MQOutput
Nó ResetContentDescriptor
ESQL
Função CARDINALITY
Função CASE
Função CAST
Instrução DECLARE
Instrução SET
Função SUBSTRING
Instrução WHILE