BDD com JBehave

Conforme prometido no tópico anterior, irei mostrar o conceito de BDD através da utilização do framework JBehave, que é o framework de BDD mais famoso para Java e que foi desenvolvido pelo Dan North, o idealizador deste conceito.

Antes de mais nada, vamos citar alguns conceitos importantes de BDD.

Estórias e Cenários

BDD é baseado em estórias e cenários, e para criarmos ambos, vamos seguir alguns padrões pré-definidos por autores de BDD. Uma vez que BDD é focado em comportamento e sequência, as estórias e cenários devem ter um formato rígido para que as ferramentas consigam entendê-los e interpretá-los.

As estórias, possuem o seguinte formato:

 Text |  copiar código |? 
1
2
As I [X]
3
I want [Y]
4
so that [Z]
5

E os cenários possuem o seguinte formato:

 Text |  copiar código |? 
1
2
Given some initial context (the givens),
3
When an event occurs,
4
then ensure some outcomes.
5

Ou seja, isso quer dizer que devemos pensar em nossos requisitos de maneira que possam ser escritos baseados nessa convenção.

O JBehave é originalmente escrito para entender estórias em inglês, entretanto como BDD é focado em pessoas (stakeholders) e na descrição de situações reais, faz muito mais sentido semanticamente que as estórias e cenários sejam escritos em português e para resolver isso, usei uma contribuição do Emerson Macedo para que os cenários possam ser escritos e entendidos em português pelo JBehave.

Começando com o JBehave

O primeiro passo para utilização do JBehave, é fazer download do JAR do projeto e incluí-lo no classpath do seu projeto.

O próximo passo é escrever a estória juntamente com o cenário e para tal resolvi criar um exemplo simples para que o entendimento do conceito possa ser casado através do código a ser desenvolvido.

O exemplo escolhido é baseado no requisito: Compra de produtos em promoção com aviso por email. E é isso que nosso cenário BDD deve descrever.

Por questão de organização, resolvi quebrar a estória em 3 cenários diferentes, onde a primeira parte representa a verificação de produtos em promoção, a segunda representa a compra desses produtos e o terceiro é a finalização da compra e o envio de email. Então, a estória e os cenários ficaram assim:

 Text |  copiar código |? 
01
02
Compra de produtos em promoção com aviso por email
03
 
04
Narrativa:
05
Como um usuário
06
Eu quero comprar produtos em promoção
07
E então receber um email de confirmação
08
 
09
Cenário: Verificar produtos em promoção
10
Dado Que uma loja possui 10 produtos
11
E Que 5 estão em promoção
12
Quando Eu verifico quais estão em promoção
13
Então Preencho minha sacola apenas com produtos em promoção
14
 
15
Cenário: Comprar produtos em promoção
16
Dado Que minha sacola de compras está preenchida com 5 produtos em promoção
17
Quando Eu verifico o somatório de produtos
18
Então Devo ter somente um total de 500 reais em produtos
19
 
20
Cenário: Enviar email
21
Dado Que minha sacola está preenchida de produtos
22
Quando Enviar um email de confirmação
23
Então Devo receber o status do envio "true"
24

A primeira linha do arquivo texto representa o título da nossa estória, o requisito de fato. A narrativa é um resumo do que essa estória deve cumprir e a seguir vem os três cenários, que no caso são as três etapas da estória.

É importante notar, que as palavras chaves em inglês (Given, When, Then, And) foram substituídas por palavras em português (Dado, Quando, Então, E).

Esse arquivo texto deve ser salvo com a extensão *.cenario e o seu nome está diretamente ligado a classe que irei criar no passo a seguir, que no caso é a classe que representa a estória e a associação com os cenários.

Criando a classe que irá comportar os cenários

Nesse passo irei criar a classe que irá apontar os cenários que compõe a estória e essa classe deve extender a classe Scenario do JBehave. Dessa forma, a classe ficaria assim:

PrecoPromocaoTeste.java

 Java |  copiar código |? 
01
02
package scenario1;
03
 
04
import scenario1.steps.CompraSteps;
05
import scenario1.steps.EmailSteps;
06
import scenario1.steps.PromocaoSteps;
07
import scenario1.util.PtBRScenario;
08
 
09
public class PrecoPromocaoTeste extends PtBRScenario {
10
	public PrecoPromocaoTeste() {
11
           addSteps(new PromocaoSteps());
12
           addSteps(new CompraSteps());
13
           addSteps(new EmailSteps());
14
	}
15
}
16

No exemplo acima, estou extendo a classe PtBRScenario só para que a estória e o cenário sejam escritos em português, mas essa classa herda a classe Scenario como descrito anteriormente.

No construtor da classe, inclui os passos que a estória deve seguir para ser satisfeita e como quebrei a estória em três pedaços, precisei incluir três passos sequenciados.

Criando os passos da estória

Como a estória foi quebrada em três partes, se faz por necessário a criação de 3 classes que irão representar os passos da estória e todas essas classes devem herdar a classe Steps do JBehave.

Pela ordem definida na nossa classe de cenário, vamos aos passos:

PromocaoSteps.java

 Java |  copiar código |? 
01
package scenario1.steps;
02
 
03
import java.util.List;
04
 
05
import junit.framework.Assert;
06
 
07
import org.jbehave.scenario.annotations.Given;
08
import org.jbehave.scenario.annotations.Then;
09
import org.jbehave.scenario.annotations.When;
10
 
11
import scenario1.entity.Loja;
12
import scenario1.entity.Produto;
13
import scenario1.util.PtBRSteps;
14
import scenario1.vo.Sacola;
15
 
16
public class PromocaoSteps extends PtBRSteps {	
17
	Loja loja 		= new Loja();
18
	Sacola sacola 	= new Sacola();
19
	List<Produto> listaProdutoPromocao;
20
	int quantidadeProdutoPromocao;
21
 
22
	@Given("Que uma loja possui $quant produtos")
23
	public void populaLoja(Integer quantidade) {
24
		loja.inicializaProdutos(quantidade);
25
	}	
26
 
27
	@Given("Que $quant estão em promoção")
28
	public void informaProdutosPromocao(Integer quantidade) {
29
		loja.colocaProdutosPromocao(quantidade);
30
		quantidadeProdutoPromocao = quantidade;
31
	}	
32
 
33
	@When("Eu verifico quais estão em promoção")
34
	public void verificaProdutosPromocao() {		
35
		listaProdutoPromocao = loja.retornaProdutosPromocao();
36
	}
37
 
38
	@Then("Preencho minha sacola apenas com produtos em promoção")
39
	public void populaSacola() {
40
		sacola.populaSacola(listaProdutoPromocao);
41
 
42
		Assert.assertEquals(listaProdutoPromocao.size(), quantidadeProdutoPromocao);
43
	}
44
}

CompraSteps.java

 Java |  copiar código |? 
01
package scenario1.steps;
02
 
03
import java.util.ArrayList;
04
import java.util.List;
05
 
06
import junit.framework.Assert;
07
 
08
import org.jbehave.scenario.annotations.Given;
09
import org.jbehave.scenario.annotations.Then;
10
import org.jbehave.scenario.annotations.When;
11
 
