Infelizmente é comum vermos projetos que atrasam e/ou excedem o orçamento, sendo uma das principais razões a complexidade dos sistemas projetados. Uma das abordagens para construção de tais sistemas e mitigação dos riscos é a decomposição em partes integradas.
Sistemas integrados permitem comunicação entre celulares de empresas distintas, transações financeiras entre bancos, reservas de viagens e confirmações de hospedagens entre a agência de turismo, a empresa aérea e o hotel, por exemplo. Esses componentes devem se integrar com integridade e segurança.
A maioria de nós compreende a importância da integração de sistemas, embora raramente planejamos integrar nossos sistemas com os dos outros. Com o propósito de preencher o espaço entre sistemas que não têm interface de comunicação, temos os frameworks de integração, onde entra o Apache Camel. Ele é um framework que provê abstrações simples e gerenciáveis para as complexidades encontradas ao se integrar sistemas.
Antes que me acusem de plágio ou algo do gênero, quero deixar claro que esta série de artigos sobre Apache Camel é baseada no livro “Camel in Action”, do Ibsen e Anstey, publicado pela editora Manning (somente em inglês).
Junto com o conteúdo do livro, vou usar das experiências que tenho vivido num projeto real que visa integrar dezenas de lojas em vários estados brasileiros e um sistema e-commerce contratado de outra empresa.
Enfim, antes de descrever o Camel com maiores detalhes e apresentar suas vantagens, vamos ver o que ele pode fazer sem muitos rodeios. Digamos que você foi designado a criar uma funcionalidade em Java de backup dos arquivos, ou seja, precisa copiar todos os arquivos do diretório de entrada para outro diretório.
Para isso, irá lançar mão do pacote de classes java.io, e o resultado será algo parecido com o código abaixo:
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; public class Backuper { public static void main(String[] args) throws Exception { File diretorioDeEntrada = new File("dados/entrada"); File diretorioDeSaida = new File("dados/saida"); diretorioDeSaida.mkdir(); File[] arquivos = diretorioDeEntrada.listFiles(); for (File arquivoDeEntrada : arquivos) { if (arquivoDeEntrada.isFile()) { File arquivoDeSaida = new File(diretorioDeSaida.getPath() + File.separator + arquivoDeEntrada.getName()); copiarArquivo(arquivoDeEntrada, arquivoDeSaida); } private static void copiarArquivo(File source, File dest) throws IOException { OutputStream out = new FileOutputStream(dest); byte[] buffer = new byte[(int) source.length()]; FileInputStream in = new FileInputStream(source); in.read(buffer); try { out.write(buffer); } finally { out.close(); in.close(); } }
Embora este seja um exemplo simples, copiar arquivos entre diretórios, resultou em 36 linhas de código e fez uso de recursos de baixo nível (Stream). Consegue imaginar a complexidade que será acrescida para executar esse código rotineiramente? Vejamos como realizar este backup com o Apache Camel.
Antes de tudo precisamos fazer o download do Apache Camel. Procure baixar a versão mais recente. Descompacte o conteúdo do download em uma pasta. Você encontrará três diretórios:
- doc – um link para a documentação online.
- examples – vários projetos de exemplo.
- lib – todas as bibliotecas do Camel e suas dependências.
Noutra edição desta série utilizaremos o Maven para construir nossos projetos, mas para essa pequena explanação vamos usar o mínimo necessário.
Crie uma pasta chamada tutorialCamel01 e dentro dela crie outra chamada lib. Copie para tutorialCamel01/lib os arquivos:
- camel-core-2.8.3.jar
- commons-management-1.0.jar
- slf4j-api-1.6.1.jar
Procure estes arquivos dentro da pasta que você descompactou (apache-camel-2.8.3/lib). Como você percebeu, estou usando a versão 2.8.3 do Camel, pode ser que a versão que você baixou seja superior, mas deve funcionar da mesma forma. Para termos alguns dados para fazer o backup, crie um diretório dados/entrada e adicione alguns arquivos.
Agora crie um arquivo BackuperComCamel.java com o seguinte conteúdo:
import org.apache.camel.CamelContext; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.impl.DefaultCamelContext; public class BackuperComCamel { public static void main(String args[]) throws Exception { CamelContext contexto = new DefaultCamelContext(); contexto.addRoutes(new RouteBuilder() { public void configure() { from("file:dados/entrada?noop=true").to("file:dados/saida"); } }); contexto.start(); Thread.sleep(10000); contexto.stop(); } }
Logo de cara percebemos que o BackuperComCamel é bem menor que o Backuper, e com um pouco mais de atenção vamos notar que este código é muito mais entendível. A linha 10 é a que nos importa, o restante é boilerplate, ou seja, é um código que será reusado com poucas modificações.
Na linha 10 fazemos uso de uma DSL para dizer qual a fonte e o destino dos dados que serão manipulados. Veremos mais a fundo as DSL que o Camel suporta e como tirar melhor proveito delas.
Para ver Camel em ação, acesse o diretório do exercício por meio do bash do seu sistema operacional (o cmd do Windows por exemplo). Execute o seguinte comando para compilar a classe:
javac -cp .;lib/* BackuperComCamel.jav
Para executar o programa utilize o comando:
java -cp .;lib/* BackuperComCamel
O Camel então copia todos os arquivos do diretório de entrada para o diretório de saída, criando um se este não existir. Não foi necessário nenhum acesso a APIs de baixo nível. Podemos rapidamente entender o que o código está executando, já que fazemos uso de uma DSL.
Vimos, por meio de um exemplo simples, como é fácil trabalhar com Camel. No próximo artigo da série vamos entender sobre como o Camel realiza o roteamento.
Curiosidades:
- O nome do projeto não tem nenhum significado especial. O nome Camel foi escolhido por ser uma palavra pequena e fácil de lembrar. Há uma lista de outras possíveis razões para o nome do projeto.
- O projeto foi iniciado em 2007, e hoje é considerado um projeto open source maduro.
- Sua licença é Apache 2.
Até a próxima!