Archive for the ‘SOA’ Category.

Fault Policy no MDS com Java Action – Parte 2

Na primeira parte, preparamos os arquivos de fault policy e a classe Java que irá receber as informações de falha para tratativa. Agora queremos adicionar os XMLs de fault ao MDS do SOA para facilitar a localização e manutenção destes arquivos, que poderão ser utilizados por todos os projetos SOA que forem tratar exceções.

Bem, uma vez que os arquivos de Fault Policy estejam concluídos (fault-policies.xml e fault-bindings.xml) você deverá empacotá-los em um arquivo Jar.

Crie um diretório qualquer chamado Fault_Policy_Arquivos, neste diretório iremos montar a estrutura que irá ser armazenada no MDS Database, então crie os sub-diretórios na estrutura abaixo:



No prompt de comando/terminal, vá até o diretório raiz e execute o comando para criação do arquivo Jar.

jar -cf blog-faultpolicy-MDS.jar ./apps/blog/fault/*.xml

Pronto, agora vamos fazer o deploy do arquivo blog-faultpolicy-MDS.jar com as estrutura do Fault Policy no MDS.
Acesse o Enterprise Manager do servidor, clique com o botão direito em soa-infra e depois vá para Administração e por fim clique em Configuração de MDS.


Na tela de Configuração de MDS, em Importar documentos de metadados de um arquivo, selecione o blog-faultpolicy-MDS.jar que acabamos de criar e clique no botão Importar. That’s all! Não é necessário reiniciar o Weblogic!

Para utilizar o fault policy no seu projeto SOA, edite o arquivo composite.xml e adicione os comandos baixo antes da tab component.

  <property name="oracle.composite.faultPolicyFile">oramds:/apps/blog/fault/fault-policies.xml</property>
  <property name="oracle.composite.faultBindingFile">oramds:/apps/blog/fault/fault-bindings.xml</property>

Isto é o suficiente para que seu projeto utilize o fault policy com Java Class Action, configurada no MDS.

Arquivos para Download:
Projeto Jdev (Exemplo de BPEL)
Estrutura de Diretórios para o MDS
Arquivo JAR para o MDS

Fault Policy no MDS com Java Action – Parte 1

Este exemplo esta dividido em duas partes, nessa primeira parte vou demonstrar como configurar os arquivos de Fault Policy chamando uma Java Class Custom como Action para o fault. Já na segunda parte vamos ver como adicionar a configuração ao MDS do SOA, facilitando o acesso e manutenção ao fault policy.

1. Definindo o Fault Policy


Vamos começar com o exemplo de configuração dos arquivos para o Fault Policy, veja a construção dos arquivos fault-policies.xml e fault-bindings.xml

Exemplo para o arquivo fault-policies.xml.

...
<Conditions>
      <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
                 name="bpelx:remoteFault">
        <condition>
          <action ref="ora-custom-retry"/>
        </condition>
      </faultName>
      <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
                 name="bpelx:bindingFault">
        <condition>
          <action ref="ora-custom-retry"/>
        </condition>
      </faultName>
    </Conditions>
    <Actions>
      <Action id="ora-custom-retry">
        <javaAction className="com.lucianosilva.lab.soa.CompositeFaultHandler"
                    defaultAction="ora-human-intervention">
            <returnValue value="ERROR" ref="ora-terminate"/>
            <returnValue value="ABORT" ref="ora-terminate"/>
            <returnValue value="RETRY" ref="ora-retry"/>
            <returnValue value="MANUAL" ref="ora-human-intervention"/>
        </javaAction>
      </Action>
            <Action id="ora-retry">
          <retry>
              <retryCount>2</retryCount>
              <retryInterval>3</retryInterval>
              <exponentialBackoff/>
          </retry>
      </Action>
      <Action id="ora-replay-scope">
          <replayScope/>
      </Action>
      <Action id="ora-rethrow-fault">
          <rethrowFault/>
      </Action>
      <Action id="ora-human-intervention">
          <humanIntervention/>
      </Action>
      <Action id="ora-terminate">
          <abort/>
      </Action>
    </Actions>
...

Definição do arquivo fault-bindings.xml.

<?xml version="1.0" encoding="UTF-8" ?>
<faultPolicyBindings version="2.0.1" xmlns="http://schemas.oracle.com/bpel/faultpolicy" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <composite faultPolicy="fault-policies"/>
</faultPolicyBindings>

2. Java Action Class

Agora, com os arquivos de policy definidos, vamos construir a classe que irá receber a exception ocorrida no BPEL. No seu projeto adicione as duas classes orabpel.jar e fabric-runtime.jar, se você utiliza o JDeveloper configure-o como a imagem abaixo.

package com.lucianosilva.lab.soa;

import java.util.Collection;
import java.util.Map;

import oracle.integration.platform.faultpolicy.IFaultRecoveryContext;
import oracle.integration.platform.faultpolicy.IFaultRecoveryJavaClass;
import com.collaxa.cube.engine.fp.BPELFaultRecoveryContext;

/**
 * @author luciano silva
 *
 */