12
import scenario1.entity.Produto;
13
import scenario1.util.PtBRSteps;
14
import scenario1.vo.Sacola;
15
 
16
public class CompraSteps extends PtBRSteps {
17
	Sacola sacola 				= new Sacola();
18
	double somatorioProdutos 	= 0d;
19
 
20
	@Given("Que minha sacola de compras está preenchida com $quant produtos em promoção")
21
	public void verificaSacola(Integer quantidade) {
22
		List<Produto> listaProduto = new ArrayList<Produto>();
23
 
24
		for (int i=1; i<=quantidade; i++) {
25
			Produto produto 	= new Produto();
26
			produto.preco 		= Math.round(Math.random()*100);
27
			produto.emPromocao 	= true;
28
 
29
			listaProduto.add(produto);
30
		}
31
 
32
		sacola.populaSacola(listaProduto);
33
	}
34
 
35
	@When("Eu verifico o somatório de produtos")
36
	public void verificaTotalProdutosSacola() {
37
		for ( Produto produto : sacola.retornaProdutos() ) {
38
			somatorioProdutos = produto.preco + somatorioProdutos;
39
		}
40
	}
41
 
42
	@Then("Devo ter somente um total de R$ $total reais em produtos")
43
	public void validaSacola(double totalProduto) {		
44
		if ( somatorioProdutos > totalProduto )
45
			Assert.fail("Total de produtos é acima de R$ 500");
46
	}
47
}
48

EmailSteps.java

 Java |  copiar código |? 
01
package scenario1.steps;
02
 
03
import static org.jbehave.Ensure.ensureThat;
04
 
05
import org.jbehave.scenario.annotations.Given;
06
import org.jbehave.scenario.annotations.Then;
07
import org.jbehave.scenario.annotations.When;
08
 
09
import scenario1.util.PtBRSteps;
10
import scenario1.vo.Sacola;
11
 
12
import com.guilhermechapiewski.fluentmail.email.EmailMessage;
13
import com.guilhermechapiewski.fluentmail.transport.EmailTransportConfiguration;
14
 
15
public class EmailSteps extends PtBRSteps {
16
	Sacola sacola 		= new Sacola();
17
	Boolean statusEnvio = false;
18
 
19
	@Given("Que minha sacola está preenchida de produtos")
20
	public void verificaSacola() {
21
		System.out.println("Lista cheia..");
22
	}
23
 
24
	@When("Enviar um email de confirmação")
25
	public void enviaEmail() {
26
		EmailTransportConfiguration.configure("localhost", false, false, "", "");
27
 
28
		new EmailMessage()
29
	    	.from("eusou@marcuscavalcanti.net")
30
	    	.to("eusou@marcuscavalcanti.net")
31
	    	.withSubject("Testando BDD")
32
	    	.withBody("Testando terceiro cenário e o final da estória.")
33
	    	.send();
34
 
35
		statusEnvio = true;
36
	}
37
 
38
	@Then("Devo receber o status do envio \"$retorno\"")
39
	public void recebeStatusEnvio(String retorno) {	
40
		ensureThat(statusEnvio.toString().equals(retorno));
41
	}
42
}

Nos exemplos acima, que representam os passos de um cenário, é importante notar que os métodos seguem a ordem definida no arquivo texto, assim como todos são anotados com as palavras chaves correspondentes, no caso Given, When, And, Then. As anotações recebem como parâmetro as frases descritas no arquivo texto, excluindo apenas as palavras chaves no começo da frase, que estão devidamente representadas pelas anotações.

Os parâmetros são identificados com o formato $variavel, e uma vez que usamos esses parâmetros, devemos também colocá-los na assinatura dos métodos. Esses parâmetros são automaticamente capturados pelo JBehave através do uso de expressões regulares.

Executando o exemplo

Para executar o exemplo deve-se executar a classe que extende a classe Scenario do JBehave, nesse caso seria a classe PrecoPromocaoTeste.java, e para acompanhar os resultados, eu utilizo a integração do Eclipse com o JUnit, através de uma view própria da IDE.

No exemplo, usei ainda algumas classes auxiliares criadas especificamente para o exemplo, mas que não irei mostrar aqui os seus códigos para não tornar o tópico extenso demais. De qualquer forma, ao final desse tópico botarei um link para download do projeto no Eclipse que contém todos os códigos.

Observações finais

Um dos problemas que eu notei no JBehave é em relação a parametrização de alguns valores no arquivo texto para o código Java, em alguns casos isso pode se tornar um trabalho sacal e pouco produtivo, mas acredito que com a evolução do framework esse problema será resolvido.

Algumas pessoas utilizam alternativas variadas para resolver esse problema, como por exemplo criar o valor dos parâmetros diretamente como atributos nas classes que representam os passos. Eu particularmente não gosto dessa abordagem, pois acredito que isso faz com que os arquivos que descrevem os cenários percam seu valor e esses arquivos são essencial para utilização e sentido do BDD.

No exemplo citado, usei ainda algumas bibliotecas como FluentMailApi, Mail e Activation da JavaMail e Hamcrest. Essas bibliotecas servem basicamente para o envio de email e uso mais aperfeiçoado de expressões regulares por parte do JBehave.

Para finalizar, é importante citar que as classes do meu negócio (Sacola, Usuario, Loja, etc) foram construídas baseadas no meu requesito, no meu cenário, que foi a primeira etapa a ser elaborada na construção do exemplo.

Download

Para download do projeto completo no Eclipse, basta clicar aqui.

Java, Tecnologia, Software & Desenvolvimento

Algumas observações sobre BDD

Ultimamente estive pesquisando sobre o assunto BDD (Behaviour-Driven Development) e também praticado com alguns exemplos reais, através disso devo dizer que consegui tirar algumas conclusões bem interessantes sobre o assunto, nas quais gostaria de expor aqui. Vamos a elas:

BDD não é uma evolução de TDD

BDD é uma abordagem de testes, assim como TDD (Test-Driven Development), a diferença principal entre ambas, é que o BDD é mais focado no comportamento, e o TDD é focado em partes isoladas.

Eu já li em alguns lugares, que BDD é uma evolução do TDD e uma das conclusões que eu cheguei é que isso não faz sentido, pois as duas abordagens podem ser muito bem complementares e atuarem juntas em um mesmo projeto. Dependendo do custo x benefício, e aí eu envolvo a questão do tempo, acharia super válido um projeto pensar nas duas abordagens e nos benefícos que o uso das mesmas podem vir a trazer.

Como dizer que BDD é uma evolução do TDD se a maneira como as duas lidam com testes é diferente? BDD é baseado no conceito de testes de aceitação e estórias, uma estória é a sua funcionalidade e a mesma é constituida de cenários, que são as etapas que constituem uma estória. Os cenários por sua vez, são constituídos de passos, que no caso representam a sequência para um cenário ser satisfeito.

Quem já fez algum teste com BDD, deve ter percebido que um cenário pode não envolver vários métodos da sua aplicação, com isso consequentemente esses métodos não seriam testados. Na minha opinião, esse é mais que um motivo que aponta que TDD não deve ser desconsiderado em seu projeto, mesmo que ele use BDD.

