Estendendo o Recurso de um Processamento de Mensagens Java ou de Nó de Saída

Antes de começar

Certifique-se de que tenha lido e entendido o seguinte tópico:

Acessando os Dados da Mensagem

Em muitos casos, o nó definido pelo usuário necessita acessar o conteúdo da mensagem recebida em seu terminal de entrada. A mensagem é representada como uma árvore de elementos de sintaxe. Grupos de funções utilitárias são fornecidos para gerenciamento de mensagens, acesso a buffer de mensagem, navegação de elementos de sintaxe e acesso a elementos de sintaxe.

A classe MbElement fornece a interface para os elementos de sintaxe. Para detalhes adicionais sobre a API Java, consulte o Javadoc.

Por exemplo:

  1. Para navegar até o elemento de sintaxe relevante na mensagem XML:
        MbElement rootElement = assembly.getMessage().getRootElement();
            MbElement switchElement = 
    			rootElement.getLastChild().getFirstChild().getFirstChild();
  2. Para selecionar o terminal indicado pelo valor desse 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);

Transformando um Objeto Mensagem

A mensagem de entrada recebida é somente leitura, portanto antes que uma mensagem possa ser transformada é preciso gravá-la para uma nova mensagem de saída. É possível copiar elementos da mensagem de entrada ou criar novos elementos e anexá-los á mensagem. Os novos elementos em geral estão no domínio de um analisador.

A classe MbMessage fornece os construtores de cópia e métodos para obter o elemento raiz da mensagem. A classe MbElement fornece a interface para os elementos de sintaxe.

Por exemplo, onde houver um conjunto de mensagem de entrada com mensagens incorporadas:
  1. Criar uma nova cópia de conjunto de mensagens e suas mensagens incorporadas:
            MbMessage newMsg = new MbMessage(assembly.getMessage());
        MbMessageAssembly newAssembly = new MbMessageAssembly(assembly, newMsg);
  2. Navegar até o elemento de sintaxe relevante na mensagem XML:
        MbElement rootElement = newAssembly.getMessage().getRootElement();
            MbElement switchElement = 
    			rootElement.getFirstElementByPath("/XML/data/action");
  3. Alterar o valor de um 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. Incluir uma nova tag como um filho da tag chave:
        MbElement tag = switchElement.createElementAsLastChild(MbElement.TYPE_NAME,
                                                               "PreviousValue",
                                                                                                                          elementValue);
  5. Incluir um atributo a esta nova tag:
        tag.createElementAsFirstChild(MbElement.TYPE_NAME_VALUE,
                                      "NewValue",
                                      switchElement.getValue());
    
        MbOutputTerminal out = getOutputTerminal("out");
Como parte da transformação, pode ser necessário criar um novo corpo da mensagem. Para criar um novo corpo da mensagem, os seguintes métodos estão disponíveis:
createElementAfter
createElementAsFirstChild
createElementAsLastChild
createElementBefore createElementAsLastChildFromBitstream
Estes métodos devem ser utilizados, porque são específicos para designação de um analisador a uma pasta da árvore de mensagens.
Ao criar um corpo da mensagem, não utilize os seguintes métodos porque eles não associam um analisador de propriedade à pasta:
createElementAfter
createElementAfter
createElementAsFirstChild
createElementAsFirstChild
createElementAsLastChild
createElementAsLastChild
createElementBefore createElementBefore 

Acessando ESQL

Os nós podem chamar expressões ESQL utilizando sintaxe ESQL de nó Compute. É possível criar e modificar os componentes da mensagem utilizando expressões ESQL, e referir-se a elementos da mensagem de entrada e dos dados a partir de um banco de dados externo.