public class CompositeFaultHandler implements IFaultRecoveryJavaClass {

    private static final String RETURN_ERROR  = "ERROR";
    private static final String RETURN_MANUAL = "MANUAL";
    private static final String RETURN_RETRY  = "RETRY";

    /**
     *
     */
    public CompositeFaultHandler() {
        super();
    }

    /**
     *
     * @param iFaultRecoveryContext
     * @return
     */
    public String handleFault( IFaultRecoveryContext iFaultRecoveryContext ) {

        // print all fault details
        System.out.println("==========");
        System.out.println("Fault Policy Id : " + iFaultRecoveryContext.getPolicyId());
        System.out.println("Fault Type      : " + iFaultRecoveryContext.getType());
        System.out.println("Partnerlink     : " + iFaultRecoveryContext.getReferenceName());
        System.out.println("Port Type       : " + iFaultRecoveryContext.getPortType());

        if( iFaultRecoveryContext instanceof BPELFaultRecoveryContext ){
            //
            BPELFaultRecoveryContext bctx = (BPELFaultRecoveryContext) iFaultRecoveryContext;

            System.out.println("BPEL ActionId       : " + bctx.getActionId() );
            System.out.println("BPEL ActivityId     : " + bctx.getActivityId() );
            System.out.println("BPEL ActivityName   : " + bctx.getActivityName() );
            System.out.println("BPEL ActivityType   : " + bctx.getActivityType() );
            System.out.println("BPEL CorrelationId  : " + bctx.getCorrelationId() );
            System.out.println("BPEL PartnerLinkName: " + bctx.getPartnerLinkName() );
            System.out.println("BPEL Fault  : " + bctx.getFault().getFaultName() );
            System.out.println( bctx.getFault().getMessage() );
        }

        if( iFaultRecoveryContext.getProperties() != null ){

          System.out.println("Properties found in propertySet:");
          // print all properties defined in the fault-policy file
          Map props = iFaultRecoveryContext.getProperties();
          Collection list = props.values();
          for (String value : list) {
              System.out.println( value );
          }//

        }

        System.out.println("==========");

        return RETURN_MANUAL;
    }

    /**
     *
     * @param iFaultRecoveryContext
     */
    public void handleRetrySuccess( IFaultRecoveryContext iFaultRecoveryContext ) {
        System.out.println("SUCCESS.");
    }
}

