Estendendo o Recurso de um Nó de Entrada Java

Antes de começar

Assegure-se de que tenha lido e entendido os tópicos a seguir:
Depois de criar um nó definido pelo usuário, as seguintes funções estarão disponíveis:
  1. Recebendo Dados Externos em um Buffer
  2. Propagando a Mensagem
  3. Controlando o Encadeamento e a Transacionalidade
  4. Tratando Exceções

Recebendo Dados Externos em um Buffer

Um nó de entrada pode receber dados de qualquer tipo de origem externa, tal como um sistema de arquivos, uma fila ou um banco de dados, da mesma maneira que qualquer outro programa Java, desde que a saída do nó esteja no formato correto.

Você fornece um buffer de entrada (ou fluxo de bits) para conter os dados de entrada e o associa a um objeto de mensagem. Você cria uma mensagem a partir de uma matriz de bytes utilizando o método createMessage da classe MbInputNode e, em seguida, gera uma montagem de mensagem válida a partir dessa mensagem. Para obter detalhes destes métodos, consulte a API Java. Por exemplo, para ler a entrada de um arquivo:

  1. Crie um fluxo de entrada para ler do arquivo:
    FileInputStream inputStream = new FileInputStream("myfile.msg");
  2. Crie uma matriz de bytes do tamanho do arquivo de entrada:
    byte[] buffer = new byte[inputStream.available()];
  3. Leia do arquivo para a matriz de bytes:
    inputStream.read(buffer);
  4. Feche o fluxo de entrada:
    inputStream.close();
  5. Crie uma mensagem para colocar na fila:
    MbMessage msg = createMessage(buffer);
  6. Crie um novo conjunto de mensagem para receber esta mensagem:
    msg.finalizeMessage(MbMessage.FINALIZE_VALIDATE);
    MbMessageAssembly newAssembly = 
              new MbMessageAssembly(assembly, msg);

Propagando a Mensagem

Quando tiver criado um conjunto de mensagem, você poderá propagá-lo para um dos terminais do nó.

Por exemplo, para propagar o conjunto da mensagem para o terminal "out":
MbOutputTerminal out = getOutputTerminal("out");
out.propagate(newAssembly);

Controlando o Encadeamento e a Transacionalidade

A infra-estrutura do intermediário trata de questões de transação tais como controlar a consolidação de qualquer unidade de trabalho do WebSphere MQ ou de banco de dados quando o processamento da mensagem estiver concluído. Entretanto, se um nó definido pelo usuário for utilizado, quaisquer atualizações de recursos não podem ser automaticamente consolidadas pelo intermediário.

Cada encadeamento do fluxo de mensagens é alocado de um conjunto de encadeamentos mantido para cada fluxo de mensagens, e inicia a execução no método run.

O nó definido pelo usuário utiliza valores de retorno para indicar se uma transação obteve êxito, para controlar se as transações são consolidadas ou retornadas e para controlar quando o encadeamento é retornado ao conjunto. Quaisquer exceções não tratadas são capturadas pela infra-estrutura do intermediário e a transação é revertida.

O comportamento das transações e encadeamentos é determinado utilizando um valor de retorno apropriado entre os seguintes:

MbInputNode.SUCCESS_CONTINUE
A transação é consolidada e o intermediário chama o método run novamente utilizando o mesmo encadeamento.
MbInputNode.SUCCESS_RETURN
A transação é consolidada e o encadeamento é retornado ao conjunto de encadeamentos, supondo que ele não seja o único encadeamento para este fluxo de mensagens.
MbInputNode.FAILURE_CONTINUE
A transação é retornada e o intermediário chama o método run novamente utilizando o mesmo encadeamento.
MbInputNode.FAILURE_RETURN
A transação é retornada e o encadeamento é retornado ao conjunto de encadeamentos, supondo que ele não seja o único encadeamento para este fluxo de mensagens.
MbInputNode.TIMEOUT
O método run não deve bloquear indefinidamente enquanto aguarda que os dados de entrada cheguem. Enquanto o fluxo estiver bloqueado pelo código do usuário, você não poderá encerrar ou reconfigurar o intermediário. O método run deve conceder controle ao intermediário periodicamente, retornando do método run. Se os dados de entrada não tiverem sido recebidos após um certo período (por exemplo, 5 segundos), o método deve retornar com o código de retorno TIMEOUT. Supondo que o intermediário não necessite reconfigurar ou encerrar, o método run do nó de entrada é chamado de novo imediatamente.
Para criar fluxos de mensagens de múltiplos encadeamentos, o método dispatchThread é chamado após a criação de uma mensagem, mas antes de propagar a mensagem para um terminal de saída. Isso garante que apenas um encadeamento esteja aguardando por dados enquanto outros encadeamentos estão processando a mensagem. Novos encadeamentos são obtidos do conjunto de encadeamentos até o limite máximo especificado pelo atributo additionalInstances do fluxo de mensagens. Exemplo:
public int run( MbMessageAssembly assembly ) throws MbException
{
  byte[] data = getDataWithTimeout();  // usuário abasteceu método
                                       // retorna nulo se for tempo limite
  if( data == null )
        return TIMEOUT;

    MbMessage msg = createMessage( data );
    msg.finalizeMessage( MbMessage.FINALIZE_VALIDATE );
  MbMessageAssembly newAssembly = 
              new MbMessageAssembly( assembly, msg );

  dispatchThread();

    getOutputTerminal( "out" ).propagate( newAssembly );

    return SUCCESS_RETURN;
}

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);
  }
Informações relacionadas
API Java
Avisos | Marcas Registradas | Downloads | Biblioteca | Suporte | Feedback
Direitos Autorais IBM Corporation 1999, 2005 Última Atualização: 04/11/2005
as24987_