BDD ajuda você, BDD ajuda seu cliente

Outro ponto que pude observar, é que usando BDD a possibilidade de um cliente participar de um projeto é imensa, mesmo que você não use alguma metodologia ágil (falarei sobre isso a seguir). E por que ele pode participar? É simples, pois é ele quem pode escrever os testes. Se ainda assim não for o seu cliente o responsável por escrever os testes, será ele quem irá validá-los, ou seja, você pode escrever os testes e pedir para que ele aprove ou não. Isso é muito importante, pois nesse caso os testes em BDD seriam o contrato entre você o seu cliente, entre o que você está entregando e o que ele está esperando.

BDD favorece o sucesso do uso de metodologias ágeis

Sem dúvida nenhuma um dos pontos fortes do uso de BDD é que suas características se encaixam muito bem em equipes que fazem o uso de metodologia ágil. E são vários pontos que favorecem.

Uma delas é a já citada participação do cliente, pois um dos requisitos para o sucesso do uso de metodologias ágeis é a participação e contribuição efetiva do cliente e no caso do uso de BDD ele pode participar diretamente, uma vez que é ele quem é o responsável (PO) por criar as estórias (ítens do backlog) e criar os testes de aceitação para as mesmas, onde tudo isso é usado no BDD.

Os artefatos que constituem BDD são muito, mais muito semelhantes aos artefatos presentes em ágil.

Em BDD se usa estórias e testes de aceitação, além de BDD favorecer a construção de aplicativos de forma evolutiva (sprints) e tudo isso casa perfeitamente com os requisitos das metodologias ágeis.

Favorece a escrita de testes antes da implementação

Uma boa prática na criação de testes, independente se você usa BDD ou TDD, é que os testes sejam criados antes de tudo. Ok, eu concordo, mas devo dizer que com TDD isso não é muito nítido, pois na maioria dos casos, principalmente no começo, as pessoas tendem a implementar os códigos e depois escreverem os testes para validá-los. Já com BDD, a primeira coisa que você precisa ter em mãos antes de implementar os testes são as estórias e os cenários, não tem como fugir disso, o que torna muito mais nítido que em primeiro lugar vem os testes e depois as implementações.

Torna mais nítido o que sua aplicação deve fazer

Com BDD é muito mais fácil isolar as funcionalidade da sua aplicação, já que o que é testado é exatamente isso, dessa forma fica fácil identificar os componentes que envolvem determinada funcionalidade, torna mais nítido qual é o papel daquela funcionalidade, além do que consegue dar um sentido melhor para a sua aplicação de maneira geral.

Com BDD, você consegue ainda uma visão de workflow da sua aplicação, ou seja, uma visão macro, o que favorece dar manutenção a mesma. Percebo também, que BDD favorece um bom design de código, evitando assim problemas de desenvolvimento como códigos com alto-acoplamento.

Torna os testes mais humanos

A essência do BDD são os cenários e não parte isoladas da aplicação e essa maneira de lidar com testes favorece o entendimento por parte de nós, humanos.

Testes de interface com o Selenium, tornam-se mais compreensíveis num contexto que envolva BDD, como em um teste de login, por exemplo.

Conclusão

Na minha opinião, está mais do que clara a vantagem no uso de BDD, entretanto ele não substitui o uso de TDD, pois a abordagem de ambas são diferentes e complementares.

No próximo tópico, irei mostrar um cenário de testes com o framework JBehave, um framework BDD para Java.

Mais sobre o assunto

The truth about DDD

The difference between TDD and BDD

Tecnologia, Software & Desenvolvimento

Algumas frases sobre SOA e BPM

Tenho andado sem tempo para postar coisas novas (apesar de ter mais de 20 posts engatilhados) e para não ficar tão ausente, resolvi colocar em prática algo que eu já vinha tendo vontade de fazer há algum tempo, que no caso seria publicar frases de autores que costumo ler.

As frases são tiradas de um contexto específico, mas podem tranquilamente ser usadas de maneira isolada para reflexão, aprendizado e até para fixar uma idéia.

Nessa “primeira edição”, vou me ater a frases que envolvam SOA e BPM.

Eis as frases:

“The first of those milestones has come to pass: process is not simply the way business operates itself, but manages itself.”
Phil Gilbert

“It’s been said, “If you can’t measure it, you can’t manage it.” It’s also been said, “Opinions are like a*******, everybody’s got one.” The ability to manage by fact (measurement), rather than opinion, is what sets the rare professional manager from the masses of loudmouth, intimidating, egotists who’ve been given the title Manager. Leaders, on the other hand, earn that title. And one of the most effective ways of earning that title is to learn to mange objectively, not subjectively. Objective management starts with identifying objective performance measurements.”
Jim Reardan

“Service Decomposition splits service, not function.”
Thomas Erl

“IT realizes the burden is not on them anymore. The business has to be the responsible party.”
Peter Woodhull

“Often when we look at business processes and SOA we ignore the information aspect and focus on the technology aspect. What’s important is that you have some vision of sets of services that you need now and then over time to meet your business requirements.”
Mike Rosen

“Unless you use SOA in the context of what you’re trying to do with the business, you can end up with just the new spaghetti to replace the old spaghetti.”
Marc Smith

“…often sees a team of business experts thinking in purely business terms and a team of developers thinking only in terms of what code they’ll need to write. But SOA is not the sort of architecture that one builds by throwing code at it. It is, at its core, very conceptual.”
Sandy Kemsley

“Using SOA as we do – as an architecture and business modeling approach – helps bridge the gap between traditional business process modeling and technology delivery.”
Steve Jones

“SOA is simply the technology architecture that defines how any technology is designed and deployed. BPM, on the other hand, represents how you link business strategy to business implementation… with [SOA-based] technology being a part of that implementation.”
Phil Gilbert

BPM, SOA

Gerando pacotes do ALBPM com Maven e Ant

O Maven é um framework da Apache que possui muitas utilidades, uma delas é a geração de pacotes das aplicações sem que seja necessário uma IDE para realizar tal trabalho, isso é muito útil para que toda a equipe possa gerar um pacote da aplicação sem que seja necessário ter todo o projeto configurado em sua máquina, dessa forma fica-se independente de IDE e máquinas.

Outra utilidades do Maven é o gerenciamento de dependências da aplicação, pois uma vez que sua aplicação use outras bibliotecas, não se faz por necessário incluir os devidos JARs no repositório da aplicação, basta apenas informar isso no Maven e deixar que ele se encarregue de encontrar essas bibliotecas e baixar para sua máquina.

No caso do ALBPM (Aqualogic BPM), temos um cenário um pouco diferente, pois no final das contas tudo que é gerado são arquivos XML com as informações dos seus processos, então nesse caso usamos o Maven apenas para geração de pacotes. No ALBPM, um pacote nada mais é que o diretório da aplicação compactado (zipado) com uma extensão específica, no caso *.exp, deve-se considerar ainda a exclusão de alguns diretórios na geração do pacote, pois esses diretórios são gerados em tempo de compilação pela engine do ALBPM. Baseado nisso, criei uma configuração do Maven que será responsável pela geração de pacote de um projeto no ALBPM.