Após compilar a classe acima, vamos empacotar em um arquivo .jar, faça isso:

 jar -cf fault-policy-javaaction.jar ./com/lucianosilva/lab/soa/*.class

Lembre-se, de usar \ se estiver no windows.

3. Adicionando Java Class (Jar) ao classpath do Weblogic

Você precisará que seu Jar seja adicionado ao classpath do Weblogic, para que em runtime a classe seja reconhecida pelo contexto e o Faut Policy funcione. O Apache Ant deve estar obrigatóriamente configurado no servidor.

O processo é muito simples, faça shutdown do servidor Weblogic, depois copie o arquivo .Jar para o diretório do servidor Weblogic $ORACLE_MIDDLEWARE_HOME/soa/modules/oracle.soa.ext_11.1.1/classes. Vá para no diretório oracle.soa.ext_11.1.1, aqui temos o build.xml, por fim, execute o Ant.

Pronto, está concluída a configuração de um exemplo para Fault Policy.
Para que as falhas do seu BPEL seja manipulada pela classe Java, as policies devem ser adicionadas ao arquivo composite.xml.

Veja na próxima parte deste post, como adicionar os XMLs de configuração do Fault Policy ao MDS e um BPEL utilizando esta configuração.

Download
Arquivos XML do Fault Policy
Projeto Java

Referências
http://docs.oracle.com/cd/E12839_01/integration.1111/e10224/bp_faults.htm
http://ant.apache.org/

Criando, Populando e Consumindo Advanced Queue com BPEL – Parte 3/3

E por fim, vamos fazer uso da AQ que foi criada e populada com dados fixos, veja Parte 1 e Parte 2.
O processo de consumo de uma fila chamado de Dequeue, quando executado remove o registro da tabela controladora (Queue Table).

Na camada Oracle Middleware o consumo desta AQ pode ser feito utilizando o Oracle JCA Adapter for Advanced Queue (AQ Adapter) do BPEL.

Nota: Não serão detalhados os procedimentos para a configuração do AQ Adapter no Weblogic, e também a construção básica de um Composite e BPEL, veja as referências deste post.

Consumindo Advanced Queue com BPEL

Crie um novo projeto SOA, e adicione um processo BPEL assíncrono, dê o nome de BPELProcessQueue.

Criando o BPEL Assincrono

Criando o BPEL Assíncrono

Configure o banco de dados em que foi criada a fila, utilizando o usuário proprietário da AQ.
Arreste o componente AQ Adapter para o processo BPEL, e faça a configuração informando o nome, nome da fila e tipo de uso (enqueue / dequeue) neste caso iremos fazer o Dequeue.

Alguns passos básicos foram ocultados, preencha apenas as configurações a seguir e utilize o next-next-finish.

AQ Adapter

Selecione a configuração Dequeue.

AQ Adapter - Dequeue

Selecione o nome da fila que estamos utilizando como exemplo – “XXAR_INVOICE_QTAB”.

AQ Adapter - Selecionando Queue

Pronto. A fila está preparada para fazer parte do fluxo BPEL, adicione um Receive e associe ao Adaptador, crie uma variável de output que irá conter o tipo de dados da fila.

Fluxo BPEL

Bem, com isso feito você já tem o controle total da fila e poderá fazer uso dos dados como quiser, veja abaixo um Assign simples, apenas demonstrando o resultado do nosso receive.

BPEL Assign

Conclusão
O uso do Oracle AQ pode ser aplicado a diversas situações, uma delas quando está trabalhando com sistemas limitados a tecnologia de Web Services, este recurso é muito útil também em casos que toda a programação está centralizada no banco de dados. Tendo em vista que a implementação e desenvolvimento são razoávelmente rápidos, utilizar a Oracle AQ fornece um ganho enorme para a plataforma de integração.

A seguir você poderá fazer download do projeto utilizado como exemplo e também os scripts para construção da fila.

Downloads

Referência

\o/

Criando, Populando e Consumindo Advanced Queue com BPEL – Parte 2/3

Com a estrutura da AQ criada, o próximo passo ainda utilizando o PLSQL é o envio das informações para a fila. O enqueue deve ser feito utilizado a API Core DBMS_AQ.

Populando (Enqueue)

O enfileiramento é um processo simples, uma vez que as variáveis foram declaradas, basta popular o type da mensagem que será enviada a fila, e fazer uso do dbms_aq.enqueue.

Este exemplo demonstra o enfileiramento de um único registro na fila, mas você pode evoluir o código fazendo o preenchimento com multiplos registros.

Veja como popular o objeto correspondente a mensagem com dados fixos.


    --
    -- Formatacao da Mensagem para o Enqueue com dados fake
    --
    MESSAGE := XXAR_KEY_INVOICE( INVOICE_NUM => 10001,
                                 SOURCE_NAME => 'core system',
                                 TOTAL_AMOUNT => 139.99,
                                 DESCRIPTION => 'White T-Short'
                               );
--

Uma vez que a mensagem foi preenchida, a próximo ação é o enfileiramento da mensagem, um procedimento tão simples quanto o anterior. O commit da transação é obrigatório.

    --
    -- Enqueue (enfileiramento)
    dbms_aq.enqueue(queue_name           => p_queue, -- nome da fila
                    payload              => MESSAGE, -- mensagem
                    enqueue_options      => enqueue_options,
                    message_properties   => message_properties,
                    msgid                => message_handle);

    commit; --
--

Pronto, feito isto já é possível consultar a Queue Table e verificar o novo registro que acabou de ser inserido.

SELECT * FROM XXAR_INVOICE WHERE 1 = 1 ORDER BY enq_time DESC;

A coluna State da Queue Table corresponde ao status do registro.

dbmsaq.READY     = 0
dbmsaq.WAITING   = 1
dbmsaq.PROCESSED = 2
dbmsaq.EXPIRED   = 3

O registro na fila está pronto para ser consumido, e vou demonstrar isto na próxima parte utilizando o BPEL.

Download

Criando, Populando e Consumindo Advanced Queue com BPEL – Parte 1/3

Este post irá mostrar como você pode fazer uso das filas do banco de dados Oracle – Oracle Advanced Queue.
No cenário apresentado, é sugerida a integração entre dois sistemas, sendo que o Sistema A irá enfileirar as informações para que o serviço da camada Middleware faça o consumo e dispare os dados para o Sistema B.

A seguir você poderá criar uma nova fila com um tipo de dado definido, em seguida ela será populada com dados fixos utilizando PLSQL e por fim, em um processo BPEL assíncrono fazer o dequeue (consumo).

Construindo

Os passos a seguir são para construção da fila e definição da mensagem que será entregue ao consumidor.
Conecte no banco de dados Oracle e execute os scripts na sequência, no final deste artigo você poderá fazer download dos scripts.

Tipo que define a estrutura da mensagem que será adicionada a fila.

--
CREATE TYPE XXAR_KEY_INVOICE AS OBJECT (
    INVOICE_NUM         NUMBER(10),
    SOURCE_NAME         VARCHAR2(200),
    TOTAL_AMOUNT        NUMBER(15,2),
    DESCRIPTION         VARCHAR2(500))
/

Criação da Queue Table, associada ao tipo (estrutura da mensagem).

--
Begin
 DBMS_AQADM.create_queue_table( queue_table => 'XXAR_INVOICE', -- nome da QTable
                                queue_payload_type => 'XXAR_KEY_INVOICE' -- tipo mensagem da QTable
                              );
End;
/

Criação da fila vinculada com a tabela controladora dos registros que serão adicionados a fila.

--
Begin
 DBMS_AQADM.create_queue(queue_name => 'XXAR_INVOICE_QTAB', -- nome da Queue
                         queue_table => 'XXAR_INVOICE' -- Tabela controladora da Queue
                         );
End;
/

Iniciando a fila.

--
Begin
  DBMS_AQADM.start_queue( queue_name => 'XXAR_INVOICE_QTAB' );
End;
/
CREATE OR REPLACE TYPE XXAR_KEY_INVOICE_T AS TABLE OF XXAR_KEY_INVOICE;
/

Pronto, agora conseguimos criar a AQ com um tipo de dado complexo definido.
Como você deve ter percebido toda a criação da fila faz uso da API core DBMS_AQADM. Para o nosso próximo passo que é o envio de mensagens para a fila (enqueue), será necessário a DBMS_AQ.

Downloads

[]‘s