Exemplo BPEL com For Each

Uma dúvida muito comum para quem está iniciando em BPEL é como iterar sobre um array. Nesse post vou mostrar como realizar essa tarefa utilizando um elemento For Each. O primeiro passo é criar um projeto BPEL e adicionar o nó For Each. com os valores adequados.

Vá em File, New, SOA Application e clique OK. Dê um nome para a sua aplicação (no meu caso: ExemploForBPELApplication) e clique em Next. Dê um nome para o projeto (ExemploForBPELProject) e clique em Next. Selecione Composite With BPEL Process e clique em Finish. Informe os dados do processo (no nosso exemplo será síncrono) e clique em OK.

Create BPEL Process
Create BPEL Process

Abra o XSD criado. Altere a string de entrada para permitir mais de uma string de entrada. Altere o valor do minOccurs para 0 e do maxOccurs para unbounded. Altere o name para algo mais expressivo, como "nome".

O resultado final é o seguinte:

<!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<schema attributeFormDefault="unqualified"
elementFormDefault="qualified"
targetNamespace="http://xmlns.thiagovespa.com.br/ExemploForBPELApplication/ExemploForBPELProject/ExemploForBPELProcess"
xmlns="http://www.w3.org/2001/XMLSchema">
<element name="process">
<complexType>
<sequence>
<element name="nome" type="string" maxOccurs="unbounded" minOccurs="0"/>
</sequence>
</complexType>
</element>
<element name="processResponse">
<complexType>
<sequence>
<element name="result" type="string"/>
</sequence>
</complexType>
</element>
</schema>

Abra o processo Bpel. Entre os nós receiveInput e replyOutput, insira uma atividade For Each. Você ficará com algo semelhane à esse:

ExemploForBpelProcessV1
ExemploForBpelProcessV1

Edite o For Each. Coloque um nome para o contador (ForEachNomeCounter) e para o For Each (ForEachNome). Se o seu For Each não depender da ordem de execução, marque a opção Parallel Exection. Essa opção otimiza a execução do For Each tornando a execução de forma paralela. Na aba Counter Values, coloque 1 para o Start Value e ora:countNodes('inputVariable','payload','client:nome') para Final Value. O ora:countNodes conta a quantidade de elementos dentro de um nó. Para saber quais valores colocar nos parâmetros, utilize o auto-completar do JDeveloper. Escreva as aspas (') e pressione Ctrl+Espaço e selecione a variável adequada. Dessa forma o nosso For Each vai do valor 1 ao total de elementos passados para o serviço.

Arraste um Assign para dentro do escopo do For Each e atribua o valor:

concat($outputVariable.payload/client:result,' ',$inputVariable.payload/client:nome[$ForEachNomeCounter])

para a variável $outputVariable.payload/client:result

Essa expressão irá concatenar o conteúdo da variavel result, com o espaço e com cada elemento do array client:nome na posição ForEachNomeCounter (que vai de 1 ao total de elementos).

Coloque outro Assign antes do For Each atribuindo 'Olá:' para a variável: $outputVariable.payload/client:result e coloque um outro Assign após o For Each atribuindo o valor concat($outputVariable.payload/client:result,' tudo bem?') para a variável $outputVariable.payload/client:result.

O processo final ficará assim:

ExemploForBpelProcessV3
ExemploForBpelProcessV3

Você pode fazer o download do projeto nesse link. Realize o deploy em um servidor SOA e para uma entrada com os seguinte valores:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body xmlns:ns1="http://xmlns.thiagovespa.com.br/ExemploForBPELApplication/ExemploForBPELProject/ExemploForBPELProcess">
<ns1:process>
<ns1:nome>Thiago</ns1:nome>
<ns1:nome>José</ns1:nome>
<ns1:nome>Mária</ns1:nome>
</ns1:process>
</soap:Body>
</soap:Envelope>

Você terá a seguinte saída:

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<env:Header>
<wsa:MessageID>urn:9F2D8F7050C811E1BF93C7D347E2EB71</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
</wsa:ReplyTo>
</env:Header>
<env:Body>
<processResponse xmlns="http://xmlns.thiagovespa.com.br/ExemploForBPELApplication/ExemploForBPELProject/ExemploForBPELProcess">
<result>Olá: Thiago, José, Mária, tudo bem?</result>
</processResponse>
</env:Body>
</env:Envelope>

Agora é só brincar com o código!

Sobre: Thiago Galbiatti Vespa

Thiago Galbiatti Vespa é mestre em Ciências da Computação e Matemática Computacional pela USP e bacharel em Ciências da Computação pela UNESP. Coordenador de projetos do JavaNoroeste, membro do JCP (Java Community Process), consultor Oracle, arquiteto de software de empresas de médio e grande porte, palestrante de vários eventos e colaborador de projetos open source. Possui as certificações: Oracle Certified Master, Java EE 5 Enterprise Architect – Step 1, 2 and 3; Oracle WebCenter Portal 11g Certified Implementation Specialist; Oracle Service Oriented Architecture Infrastructure Implementation Certified Expert; Oracle Certified Professional, Java EE 5 Web Services Developer; Oracle Certified Expert, NetBeans Integrated Development Environment 6.1 Programmer; Oracle Certified Professional, Java Programmer; Oracle Certified Associate, Java SE 5/SE 6