Usei ainda uma integração do Maven com o Ant, através de um plugin específico do Maven, onde o Ant será responsável por realizar algumas rotinas bem específicas, como renomear o arquivo gerado e apagar diretórios que não serão usados.

Vale ressaltar que eu testei essa rotina apenas para o ALBPM na versão 6.*, no caso da versão 5.*, acho que não deve mudar muita coisa, mas a extensão do pacote gerada é diferente, portanto será necessário algumas adaptações para que essa rotina funcione também nessa versão. No caso das versões já com a Oracle como responsável pelo produto (OracleBPM), essa rotina também deverá funcionar sem problemas.

Criando o POM do Maven

Como nosso projeto do ALBPM possui apenas um único módulo, será necessário a criação apenas de um único arquivo *.pom, que no caso será o responsável por incluir os plugins que serão usados, além de chamar um arquivo com algumas tasks do Ant. Dessa forma, o arquivo POM fica assim:

 XML |  copiar código |? 
01
<project xmlns="http://maven.apache.org/POM/4.0.0"
02
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
03
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
04
 
05
	<modelVersion>4.0.0</modelVersion>
06
	<groupId>com.b2w</groupId>
07
	<artifactId>ControleOrcamento</artifactId>
08
	<packaging>pom</packaging>
09
	<version>1.0</version>
10
	<name>ControleOrcamento Project</name>	
11
 
12
	<properties>
13
		<packageName>ControleOrcamento</packageName>
14
		<packageDirectory>package</packageDirectory>
15
		<packageExtension>exp</packageExtension>		
16
	</properties>
17
 
18
	<build>
19
	   	<plugins>
20
	   		<plugin>
21
				<artifactId>maven-assembly-plugin</artifactId>
22
				<executions>
23
					<execution>
24
						<id>assemble-zip</id>
25
						<phase>install</phase>
26
						<goals>
27
							<goal>attached</goal>
28
						</goals>
29
					</execution>
30
				</executions>
31
				<configuration>
32
                                       <appendAssemblyId>false</appendAssemblyId>   
33
					<finalName>${packageName}</finalName>                 
34
					<descriptors>
35
						<descriptor>assembly-descriptor.xml</descriptor>
36
					</descriptors>
37
				</configuration>
38
			</plugin>
39
      		<plugin>
40
				<groupId>org.apache.maven.plugins</groupId>
41
				<artifactId>maven-antrun-plugin</artifactId>
42
				<executions>									
43
					<execution>
44
						<id>rename-package</id>
45
						<phase>install</phase>
46
						<configuration>
47
							<tasks>
48
								<property name="package_name" value="${packageName}"></property>
49
								<property name="package_extension" value="${packageExtension}"></property>
50
								<property name="package_directory" value="${packageDirectory}"></property>
51
								<ant antfile="maven-setup.xml" ></ant>
52
							</tasks>							
53
						</configuration>
54
						<goals>
55
							<goal>run</goal>
56
						</goals>
57
					</execution>					
58
				</executions>
59
			</plugin>
60
	    </plugins>
61
	</build>  	
62
 
63
	<repositories>
64
		<repository>
65
			<id>default</id>
66
			<name>Internal</name>
67
			<url>http://intranet/archiva/repository/internal</url>
68
		</repository>
69
		<repository>
70
			<id>ideais</id>
71
			<name>Ideais</name>
72
			<url>http://intranet/archiva/repository/ideais</url>
73
		</repository>
74
		<repository>
75
			<id>thirdparty</id>
76
			<name>Thirdparty Artifacts</name>
77
			<url>http://intranet/archiva/repository/thirdparty</url>
78
		</repository>	
79
	</repositories>
80
 
81
</project>

A idéia aqui não estar explicando o que é um POM, sua estrutura, como funciona, etc, a idéia é apenas mostrar como criar um POM com o intuito de gerar pacotes do ALBPM.

Explicando o POM utilizado

No começo do nosso POM temos algumas informações obrigatórias que o Maven exige, portanto acho que não vale a pena citá-las, dessa forma partindo para a declaração das propriedades ( ), nós temos:

packageName – Nome do diretório da aplicação
packageDirectory – Diretório onde deverá ser gerado o pacote
packageExtension – Extensão do pacote a ser gerado

Na parte da declaração de plugins, nós declaramos os dois plugins que utilizaremos: maven-assembly-plugin (será o responsável por gerar o arquivo compactado, excluir os diretórios não desejados, etc) e maven-antrun-plugin (será o responsável por fazer algumas tarefas pontuais como renomear o arquivo compactado e deletar os diretórios não utilizados e que são gerados pelo plugin anterior).

No caso do plugin maven-assembly-plugin, associamos ainda um descriptor, que é um arquivo XML que contém todas as rotinas que esse plugin deverá executar e que possui o seguinte conteúdo:

 XML |  copiar código |? 
01
<assembly>
02
	<formats>
03
		<format>zip</format>
04
	</formats>
05
	<includeBaseDirectory>false</includeBaseDirectory>	
06
	<fileSets>
07
		<fileSet>
08
			<directory>${basedir}/${packageName}</directory>		  			  	
09
			<filtered>true</filtered>			
10
		  	<excludes>		  		