O procedimento a seguir demonstra como controlar transações no nó definido pelo usuário utilizando ESQL:
  1. Defina o nome da origem de dados ODBC a ser utilizada. Exemplo:
    String dataSourceName = "myDataSource";
  2. Defina a instrução ESQL a ser executada:
    String statement = 
          "SET OutputRoot.XML.data = 
                        (SELECT Field2 FROM Database.Table1 WHERE Field1 = 1);";
    Ou, se quiser executar uma instrução que não retorna nenhum resultado:
    String statement = "PASSTHRU(
                                                    'INSERT INTO Database.Table1 VALUES(
                                                              InputRoot.XML.DataField1,
                                                              InputRoot.XML.DataField2)');";
  3. Selecione o tipo de transação que deseja entre os seguintes:
    MbSQLStatement.SQL_TRANSACTION_COMMIT
    Consolide imediatamente a transação após a execução da instrução ESQL.
    MbSQLStatement.SQL_TRANSACTION_AUTO
    Consolide a transação quando o fluxo da mensagem tiver concluído. (Os retornos são executados caso necessário.)
    Exemplo:
    int transactionType = MbSQLStatement.SQL_TRANSACTION_AUTO;
  4. Obtenha a instrução ESQL. Exemplo:
    MbSQLStatement sql = 
                  createSQLStatement(dataSourceName, statement, transactionType);
    Você pode utilizar o método createSQLStatement(dataSource, statement) para definir o tipo de transação como o padrão de MbSQLStatement.SQL_TRANSACTION_AUTO).
  5. Crie o novo conjunto de mensagem a ser propagado:
    MbMessageAssembly newAssembly = 
                  new MbMessageAssembly(assembly, assembly.getMessage());
  6. Execute a instrução ESQL:
    sql.select(assembly, newAssembly);
    Ou, se quiser executar uma instrução ESQL que não retorna nenhum resultado:
    sql.execute(assembly);

Para obter informações adicionais sobre ESQL, consulte Visão Geral do ESQL.

Tratando Exceções

Utilize a classe mbException para capturar e acessar exceções. A classe mbException retorna uma matriz de objetos de exceção que representam os filhos de uma exceção na lista de exceções do intermediário. Cada elemento retornado especifica o tipo de exceção. Uma matriz vazia será retornada se uma exceção não tiver filhos. A seguinte amostra de código mostra um exemplo do uso da classe MbException.

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

        // funcionalidade plug-in

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

                throw ex; // se for uma reemissão, deverá ser a exceção original capturada
      }
  }

    void traverse(MbException ex, int level)
  {
        if(ex != null)
      {
                // Fazer qualquer ação aqui
                System.out.println("Level: " + level);
                System.out.println(ex.toString());
                System.out.println("traceText:  " + ex.getTraceText());

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

Consulte o javadoc para obter detalhes adicionais sobre o uso da classe mbException.

Você pode desenvolver um processamento de mensagens definidas pelo usuário ou nó de saída, de forma que ele possa acessar todas as exceções atuais. Por exemplo, para capturar as exceções do banco de dados você pode utilizar a classe MbSQLStatement. Essa classe define o valor do atributo 'throwExceptionOnDatabaseError', que determina o comportamento do intermediário quando ele encontra um erro no banco de dados. Quando ele for configurado como true, se uma exceção for emitida, ela poderá ser capturada e manuseada pela extensão definida pelo usuário.

A seguinte amostra de código mostra um exemplo de como utilizar a classe 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)
      {
                // Fazer tratamento de erros aqui

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

Propagando a Mensagem

Antes de propagar uma mensagem, você precisa decidir que dados do fluxo de mensagens deseja propagar, e qual dos terminais do nó deve receber os dados. Você deve finalizar a mensagem antes de propagá-la. Depois de propagar uma mensagem, é preciso excluir a mensagem de saída.

Exemplo:
  1. Para propagar a mensagem para o terminal de saída "out":
    MbOutputTerminal out = getOutputTerminal("out");
            out.propagate(newAssembly);
  2. Para excluir a mensagem de saída:
      newMsg.clearMessage();	

Gravando em um Dispositivo de Saída

Para gravar para um dispositivo de saída, a mensagem lógica (hierárquica) precisa ser convertida de volta para um fluxo de bits. Você faz isso utilizando o método getBuffer em MbMessage, da seguinte forma:

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

  // gravar o fluxo de bits para algum lugar
  writeBitstream( bitstream );   // user method

 }

Em geral, para um nó de saída a mensagem não é propagada para nenhum terminal de saída, portanto você pode somente retornar neste ponto.

Nota: É preciso utilizar o nó MQOutput fornecido ao gravar para filas do WebSphere MQ, porque o intermediário mantém internamente uma conexão ao WebSphere MQ e o identificador de filas aberto em uma base encadeamento a encadeamento, e estes são armazenados em cache para otimizar o desempenho. Além disso, o intermediário manipula cenários de recuperação quando determinados eventos WebSphere MQ ocorrem e isso seria afetado de forma adversa se chamadas WebSphere MQ MQI fossem utilizadas em um nó de saída definido pelo usuário.
Referências relacionadas
Estrutura da Lista de Exceções
Informações relacionadas
API de Nó Java Definido Pelo Usuário
Avisos | Marcas Registradas | Downloads | Biblioteca | Suporte | Feedback
Direitos Autorais IBM Corporation 1999, 2005 Última Atualização: 04/11/2005
as24990_