11
				<exclude>**/.svn/**</exclude>
12
				<exclude>**/fuego.portal.jar/**</exclude>
13
				<exclude>**/build/**</exclude>
14
				<exclude>**/system/**</exclude>
15
		  	</excludes>		  	
16
		</fileSet>
17
	</fileSets>	
18
</assembly>

No conteúdo acima, especificamos no elemento
o formato do arquivo a ser gerado, no caso um zip. No elemento informamos ao plugin que não queremos que ele inclua o diretório base no arquivo zip a ser gerado. No elemento definimos uma série de regras que o arquivo a ser zipado deverá obedecer: no primeiro elemento () informamos qual diretório deverá ser zipado, repare que nesse caso usamos os valores das propriedades definido no arquivo POM do Maven. No segundo elemento, no caso , informamos que NÃO queremos que o plugin inclua os diretórios que não possuem arquivos, ou seja, não queremos diretórios em branco. No terceiro elemento (), informamos ao plugin quais são os diretórios e arquivos que NÃO devem ser incluídos no arquivo zip a ser gerado, nesse caso não queremos incluir nenhum diretório/arquivo do SVN, não queremos incluir o JAR fuego.portal, assim como não queremos incluir os diretórios build e system, pois eles são gerados pela IDE em tempo de compilação e não são necessários para nosso pacote.

Explicando o arquivo Ant

No nosso POM, declaramos o plugin maven-antrun-plugin, que será o plugin responsável por executar tasks do Ant.

Ainda no arquivo POM, definimos algumas propriedades que o arquivo Ant deverá conhecer, ou seja, ele irá herdar as propriedades que definimos no POM, bem como definimos qual é o arquivo XML que conterá as taks do Ant a serem executadas, no nosso caso esse arquivo é o maven-setup.xml.

O arquivo maven-setup.xml conterá duas rotinas: uma que é renomear o zip gerado, para ao invés de possuir a extensão .zip, possuir a extensão .exp (propriedade definida no POM e herdada no arquivo Ant), e outra rotina deverá ser remover o diretório target, que é gerado pelo maven-assembly-plugin e que no nosso caso não teria nenhuma utilidade. Dessa forma o conteúdo do nosso arquivo Ant ficou assim:

 XML |  copiar código |? 
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project name="mavensetup" default="setup">
3
	<target name="setup">
4
			<echo level="info">Renomeando o pacote para ${package_name}.${package_extension}</echo>
5
		  	<move file="target/${package_name}.zip" tofile="${package_directory}/${package_name}.${package_extension}"></move>
6
		  	<echo level="info">Apagando o diretorio /target</echo>
7
		  	<delete dir="target"></delete>
8
  	</target>
9
</project>

Repare, que no arquivo Ant usamos as propriedades definidas no nosso POM do Maven e usamos ainda o elemento para termos informação do que o Ant está fazendo.

Resumindo

Usando apenas 3 arquivos (pom.xml, assembly-descriptor.xml, maven-setup.xml) nós temos nosso pacote do ALBPM sendo gerado pelo Maven e pronto para ser deployado na versão enterprise do ALBPM.

Agora basta apenas um mvn install na linha de comando para geração do pacote.

Mais informações

Começando com o Maven

Maven Assembly Plugin

Maven AntRun Plugin

Maven Lifecycle

BPM

Entendendo como funciona a arquitetura do Weblogic Server em ambientes clusterizados

Antes de mais nada, gostaria de ressaltar que esse post não tem o intuito de ensinar ou mostrar o passo-a-passo para a criação de um ambiente clusterizado com o Weblogic Server, na verdade o intuito é mostrar como é e como funciona essa arquitetura, usando um exemplo prático criado para esse propósito específico. Para criação e configuração de um ambiente clusterizado, indico a documentação da Oracle/BEA, na qual estarei citando os links ao final do post.

Domínio

Quando trabalhamos em um ambiente de desenvolvimento, basicamente o que temos que nos preocupar é referente a criação de um domínio. Um domínio nada mais é que um conjunto de recursos e serviços que fisicamente são mantidos através de arquivos.

A parte principal de um domínio chama-se Administration Server, que é uma instância de um Weblogic Server responsável por manter e configurar seus recursos. Todo esse gerenciamento do Adminstration Server é feito através do Admin Console, que por sua vez é uma aplicação que é deployada no seu Administration Server e que será responsável por fornecer uma interface gráfica para que você possa gerenciar seu domínio, ou seja, toda a configuração feita pelo Admin Console é baseada em XML e é ele quem gerencia esses arquivos.

É através do Administration Server que você faz o deploy/undeploy das suas aplicações, porém em um ambiente de produção, ou até mesmo de homologação, o mais indicado é que tenhamos nossas aplicações em um servidor a parte, que são chamados de Managed Servers.

Managed Servers

Uma instância de um Weblogic Server, que não é uma instância do Administration Server, é chamada de Managed Server, é no Managed Server onde suas aplicações e recursos serão deployados de fato, deixando para o Administration Server apenas a responsabilidade de gerenciá-los.

São os Managed Servers que hospedam todos os componentes e recursos que constituem uma aplicação, e toda vez que um Managed Server é inicializado, ele se conecta com o Administration Server para obter informações de configuração e deployment.

Cluster. O quê é e por quê usar?

Em ambientes de produção é normal que existam certas preocupações que não ocorrem com ambientes de desenvolvimento, como alta disponibilidade das aplicações e balanceamento de carga.

Imagine que ocorra qualquer problema na máquina onde a sua aplicação está deployada? O quê fazer? Para não ficar a mercê desse tipo de problema, o correto é pensar em uma estrutura em que sua aplicação possa ser replicada em N instância de servidores em máquinas diferentes, onde caso uma máquina dê problema, a outra assume e assim sucessivamente.

Outro problema comum é a sobrecarga de uma aplicação. Um cenário normal em aplicações web é o acesso de muitos usuários e consequentemente o processamento a exaustão das máquinas onde essas aplicações estão deployadas, isso por muitas vezes pode ocasionar um estouro de processamento ou até mesmo um tempo de resposta maior para o usuário. E como fazer para resolver esse problema? A resposta é através do balanceamento de carga.

Para resolver esses tipos de problemas foi criada uma estrutura cuja o nome é Cluster. Um Cluster é um conjuto de computadores que trabalham de forma conjunta cujo objetivo é fazer com que todo o processamento da aplicação seja distribuído a N computadores, mas de forma que pareça com que eles sejam um computador só.

Cluster e Managed Servers

Um Cluster de Weblogic Server corresponde a múltiplas instância de Weblogic Server que estão trabalhando e rodando simultaneamente com o objetivo de prover escalabilidade e disponibilidade.

Ou seja, um Cluster é um conjunto de Managed Servers, e cada Managed Server representa um nó de um cluster.

Quando se pensa em uma arquitetura usando Clusters, é normal que se pense em mais de uma máquina, afinal não faz muito sentido ter um Cluster com uma máquina, pois caso essa máquina pare de funcionar, todas as aplicações também irão parar.

A relação Managed Servers, Machines e Domínio

Partindo do princípio que um Cluster deve necessariamente ter mais de uma máquina, chegamos ao conceito de “Machines” do Weblogic Server.

Uma “machine” é exatamente uma máquina, um computador físico, e essa máquina pode ter mais de um managed server, ou seja, pode ter mais de uma instância do Weblogic Server rodando ao mesmo tempo. É óbvio que nesse caso teríamos que ter essas duas instâncias rodando em portas diferentes.

Dessa forma, chegamos a seguinte associação: Domínio -> Administration Server -> Cluster -> Machine -> Managed Server.

Node Manager

Quando falamos a nível de máquina (machine), devemos falar também dos Node Managers. Um Node Manager não está associado a um domínio, está associado a uma máquina, já que uma máquina pode ter mais de um Managed Server.

Um Node Manager é uma aplicação standalone responsável por gerenciar Managed Servers em uma máquina (machine) remota. Através do Node Manager é possível inicializar, parar e re-startar instâncias do Administration Server e dos Managed Servers de uma máquina remota.

Multi-cast Address

Em um ambiente clusterizado, precisamos ter N computadores trabalhando de forma conjunta de forma que isso seja transparente, mas quando usamos recursos como sessões, ou até mesmo conexões distribuídas, precisamos que isso também seja feito de forma distribuída, sem que seja necessário por exemplo criar uma sessão para cada Managed Server.

Isso é feito através do multi-cast address, que é um IP associado a um cluster, que por sua vez irá informar esse IP para seus Managed Servers para que os mesmos possam usar um único IP para fazer esse tipo de compartilhamento.

Juntando tudo

Para dar uma visão mais clara de toda essa arquitetura e quem está associado a o que, resolvi criar um diagrama que mostra todos os elementos citados acima e associação/relação entre eles.

No exemplo usei ainda o Apache como Servidor Web, que será a porta de entrada de tudo, será ele que irá receber as requisições HTTP, fazer o balanceamento de carga e delegar as responsabilidades para os Managed Servers. Será o Apache ainda o responsável por identificar e servir conteúdo estático sem que seja necessário passar pelo Cluster.

Diagrama

clique para ampliar

clique para ampliar

Mais Informações

Weblogic Server
http://download.oracle.com/docs/cd/E13222_01/wls/docs92/admin.html

Understanding Cluster Configuration
http://download.oracle.com/docs/cd/E12840_01/wls/docs103/cluster/config.html

Understanding Weblogic Server Clustering
http://download.oracle.com/docs/cd/E13222_01/wls/docs92/cluster/overview.html

Setting Up Weblogic Cluster
http://download.oracle.com/docs/cd/E12840_01/wls/docs103/cluster/setup.html

Using Node Manager
http://download.oracle.com/docs/cd/E13222_01/wls/docs92/server_start/nodemgr.html

Node Manager Architecture
http://download.oracle.com/docs/cd/E13222_01/wls/docs81b/adminguide/nodemgr.html

Configure Apache HTTP Server
http://download.oracle.com/docs/cd/E15051_01/wls/docs103/plugins/apache.html

Java

Dica rápida: recuperando um domínio corrompido no Weblogic

Essa é uma dica rápida para quem trabalha com aplicações em cima do Weblogic.

Um domínio Weblogic pode ser corrompido por diversos motivos, como: domínio ser encerrado de forma forçada ( com um kill -9, por exemplo), máquina ser desligada de forma repentina, falta de luz, etc. Quando isso acontece, seu domínio que estava rodando pode ser corrompido, e com isso a seguinte mensagem é retornada ao tentar iniciá-lo novamente:

 Text |  copiar código |? 
1
Server cannot be started.   The server process cannot be started, or terminated abruptly. Check the start script.

Para resolver isso é muito simples, basta remover todas as pastas build pré-existentes (são geradas automaticamente pela seu Workshop, quando a aplicação é compilada) e em seguida basta fazer um start do seu domínio novamente.

Outra dica, é que antes de tentar fazer o deploy das aplicações em cima desse domínio novamente, que antes faça um undeploy (usando o console) das mesmas, pois se o domínio foi encerrado de forma forçada, as aplicações ainda estarão lá deployadas e caso você tente novamente, provavelmente não conseguirá.

Procurei sobre isso nos forums da Oracle e não achei nada, então fica aí a dica, pois isso evita que você tenha que re-criar e configurar seu domínio novamente.

Java

Existe SOA sem BPM?

Recentemente fiz uma apresentação sobre BPM na empresa onde eu trabalho e o meu foco foi explicar o que são processos de negócio, o que é BPM e para que serve, quais são seus benefícios, além de mostrar todo o suporte que BPM dá para uma organização migrar e utilizar SOA, que é exatamente sobre o que eu vou falar neste tópico.

BPM pode muito bem existir sem SOA, já que BPM é uma modalidade que foca na aplicação de práticas e conceitos para melhoria e absorção de processos de negócios por parte de uma organização, mas e SOA, pode existir sem BPM?

SOA é um modelo arquitetural de construção de software que possui alguns pilares, dentre eles:

Dentre os pilares citados acima, é fácil perceber que SOA gera valores semelhantes ao que aplicação adequada de uma solução BPM geraria, entretanto BPM não é uma maneira de se construir software, BPM está muito além disso, está no topo, mas deve atuar lado-a-lado a SOA para produzir resultados mais duráveis, que gerem mais valor ao negócio, que sejam mais fáceis de manterem e de darem manutenção. E o somatório disso tudo proporciona resultados mais efetivos.

Certa vez li uma analogia sobre uso de SOA sem BPM e que de certa forma ajuda a esclarecer a importância da aplicação de BPM junto a SOA. Era mais ou menos assim: “Usar SOA sem BPM seria como um malabarista com uma mão atada atrás das costas. Ele poderia ainda fazer alguns malabarismos, mas não seria tão eficaz e nem tão rápido como poderia ser”.

E na prática como BPM complementa SOA?

Um dos pilares citados em uma arquitetura SOA é a possibilidade do alinhamento entre TI e negócio, e BPM ajudaria isso de forma efetiva através de uma notação para mapeamento de processos, no caso BPMN. Existe forma mais efetiva do que representar ações no formato de desenhos e diagramas? Dessa forma analistas de negócio e analistas de processos conseguem trabalhar juntos com times de TI na implantação e implementação de uma arquitetura SOA, onde através do mapeamento dos processos de negócio, conseguiriam identificar serviços que agreguem e tenham importância para o negócio de uma organização, identificando assim a necessidade de implementá-los.

Em relação a possibilidade de mudanças, BPM oferece todo suporte e facilidade para mudanças através da visão holística que o mapeamento de um processo de negócio proporciona, dando a possibilidade de visualização de papéis, atividades, setores, departamentos e parceiros de uma organização, ou seja, todos os stakeholders, além do conhecimento de todo fluxo da informação.

Do ponto de vista da automatização de processos de negócio, através dos softwares BPMS, BPM oferece adaptadores e conectores para realizar a integração entre sistemas legados através da exposição de serviços e atuando na composição e orquestração desses serviços, BPM proporciona uma “API visual” de toda as integrações e uma facilidade maior de manutenção e mudança.

BPM no topo de uma arquitetura SOA

BPM deve atuar no topo de uma arquitetura orientada a serviços, pois uma arquitetura SOA deve focar de ponta-a-ponta no negócio, e dessa forma BPM atuaria do ínicio ao fim em uma arquitetura SOA.

BPM proporciona o melhor uso de serviços de negócio oferecidos por SOA gerenciando a relação entre eles sob o ponto de vista de processos de negócio.

BPM ajuda na Governança de SOA

Numa arquitetura SOA, consumidores e fornecedores de serviço são executados em diferentes processos de negócio, são desenvolvidos e gerenciados por diferentes departamentos e exigem um grande número de coordenação para trabalhar juntos com sucesso.

Para SOA ter êxito, múltiplas aplicações precisam compartilhar serviços comuns, o que significa que eles precisam ser coordenados para tornarem estes serviços comuns e reutilizáveis (olha o BPM aí!). Estes são os problemas de governança e eles são muito mais complexos do que problemas de aplicações monolíticas ou mesmo problemas de componentes e códigos reutilizáveis.

Exemplo real

Fiz um rascunho simples de uma arquitetura em camadas que utiliza BPM, SOA e BPEL e que estará exemplificada logo abaixo. O processo é para um banco e o intuito é fornecer o empréstimo de uma quantia em dinheiro para um cliente, que no caso é quem faz essa solicitação. Tudo começa e termina no BPM, que atua como um orquestrador de serviços.

Nesse exemplo temos serviços em um nível mais baixo, que no caso são serviços expostos por sistemas de terceiros, módulos de ERP, CRM, etc. Temos nível intermediário com um processo de negócio BPEL que faz a composição de alguns serviços presentes no nível mais baixo e no topo de tudo temos o BPM orquestrando todos os serviços e controlando todo o processo.

Diagrama de uma arquitetura SOA com BPM

clique para ampliar


Para finalizar, é importante ressaltar que através do uso de BPM e de BPMS, é possível definir métricas e indicadores, comos os KPI’s (Key Performance Indicators) e utilizar ferramentas que dão todo suporte para acompanhamento de nossos processos de negócio, como as ferramentas de BAM, onde o intuito seria fornecer relatórios em tempo real que podem servir como caráter estratégico e para tomadas de decisão, além também da possibilidade de usar as informações geradas para alimentar ferramentas de BI (Business Inteligence) e consequentemente obter resultados mais completos para a organização.

BPM, SOA

Usando PAPI para criar e recuperar instância de processos no ALBPM/OracleBPM

O PAPI (Process API) é uma API do ALBPM/OracleBPM que permite que se possa interagir diretamente com a engine de execução de processos da ferramenta, e dentre outras coisas é possível: criar instâncias, recuperar instâncias, realizar buscas, abortar instâncias, enviar notificações, auditar uma instância, etc.

Ou seja, é muito importante sabermos que essa API existe e principalmente sabermos como usá-la. Existem duas maneiras de usá-la: externa e internamente. Externamente isso pode ser feito usando o PAPI-WS, que são serviços expostos pelo próprio ALBPM para que se possa usar o PAPI, porém um pouco limitado. Outra opção é usando a JAVA API, que é mais completa. Dentro do ALBPM usamos diretamente a Java API através do Catálogo de API’s da ferramenta.

Criando e Recuperando Instâncias de Processos

Fiz um exemplo de código bem simples no ALBPM para poder apresentar como criar instâncias e recuperar instâncias de processos. Seguem os dois exemplos com os respectivos comentários:

Criando Instâncias
Para criar instâncias é muito simples, basta usarmos o método create da API ProcessInstance, passando como parâmetros o ID do processo (sempre com “/” na frente), os argumentos de incialização (caso existam), e o nome do método de inicialização, que pode ser visto através da opção “argument mapping” do evento de inicialização. Segue o código:

 Java |  copiar código |? 
1
2
String processCreateResult = create(processId : "/Teste", arguments : null, argumentsSetName : "BeginIn");
3

Recuperando Instâncias
Para recuperar instâncias também é muito simples, mas devemos ter atenção com a autenticação no DirectoryService onde o projeto correspondente a instância a ser recuperada está deployado.

Esse passo é necessário, pois para recuperar instâncias é usada outra API, no caso a API ProcessService e para tal precisamos autenticar no DirectoryService antes de tentar recuperar a instância de fato.

Para autenticação no DirectoryService, usamos o método connectTo da API ProcessService, e esse método espera 3 parâmetros: A URL do DirectoryService (pode-se usar as constantes como no exemplo abaixo), o usuário e a senha. O usuário e a senha devem possuir a role onde a atividade de criação da instância está associada.

 Java |  copiar código |? 
1
2
(ProcessService).connectTo(url : Fuego.Server.directoryURL, user : "tester", password : "tester");
3
businessProcess = (ProcessService).getProcess(process : "/Teste");
4

Agora para visualizar o resultado, basta o seguinte código:

 Java |  copiar código |? 
1
2
logMessage("-------------------------------------------------------------------");
3
logMessage("Instância do Processo Criado: "+processCreateResult);
4
logMessage("Referência da Instância Recuperada: "+businessProcess);
5
logMessage("-------------------------------------------------------------------");
6

BPM

Vivendo e aprendendo

Eu acredito que um bom profissional, independente da profissão, sabe sempre que pode melhorar mais, sabe que pode chegar a um nível mais elevado que o seu atual e sabe principalmente que faltam ainda muitas coisas pra ele aprender e se aperfeiçoar. Não conhecer ou ter domínio sobre determinado assunto, não significa que não sejamos bons profissionais e que não sejamos competentes, afinal sempre existirá algo para se aprender. Não existe o ápice, o topo ou o nível máximo na carreira de um profissional, isso é uma utopia e quem acredita que chegou a tal nível, demonstra precisar aprender mais do que qualquer um.

Na minha opinião, para uma pessoa ser considerada um bom profissional ela precisa ter principalmente 3 características, são elas: estudo, experiência e o famoso pensamento “out of the box“.

É claro, que existem outros fatores não menos importantes, como: bom relacionamento inter-pessoal, ambição, humildade, caráter, etc, mas que não citei, pois acredito que isso já deveria ser parte do cidadão, da pessoa e se não somos bons cidadãos, boas pessoas, dificilmente seremos um bom profissional.

Voltando aos 3 tópicos citados acima, irei falar um pouco da minha percepção sobre cada um desses ítens e consequentemente o porque de eu considerá-los os mais valiosos.

Estudo

Desde que eu me entendo por gente, escuto que para “ser alguém na vida” eu deveria estudar muito, já que o mercado profissional é muito concorrido e blá blá blá.. aquele papo de sempre, chato, mas que não deixa de ser uma enorme verdade. Só que além de termos o desejo de ser um “profissional bem posicionado no mercado”, acredito ser mais importante estudarmos para entendermos o porque das coisas, para nos questionarmos, para questionarmos outras pessoas, para darmos outras idéias e consequentemente sairmos da inércia de um padrão estabelecido.

Estudar não significa só ir para escola e passar com nota boa, como também não significa só ir para faculdade e ter o melhor CR da turma, é óbvio que isso tudo é importante, mas há muitas coisas além disso.

Estudar significa ter interesse pelo que estamos lendo e pesquisando, significa termos curiosidade sobre o motivo de como as coisas funcionam, significa termos sempre aquela anseio por novos conhecimentos para irmos além. Estudar está diretamente ligado a nossa aptidão e gosto por determinado assunto, pois no meu modo de ver é impossível estudar e se interessar por algo em que não se tenha prazer. Quem nunca viu uma penca de pessoas estudando para um concurso durante anos e não sendo aprovada? Quem não conhece pessoas que foram muito mal na escola e que hoje são bons profissionais? Quem não conhece pessoas que não fizeram faculdade e hoje são bons profissionais? E finalmente, quem não conhece pessoas que são formadas em outra área e hoje são bons profissionais em outras? Eu já vi pessoas que se enquadram em todas essas situações.

Estudar também, nesse caso, é o contrário de acomodação, afinal quem estuda, lê e se informa, nunca está acomodado, está sempre por dentro das novidades, está sempre trocando e compartilhando conhecimento e consequemente desempenhando melhor a sua atividade profissional.

Experiência

Esse é um fator determinante para nos tornamos um bom profissional, quanto mais bagagem tivermos, mais fácil será prever alguns problemas, mais fácil será identificar problemas e mais fácil será criar soluções para os problemas.

Uma pessoa que está começando agora, com talento, interessada e esforçada, pode ser uma pessoa muito boa de se trabalhar, de fazer parte da sua equipe, mas ela só será considerada como um profissional completo (completo != topo), quando ela adquirir determinada experiência em sua área de atuação profissional. Por exemplo: existem bons médicos recém-formados, que estudaram, se especializaram e que lêem bastante, mas que provavelmente demorariam mais a associar alguns sintomas a determinada patalogia, que um médico, com as mesmas virtudes, mas com mais experiência, talvez identificasse mais rápido. Isso se chama experiência, bagagem.

Sendo específico no mercado de desenvolvimento de software: quem nunca viu aquele cara que trocou a versão de uma API usada em um projeto (que funcionava!) e passou a ter enormes problemas na aplicação? A intenção desse cara foi boa, com toda certeza, mas nesse caso lhe faltou experiência para saber que a nova versão da API pode impactar diretamente questões de ambiente e infra-estrutura. Provavelmente um profissional mais experiente, não mudaria a versão de uma API que já funcionava e era estável, por uma versão mais atual, só porque é mais atual, ele faria isso caso houvesse um BOM motivo.

Não tem jeito, se existem dois profissionais com o mesmo nível de estudo e de habilidade e técnica, o que tem mais experiência vai acabar se sobressaindo, pois esse saberá lhe dar com situações mais críticas, situações que exigem um tempo de resposta mais rápido e situações que exigem uma análise mais profunda para detecção do problema ou para bolar uma solução.

Pensamento “out of the box

Pensar de uma maneira “out of the box“, significa pensar em uma maneira de fazer algo fora dos padrões pré-estabelecidos, que poucas ou nenhuma pessoa pensaria da mesma forma, é ser criativo e imaginativo para criar e enxergar uma solução para um problema existente, é conseguir enxergar pra frente e pros lados.

Existem determinadas situações onde um problema requer uma solução “out of the box”, na indústria de software existem muitos casos em que uma solução “out of the box” foi usada para resolver determinado problema ou para criar determinado produto. Certa vez assisti a uma palestra do Guilherme Chapiewski onde ele (se eu não me engano) havia pensado em uma maneira de diminuir o tráfego (requests/responses) de comunicação do Twitter usando o protocolo XMPP, ao invés de apenas a sua API REST. Isso é pensar out of the box.

Não faltam exemplos sobre pensamentos “fora da caixa”, inclusive vários fora da indústria de software. Recentemente assisti um vídeo muito interessante sobre um projeto para o metrô de uma determinada cidade onde o trem não pararia. Esse vídeo pode ser visto aqui.

Por que eu estou dizendo isso tudo?

A idéia de publicar algo sobre o assunto surgiu essa semana, quando eu estava tentando resolver um problema pouco convencional reportado por um cliente.

Estamos dando suporte a algumas aplicações desenvolvidas por terceiros, portanto tudo fica mais difícil, e o erro reportado pelo cliente não conseguia ser reproduzido no meu ambiente de desenvolvimento, mas ao gerar um pacote para fazer o deploy no nosso ambiente de homologação interno, o mesmo erro que ocorria com o cliente, passou a ocorrer conosco.

O mais curioso é que o erro só acontecia em determinadas situações bem específicas MESMO, então toda possibilidade de identificação do erro ia por água baixo, pois não conseguiamos associar um erro ao outro, e a cada mudança nos valores das variáveis usadas para input no sistema, o erro não conseguia ser simulado novamente.

Até que um companheiro de trabalho começou a fazer perguntas que demonstravam toda sua experiência e um pensamento “out of the box” para enxergar o problema, eis o diálogo que tivemos:

- Qual arquitetura do SO do ambiente de desenvolvimento?
- 32 bits
- E de homologação?
- 32 também
- Qual JVM você tá usando em desenvolvimento?
- A da Sun
- E do ambiente de homologação é a da Sun também?
- Humm, não, é JRockit
- Experimenta mudar a do ambiente de homologação para Sun

Resumindo, mudei o ambiente de homologação para usar a JVM da Sun e o erro esquisito parou de ocorrer, a partir disso, conseguimos identificar que o problema estava ao realizar cálculos utilizando o tipo float, que não é o mais adequado para cálculos, mas que o código que já estava feito estava usando. O problema era no arredondamento do resultado do cálculo e de acordo com a arquitetura da JVM utilizada esse valor variava. Mudamos os tipos para BigDecimal e tiro e queda, problema resolvido, mesmo tendo JVM diferentes em ambientes diferentes.

O que se conclui é que o meu amigo teve uma sacada diferente para esse problema, conseguiu pensar de uma maneira “out of the box” e achar uma solução para o problema. Isso tudo baseado na sua experiência com linguagens de baixo nível, que sem dúvida lhe deu embasamento para pensar na razão da problema. Sem estudar, ele também não conseguiria ter essa percepção do problema.

E para você, quais são as principais características que determinam um bom profissional?

Carreira & Profissão

BPMS, workflow e legados

Vez ou outra recebo por email, dúvidas de pessoas que estão iniciando com BPM, estudando processos de negócio ou passando por alguma situação que envolva processos e TI, na maioria das vezes (quando as perguntas são bacanas) eu procuro respondê-las baseado na minha opinião pessoal.

Recentemente recebi duas dúvidas de uma analista de processos confusa com os termos comuns usados dentro dessa área de processos e também em relação a adoção de processos negócio servindo como orquestrador de sistemas legados.

Eis as perguntas e as minhas respostas:

1) Qual é a diferença básica entre o BPMS e um Workflow?

Os softwares BPMS se assemelham com Workflow de diversas maneiras, a principal delas é que ambos servem como apoio para gestão de processos de negócio, onde você consegue fazer o mapeamento, modelagem e desenho desses processo de negócio. Entretanto os BPMS, por serem uma suite, oferecem mais opções que um Workflow. Com ambos, tanto BPMS e Workflow, você consegue fazer a modelagem dos processos, mas no geral os BPMS são mais usados para execução, monitoração e automação de processos de negócio. Já o foco principal dos Workflow é servir como um “tradutor” de processos de negócios (e todos seus usuários, regras e cenários) para uma notação visual, que irá servir como uma espécie de documentação para uma visão macro (ou até mesmo mais detalhada, dependendo do caso) do processo de negócio.

Apesar de ser possível executar e automatizar processos de negócio com a tecnologia Workflow, OS BPMS possuem alguns recursos como BAM, BRM, facilidade de integração entre sistemas através de adaptadores, padrão de notação visual (BPMN), facilidade para orquestração de serviços (BPEL), que por exemplo um Workflow não possui.

Processos de negócio mais complexos são melhores atentidos com uma solução BPMS do que com Workflow.

Abaixo, dois bons links como complementação de leitura para esse tópico:

Workflow? BPM? I’m So Confused!

Comparing BPA and BPMS is like comparing apples and oranges

2) Posso utilizar um BPMS apenas para controle do processo? E continuar utilizando meus sistemas legados normalmente, sem mudar o trabalho dos usuários?

Quanto aos sistemas legados, como eu disse anteriormente, os BPMS oferecem ótimos recursos para integração com sistemas legados, seja através de Web Services, Banco de Dados, Filas JMS, dentre outros. Por isso não há a necessidade de que esses sistemas legados deixem de existir, eles podem muito bem ser orquestrados no seu processo de negócio utilizando uma solução BPMS, mas o que é muito importante e nunca deve ser esquecido é o real motivo da existência desse processo: por que ele existe? Para que ele existe? Qual seu foco? Essas são perguntas que não podem deixar de ser respondidas.

BPM