Pensando em uma arquitetura simples para integração entre sistemas

Tentei bolar um título melhor para o tópico, porém confesso que não consegui, mas ainda assim acho que o título se aplica no que será falado nas próximas linhas.

O problema


Em um projeto pessoal recente precisei fazer a integração entre três sistemas distintos, na verdade os sistemas são distintos, mas não deveriam ser. Trata-se de um site e o que ocorre é que esse mesmo site possui três módulos (sistemas) que estão em plataformas, linguagens e lugares diferentes. Conclui-se que é um projeto que foi crescendo desordenadamente e que em nenhum momento ninguém pensou em uma maneira de organizar melhor os módulos e realizar as integrações. Como esses módulos foram feitos em linguagens e plataformas diferentes, o requisito número um do cliente era que esses módulos se comunicassem e que essa comunicação fosse transparente pra ele e para quem fosse administrar o sistema.

Cenário atual


O site é um pequeno site de e-commerce e dos três módulos existentes, um diz respeito ao frontend/backend do site e é feito com .NET/SQL Server, o outro módulo é o backend de vendas e é feito com PHP/MySQL e o último módulo é o de newsletter (mailing) que também está em PHP/MySQL. O módulo de vendas foi o último a ser desenvolvido e deveria ser mantido, o problema é que o administrador do sistema precisa “inputar” todas as vendas na mão, isso mesmo, na mão! Atualmente, quando um cliente tem interesse em algum produto do site, ele envia um email ao administrador informando qual(is) o(s) produto(s) ele tem interesse e os seus dados pessoais, e por sua vez o administrador entra no módulo de vendas, cadastra esse novo cliente, cria um pedido de venda, gera um login/senha para esse cliente e envia por email para que ele possa se autenticar no módulo de venda, concluir a compra e efetuar o pagamento.

Além de ser algo totalmente mecânico e nada prático, não há nenhuma relação entre os módulos do site e o administrador precisa reproduzir os dados do produto, que já existe em um módulo, em outro. Eram esses problemas que deveriam ser remediados.

Requisitos do cliente


Um dos requisitos do cliente, era de que o site (frontend e backend) deveria ser construído novamente, pois o atual além de ter sido construído em uma plataforma que ele não tinha mais interesse em manter, também estava incompleto e apresentando problemas, portanto o primeiro requisito era refazer todo o site com PHP/MySQL.

O segundo requisito era que o processo compra de produtos deveria ser todo feito através do site, pelo cliente, e não da forma arcaica como é atualmente e que foi descrita acima.

O terceiro requisito era que o módulo de vendas deveria ser mantido, pois ele atendia o que o cliente precisava, sendo assim o sistema que eu iria desenvolver deveria alimentar diretamente esse módulo de vendas.

Estrutura do módulo de vendas


Felizmente o módulo de vendas estava construído de uma maneira que facilitou o meu trabalho, quem o desenvolveu se preocupou em criar classes de modelo, uma camada de persistência e uma camada de negócio, portanto pude pensar em uma arquitetura simples em funcional muito em função disso.

Arquitetura pensada


Tentei pensar em algo que não criasse uma dependência entre os sistemas e que me fizesse mexer o minímo possível, ou nada, no módulo de vendas que seria mantido. Outros fatores que levei em consideração era que eu queria algo fácil de implementar, de dar manutenção e que de certa forma fosse rápido de desenvolver.

Conclui o desenvolvimento do (frontend/backend) e parti para pensar em uma arquitetura que me permitisse fazer tudo o que citei acima e que além disso me permitisse utilizar a boa estrutura que eu encontrei no módulo de vendas.

Para construir o site utilizei o Code Igniter, que é um framework que tenho prática, e também é leve e rápido de desenvolver, mas o que vale ressaltar é que arquitetura é algo que é independente de framework, portanto se eu tivesse utilizado qualquer outro framework, ou até mesmo se eu não tivesse utilizado nenhum framework, não faria a mínima diferença. Nesse caso os frameworks escolhidos só entram como facilitadores na implantação da arquitetura.

Mas voltando ao foco inicial, que é explicar a arquitetura, o que eu pensei foi em criar um Web Service com as operações específicas para tudo o que eu precisaria fazer no módulo de vendas, ou seja, eu precisaria identificar todas as ações que eu precisaria realizar para fazer essa integração e alimentar esse módulo. Na verdade, além de alimentar eu também precisaria recuperar algumas informações do módulo de vendas. Como os módulos (site, vendas, newsletter) ficariam provavelmente em servidores diferentes, em bancos diferentes e em estruturas diferentes essa era a forma mais limpa de realizar a integração sem causar dependência entre esses módulos e com isso dar manutenção seria bem mais fácil.

Como já estava definido que eu iria utilizar Web Service, eu optei por utilizar o formato RESTful, pois eles se encaixava perfeitamente na minha necessidade: me trazia simplicidade, praticidade, facilidade, além do que no meu caso a aplicabilidade de ROA, que é o conceito que Web Services RESTful utilizam, era muito mais evidente do que a abordagem de serviços.

O próximo passo era identificar os recursos necessários e criar as URI que eu utilizaria nos requests do meu Web Service REST, então ficou dessa forma:


Para desenvolver esse Web Service RESTful resolvi utilizar o Zend Framework, pois ele possui alguns componentes que me ajudariam a desenvolver esse Web Service mais rápido, como o suporte a Web Services RESTful, por exemplo, o ZF também tem uma API para trabalhar com JSON muito boa, então esse foi outro componente do ZF que eu resolvi utilizar.

Como no módulo de vendas já existiam classes de modelo que representavam as entidades do meu domínio, o que eu fiz foi criar uma estrutura JSON semelhante as essas entidades e que representaria os requests/responses do meu Web Service RESTful. Paralelo a isso criei algumas classes de apoio que serviriam como os Marshallers e Unmarshallers do Spring. Marshallers e unmarshallers são como data mappers, e no meu caso servem para eu mapear um objeto JSON para um objeto PHP (classes modelo) e também realizar o inverso.

Dessa forma com objetos JSON convertidos para objetos PHP que representavam as minhas classes modelo eu poderia usar a camada de persistência existente na aplicação para persistir todo objeto, então no caso de salvar um novo usuário, ficou assim:

 PHP |  copiar código |? 
01
function saveUser($user) {	
02
	$userObject = Unmarshaller::user(Zend_Json::decode($user));	
03
	$conn 	    = DB::getConnectionHandler();
04
 
05
	$result 	= $conn->user->save($userObject);	
06
 
07
	if ( $result )
08
		return array('status' => TRUE, 'response' => 'Usuário cadastrado com sucesso.');	
09
	else
10
		return array('status' => FALSE, 'response' => $conn->ErrorMsg());	 
11
 
12
}
13

Bem simples, né? No exemplo acima, criei algumas classes estáticas (utilitárias), a primeira me retorna um objeto de conexão com o banco de dados e a segunda classe representa o unmarshaller para transformar um Objeto JSON em uma classe de modelo que representa um usuário, após isso foi só persistir o usuário e retornar as mensagens correspondentes para quem está acessando recurso.

Visão geral


No fluxo de salvar um novo usuário, teríamos:

1) Site (módulo site) deseja salvar um novo usuário;
2) Site monta um objeto JSON com os dados que representam o novo usuário;
3) Site acessa o Web Service RESTful do módulo de venda através do recurso user/new;
4) No módulo de venda, o método mapeado para o recurso user/new, faz unmarshaller do objeto JSON mapeando os valores desse objeto JSON para uma classe de modelo;
5) O usuário é persistido através do objeto que foi mapeado no passo anterior;
6) O Web Service RESTful retorna a mensagem correspondente para o site.

Quando se fala em arquitetura é comum pensarmos em algo complexo, cheio de tecnologias, frameworks e etc, mas o foco de arquitetura não deve ser esse, o foco de arquitetura deve ser pensar em uma estrutura que prime pela organização, relacionamento e reuso dos componentes de softwares envolvidos em um sistema, onde o intuito deve ser facilitar e não complicar.


Arquitetura e Padrões

Download de projeto BPM para iniciantes no ALBPM (ou OracleBPM)

Hoje fiz uma apresentação sobre BPM e o BPMS Aqualogic BPM (ou OracleBPM) na empresa que eu trabalho, o objetivo era mostrar o que é BPM para quem não conhece e principalmente apresentar a solução BPMS citada em um projeto piloto.

Para apresentação, criei um projeto piloto “empréstimo bancário” onde é possível mostrar os conceitos mais básicos do ALBPM. Como imagino existirem mais pessoas com tal necessidade, irei disponibilizar o download do projeto, bem como o script SQL necessário para criação da tabela usada no projeto.

Os tópicos abordados na apresentação foram:

- O que é BPM e BPMS?

- BPMN

- BPM(s) não é arrastar e soltar figurinhas

- Workspace

- Processo

- Screenflow

- Atividades (Globais (Global Creation e Global), Automáticas, Interativas, Grab/Joins/Split)

- Transições

- BPM OBjects, Instance Variables, Local Variables, Project Variables

- Argumentos / Argument Mapping

- Business Parameters e Business Rules

- Exceções

- Grupos

- Connectors

- Logs (Log Viewer), Problems View, Variables View e Outline View

- Componentes (Catálogo)

- Organization (Roles, Usuários)

- Presentations e JSP

- External Resources

- Geração de “pacote” (.exp)

- SVN


Download do projeto.

Download do script SQL.

PS: O projeto não disponibiliza todos os tópicos abordados e citados acima, mas quase todos.


BPM

Evento internacional de BPM (DF, RJ, SP)

Vai acontencer nos dias 01, 06 e 07 de outrubro um evento internacional de BPM aqui no Brasil, onde teremos apresentações nas cidades de Brasília, Rio de Janeiro e São Paulo.

Segue a chamada do Evento:

A ELO Group e o GPI/UFRJ estão promovendo o evento internacional ‘Elaboração e Implantação de Estratégias de Sucesso em BPM’, com a participação do Prof. Michael Rosemann, uma referência mundial no assunto. O evento será realizado nos dias 01, 06 e 07 de outubro de 2009, nas cidades de Brasília, Rio de Janeiro e São Paulo, respectivamente. INSCRIÇÕES ABERTAS!

Uma das organizadoras do evento será a ELO Group, que vem tendo algumas iniciativas legais de BPM em prol da disseminação do conhecimento, duas dessas iniciativas são a publicação BPM 360 e também Webinars gratuitos.

BPM

Wizard de formulários com JS sem bibliotecas

Em um projeto que estou participando, temos um formulário para lá de grande, são 5 passos, ou seja, um wizard e sendo que em um dos passos existe uma tela com mais de 100 inputs, sendo que esse valor é dinâmico, mas dificilmente tem menos que 100 inputs, é mais normal ter mais do que isso.

Estávamos usando o jQuery até então, que é uma biblioteca JS, que contém inúmeros plugins, além de vários facilitadores para construção de aplicações mais interativas. Acho bacana terem surgidos várias bibliotecas JS, onde o jQuery talvez seja a principal dessas, pois com isso o nível de interatividade entre o usuário e as aplicações aumentaram consideravelmente e isso trás (ou pelo menos deveria) outros prós, como: facilidade de navegação e usabilidade mais intuitiva nas interfaces que fazem o bom uso desses recursos. Para os desenvolvedores sem dúvidas também foi algo positivo, pois é bem tranquilo hoje fazer uma requisição ajax com uma linha de script, além de termos também um código mais organizado e estruturado.

Só que eu sempre tive um certo receio em relação a essas bibliotecas, não com as bibliotecas em si, mas da forma que alguns desenvolvedores as usam, principalmente em caso de aplicações para um grande número de acessos em um ambiente mais “pesado”, já vi alguns casos em que o uso dessas bibliotecas atrapalhou mais do que ajudou e recentemente isso aconteceu comigo.

Utilizei um plugin do jQuery pronto para criar wizards de formulário, ou formulário no formato de wizard, como preferir. Esse plugin, além de ser pouco flexível, causou um problema na minha aplicação justamente no wizard que possui vários inputs. O problema é que ao entrar nesse wizard, o browser simplesmente para durante uns 3s, respira, e depois mostra o wizard, e vamos combinar que isso é muito esquisito, não é um comportamento normal. Para ser sincero não consegui identificar a causa principal, mas desconfio de várias coisas, primeiro é que no geral essas bibliotecas são muito pesadas, só para esse wizard de form eram mais de 50kb de arquivo, algo desnecessário, ainda mais considerando um ambiente com MUITO VOLUME de acessos, pois isso acaba causando um overhead. O segundo é em relação ao código da função para geração do wizard, achei o mesmo extenso demais para fazer algo que funciona, mas que é pouco flexível. O terceiro é que essas bibliotecas JS já são uma abstração de N componentes nativos do JS e por mais que seja ínfimo, isso também pode ajudar a causar um overhead.

Mediante a esses percalços e também a falta de flexibilidade do script que eu utilizei, resolvi criar o meu próprio script para fazer o wizard do formulário, esse script é bem simples, não utiliza nenhuma biblioteca JS, é bem fácil de entender e extender, além de ser flexível. Falando assim parece até uma maravilha do mundo moderno hehe, mas realmente o script resolveu meus problemas de performance e me deu a flexibilidade que eu queria. Testei o mesmo no Firefox 3, Opera 9 e IE 7 e funcionou perfeitamente e da mesma maneira em ambos.

Para visualizar o script funcionando, basta clicar aqui, para fazer o download do mesmo, é só clicar aqui.

Se surgirem dúvidas ou problemas, sugiro criar um comentário que responderei somente por aqui, até porque caso outras pessoas que venham a utilizar o script tenham a mesma dúvida, já fico mais fácil de achar e procurar.



Web

Usando GET e POST corretamente

Pelo título do tópico parece um assunto básico, correto? E realmente é, mas infelizmente ainda vejo muitos desenvolvedores fazendo o mal uso dos métodos GET e POST do protocolo HTTP. Principalmente no caso de desenvolvedores Web, esse assunto deveria ser pré-requisito antes mesmo de aprender qualquer linguagem de programação, ou então, até antes mesmo de aprender HTML.

A especificação do protocolo HTTP diz, que o mesmo possui 8 métodos, porém os métodos geralmente mais usados são GET e POST. Quando aprendemos a desenvolver para Web, é comum lermos ou sermos informados, que o método POST deve ser usado em formulários e que o método GET deve ser usado através de links. Isso é uma inverdade.

Tanto o método GET, como o método POST, podem ser usados de várias maneiras, contudo existem boas práticas que indicam as melhores maneiras de fazer o uso desses métodos, a seguir explicarei melhor quais são essas maneiras.

Explicando GET e POST

O método GET faz a passagem de parâmetros para o servidor HTTP através de uma URL, enquanto o método POST envia um documento ao servidor HTTP com o conteúdo contido nesse documento (message body).

Quando usar GET e quando usar POST?

O método GET deve ser usado para acessar recursos, ou seja, para recuperar informações (dados), enquanto o método POST deve ser usado em ações que modifiquem essas informações.

Sendo mais claro, o método POST é usado em ações destrutivas, como: inscrição em algum serviço, modificação do estado de algum recurso no banco de dados, etc. Enquanto o método GET é usado em ações não destrutivas, como: buscas, listagens, etc.

Na prática

GET deve ser usado em operações seguras, justamente por ser indicado em ações que não modifiquem o estado de um recurso, pois imagine que você tenha em sua aplicação um link (GET) que leve a remoção de um determinado ítem, o que poderia acontecer no caso desse link ser indexado por algum web crawler? Pois bem, esse é um dos casos no qual o método POST seria indicado (operações não-seguras).

Exemplos reais

GET: query, buscas, filtros, listagem.

POST: inscrição em serviços (newsletter, por exemplo), alteração/edição/remoção de recursos em banco de dados, envio de email.

Referências

Architecture of the World Wide Web

The fundamental differences between “GET” and “POST”

URIs, Addressability, and the use of HTTP GET and POST

Form Submission

Web

Web Services: REST versus WS-*, WS-* versus REST

Um dos maiores problemas no desenvolvimento de software é a integração entre aplicações que foram construídas sobre plataformas/linguagens distintas, onde essas aplicações deveriam conversar entre si com o intuito de trocar informações. Para resolver, ou melhor, tentar resolver esse problema, foi proposto um padrão que atende pelo nome de Web Services, que hoje é um padrão mantido pela W3C e OASIS.

Web Services são componentes que permitem que duas aplicações troquem informações entre si utilizando um canal de comunicação (network), na maioria das vezes o protocolo HTTP. Existem alguns tipos de Web Services, mas os mais conhecidos e usados hoje em dia são: RPC, WS-* (WSDL/SOAP) e REST.

Dos padrões citados, provavelmente o formato mais conhecido e usado hoje em dia é o WS-*, que define que um serviço deve receber/responder mensagens no formato XML (SOAP) e deve possuir um contrato que defina os seus serviços (WSDL). Só que esse formato, principalmente depois da popularização do REST, vem sofrendo pesadas críticas de toda comunidade de desenvolvimento, que alega que esse formato é burocrático e complicado, enquanto o REST é um formato mais simples e objetivo.

Minha opinião é que tanto o padrão WS-* como o padrão REST não se substituem, pelo menos não por enquanto, e que tentar fazer essa comparação ainda não agrega, pois existem casos específicos onde REST é muito bem-vindo, assim como existem casos onde o padrão WS-* é muito bem-vindo.

WS-* - Vantagens e desvantagens


Uma das principais reclamações em relação a esse formato é que o mesmo possui N especificações e que isso o torna complexo e burocrático, e de certa forma eu concordo. Só para se ter uma idéia existem mais de 15 especificações para esse formato e conhecer todas é humanamente impossível e inviável.

Outra reclamação é em relação ao overhead que a troca de mensagens de um serviço no padrão WS-* pode causar, pois todas as mensagens precisam ser envelopadas dentro de um pacote SOAP, que nada mais é que um XML padronizado. Esse overhead é causado, pois dentro de um envelope SOAP, o que é usado é a menor parte do conteúdo que está ali contido, dessa forma há muito “lixo”.

Essas duas reclamações citadas acima, são as maiores reclamações dos desenvolvedores em relação a serviços WS-*, contudo no meu modo de ver existem também muitas vantagens no uso do formato WS-*, principalmente no que diz respeito a integração entre aplicações corporativas e também em relação a SOA.

Por exemplo, eu trabalho em um ambiente onde existem muitos serviços, muitos mesmos, e esses serviços são desenvolvidos por N fornecedores, em N plataformas distintas e são usados por N por aplicações. É um cenário bem complexo e eu não imaginaria esse cenário sem o uso do formato WS-*. E por quê? Em primeiro lugar porque ter um contrato formal desses serviços é totalmente necessário, afinal eu preciso saber o nome desses serviços, preciso saber o que eles estão esperando receber, o que eles irão me responder e como serão esses dados. Imagine se um serviço desses mudar o caos que seria?

Outro fator muito importante são as ferramentas de apoio, afinal elas além de facilitar o trabalho, trazem também produtividade. Existem N ferramentas que ajudam na simulação, testes, geração de Mock’s, teste de carga, debug e tantas outras atividades necessárias no desenvolvimento/acesso a esses serviços. A principal ferramenta free usada hoje em dia é o soapUI.

Em relação a SOA, o formato WS-* também se mostra a melhor opção. SOA é uma maneira de se construir softwares baseado no conceito de serviços, onde esses serviços devem possuir um contrato formal, devem ser independentes (possuir baixo acoplamento) e devem ser reutilizáveis. Outro princípio de SOA diz que esses serviços devem ter a capacidade de serem descobertos e nesse ponto o WS-* mais uma vez sai na frente, pois o mesmo possui o protocolo UDDI, que é um método utilizado para publicar e descobrir diretórios de serviço em uma arquitetura SOA.

REST - O que é, vantagens e desvantagens


REST é o acrônimo de Representational State Transfer, que é um modelo de arquitetura baseado no protocolo HTTP e que utiliza URI para identificação dos seus serviços. REST é uma maneira de construir serviços usando o protocolo HTTP como ele foi concebido, ou seja, usando: POST, GET, DELETE e PUT.

Serviços RESTful (serviços REST) partem do princípio que o protocolo HTTP é rico o suficiente para que seja criada uma abstração - no caso WS-* seria uma abstração - para construção de serviços.

Uma das vantagens em utilizar serviços REST sem dúvida nenhuma é a simplicidade, afinal criar serviços REST é usar de maneira parecida o protocolo HTTP como usamos atualmente no desenvolvimento de aplicações Web, ou seja, se você usa o método POST em um formulário, você consequentemente está usando REST, a única diferença é que o submit desse formulário devolveria um conteúdo HTML, quando que em um serviço RESTful o indicado seria devolver uma estrutura mais padronizada, no caso um XML ou um JSON, por exemplo.

Outra vantagem no uso de serviços REST é a performance, pois os seus request/response são infinitamente menores se comparados com os do formato WS-*, e são menores, porque não precisam ser envelopados dentro de um pacote SOAP, serviços REST apenas recebem o que precisam e consequentemente respondem o que é necessário.

Serviços construídos no formato REST também são mais humanos, ou seja, são mais compreensíveis que serviços WS-*. Isso se deve ao fato de que para construir um serviço REST não é necessário conhecer N especificações, não é necessário saber o que é WSDL, assim como também não é necessário conhecer um pacote SOAP. São mais humanos também, pois são identificados através de URI’s.

Dentre outras vantagens de serviços RESTful destaco a possibilidade de fazer cache das operações, possibilidade de criar camadas intermediárias (proxy, gateway, cache servers) com o intuito de aumentar a performance ou segurança e possibilidade de usar HTTPS nativamente.

Pensando em um ambiente corporativo, em aplicações enterprise e em arquitetura SOA, começam a surgir alguns problemas em relação a adoção de serviços REST, a começar pelo fato de que REST não possui um padrão oficial para descrição dos seus serviços, até existe uma frente interessada em criar esse padrão utilizando WADL, mas ainda não existe nada oficial, portanto essa é uma grande desvantagem.

Serviços REST também não possuem estado, são stateless, ao contrário de serviços WS-*, pois os mesmos podem possuir estado entre uma chamada e outra. Serviços REST também não permitem requisições assíncronas e utilizando o formato WS-* é possível fazer requisições sem que seja necessário esperar uma resposta.

Pensando em SOA, REST não é a melhor opção, afinal, conforme citado anteriormente, REST não possui um contrato formal para definir a interface dos seus serviços, assim como também não possui uma maneira para que esses serviços possam ser publicados e descobertos.

Outra desvantagem no meu modo de ver, é que para construção de um processo BPEL, se faz por necessário que os serviços possuam uma interface que os descreva (WSDL), nesse caso serviços REST não seriam os mais indicados para serem usados dentro de um processo BPEL, contudo existem algumas maneiras de realizar esse workaround para usar serviços REST dentro de um processo BPEL. Dependendo da ferramenta escolhida, algumas fornecem soluções como a criação de Partner Links HTTP, ou seja, são Partner Links próprios para serviços REST, ou então, algumas outras ferramentas fornecem maneiras um pouco mais trabalhosas como a criação de um WSDL que descreva o serviço HTTP (REST).

Afinal, qual devo usar?


Sinto lhe frustrar, mas a resposta para essa pergunta é: depende, cada caso é um caso.

Não é inteligente ignorar uma ou outra opção, ou ser cego a ponto de desconsiderar os benefícios e vantagens de cada uma. Na minha opinião, fomentar essa discussão é cair no mesmo de discutir “qual linguagem é melhor”, afinal cada uma tem seu propósito.

Os fanáticos por REST costumam dizer que o formato WS-* só existe, pois os grandes players do mercado (Oracle, IBM, Microsoft, etc) estão envolvidos, já que esses grandes players desenvolvem ferramentas específicas para facilitar a criação e a manutenção a serviços construídos dessa maneira. Quem faz essa afirmação está completamente equivocado, pois por mais burocrático que serviços WS-* possam ser, eles ainda possuem uma enorme utilidade que serviços REST ainda não satisfazem.

Agora, no caso de serviços para celulares, PDA’s, e outros dispositivos móveis, onde cada dado enviado/recebido tem um custo alto, utilizar serviços REST é sem dúvida a melhor opção. Da mesma maneira que para prover serviços de aplicativos web, como mashups, REST também é a melhor opção, a maior prova disso é que em serviços como Twitter, Facebook, Amazon e até mesmo o Google, estão usando REST em larga escala.

Mas também existe o outro lado da moeda, pois pensando em um ambiente complexo, com muitos serviços, repositórios, ainda não dá para pensar em outro formato que não seja WS-*.

Enfim, mais uma vez volto ao ponto de que devemos conhecer as opções para tomar a decisão de escolher o que é mais adequado, REST não substitui WS-* e vice-versa, insistir nessa rixa não agrega e quem não enxerga dessa maneira, precisa rever seus conceitos, ou então estudar mais.

Aproveito para deixar o link para download de uma apresentação sobre REST, que fiz no meio do ano passado, na empresa que eu trabalho: clique para fazer download.

SOA

Primeiras impressões sobre o Yii framework

Seguindo a febre de frameworks, que borbulham a todo momento, em todas as linguagens, de todos os gostos, surge então mais um! Na verdade, se fosse mais um eu nem me daria ao trabalho de estar escrevendo sobre algo que seria irrelevante, mas esse tal de Yii Framework ao que me parece veio para ficar, mesmo tendo pouquíssimo contato com ele, acho que dá para afirmar isso com alguma certeza.

O que é o Yii Framework?

O Yii é um framework que está sendo mantido e desenvolvido pelo criador do framework Prado, que é um famoso framework PHP baseado no conceito de event-driven programming, que a grosso modo seria um framework em que o seu fluxo é determinado por eventos.

Comparação com outros frameworks

Quando digo que o Yii não é mais um framework MVC, digo, pois ele parece ser muito mais maduro, estável, flexível e bem projetado que o restante, além do que ele é focado em performance, ou seja, foi desenvolvido pensando em aplicações Web “parrudas” e que precisam ser escaláveis.

Tenho alguma experiência com frameworks em PHP, já desenvolvi projetos que estão em produção usando o Kohana, Code Igniter e o Drupal (também é um framework!), além de já ter desenvolvido aplicações dummy usando o Zend Framework, Akelos e Cake, e por isso posso afirmar que o Yii é diferenciado. Por exemplo, o Code Igniter eu gosto bastante, mas ele é muito lightweight e não é PHP 5, o Zend Framework é sólido, mas na verdade é mais um conjunto de componentes do que um framework, o Kohana, que é um fork do CI, é interessante, mas ainda precisa comer muito feijão com arroz, o Cake sinceramente não me agrada e o Akelos é bem interessante, mas tem pouca comunidade e documentação. Nenhum desses, com exceção do ZF, me parece ser um projeto a longo prazo como o Yii.

O Yii é baseado em várias idéias do queridinho Ruby on Rails, e assim como o RoR possui geradores de código para gerar: controllers, models, scaffoldings apenas usando linha de comando. Ainda não me acostumei muito com essas idéias de geradores de código hehe, sou um pouco conservador em relação a isso, e muita “mágica” as vezes me preocupa, mas de qualquer maneira esses geradores trazem uma agilidade absurda e no final das contas se houver um equilíbrio entre agilidade e controle do que está sendo gerado, acho que vale muito a pena.

Principais atrativos

Além de ser bem projetado, com uma arquitetura bem definida, uso de design patterns e facilidade de ser extendido, o que me atraiu no Yii foi algumas features mais avançadas e que outros frameworks não possuem nativamente, como: sistema de cache em camadas (usando memcached e apc), suporte a web services (WS-*), internacionalização de verdade, sistema de autenticação/permissão usando RBAC, integração nativa com jQuery, acesso a dados usando DAO, ORM + ActiveRecord (com lazy loading, inclusive), etc.

Outro ponto que me convenceu foi a documentação, que é bem completa, clara e objetiva, possuindo manuais, tutorias, screencasts, fóruns e API.

O framework também é todo modularizado, permitindo que componentes sejam desenvolvidos para serem totalmente desacoplados da aplicação.

Aprendizado

A curva de aprendizado do Yii é muito mais alta que a do CI ou do Kohana, por exemplo, apesar de no site do framework dizer o contrário. Mesmo com o framework tendo uma documentação extensa, skeletons para construção da aplicação e geradores de código, entender como funciona o framework e sua arquitetura não é tão simples como os outros frameworks citados anteriormente, mas isso não quer dizer que o código seja ilegível, ou difícil de entender, muito pelo contrário, como a tendência dos frameworks hoje em dia é descomplicar e humanizar, acredito que o Yii tenho seguido essa linha, apenas acho que para um desenvolvedor inexperiente será mais árduo aprender o Yii do que o CI.

O que pode melhorar

Como é um framework recente, mesmo tendo muitas funcionalidades mais avançadas, algumas outras ainda senti falta. Por exemplo, o framework ainda não tem um suporte para testes, seja BDD ou TDD e isso hoje em dia é inaceitável. O RoR, por exemplo, é um framework que tem a parte de testes muito forte dentro do framework e toda sua comunidade também é assim, em PHP isso é um pouco diferente, portanto seria interessante que o Yii começasse a fornecer mecanismos para realização de testes, porém nada impede que se integre o SimpleTest ou PHPUnit com o Yii.

Outra coisa que senti falta também foi suporte para serviços REST, o framework apesar de oferecer suporte a Webservices, só oferece suporte para Webservices no padrão SOAP/WSDL, REST seria muito interessante, até mesmo porque um dos pilares do framework é performance.

Conclusão

Estou animado com esse novo framework, apesar de ter pouco contato, senti seriedade no trabalho, mas só posso afirmar tudo que eu disse depois que eu tiver uma experiência real com o framework.

No momento estou participando de um job novo, em que estou definindo o que será usado como framework web, na verdade, não gosto e não costumo usar tecnologias que não tenho experiência em projetos que estou a frente, mas como esse projeto não é crítico e nem complexo, possa ser que eu use o Yii para ter uma opinião formada sobre o mesmo, e caso eu opte realmente por essa opção, irei comunicando o progresso.


PHP

Mostrando mensagens de log no stdOut (console) do Weblogic

Essa é uma dica bem rapidinha, que na verdade estou postando, pois não achei nada no Google muito relevante a respeito. Como imagino que existem pessoas com o mesmo probleminha, então segue a dica logo abaixo.

Na aplicação web do projeto que estou trabalhando, nós fazemos o uso da API Commons Logging do Apache para poder fazer logging da aplicação, só que para o log aparecer corretamente no console existe um pequeno “macete”, que por incrivel que pareça não diz com mais detalhes na documentação do Weblogic.

O probleminha era, que por mais que eu fizesse o seguinte:

 Java |  copiar código |? 
01
02
public class SovWS {
03
 
04
	private static Log log =  LogFactory.getLog("SOV-"+SovWS.class);
05
 
06
	@WebMethod
07
	public SaveMetaResponseDocument saveMeta(SaveMetaRequestDocument request) {		
08
		log.info(this.getClass() + " iniciando a nova meta");
09
               ....
10
        }
11
}
12

Eu não conseguia fazer com que a mensagem de log aparecesse no console do Workshop, ainda que tudo estivesse correto.

Para resolver é muito simples, basta ir nas propriedades do projeto, ir nos facets do projeto e verificar se a extensão Weblogic Integrated Commons Logging está como um facet do projeto, se não estiver, está aí o problema e para resolver basta adicionar esse novo facet.

Para ter certeza que está tudo certinho, sugiro abrir o arquivo weblogic-application.xml e verificar se a seguinte configuração está presente:

 XML |  copiar código |? 
1
2
<wls:library-ref>
3
    <wls:library-name>wls-commonslogging-bridge</wls:library-name>
4
    <wls:specification-version>1.0</wls:specification-version>
5
    <wls:exact-match>true</wls:exact-match>
6
</wls:library-ref>
7

Se a seguinte configuração estiver presente, pronto, tudo ok! Agora o log deverá aparecer no console sem problemas.

PS: Só para ressaltar que essa dica é válida para ambiente de desenvolvimento.

Java

Oracle BPM com JSP e Ajax

Nos projetos de BPM que tenho participado utilizando o Oracle BPM como solução BPMS, dificilmente faço o uso de presentations, é muito mais comum eu optar em utilizar páginas JSP como camada de apresentação dos meus processos. Isso se dá pelo fato de que as presentations são bastante limitadas, e quando se faz por necessário ter interfaces mais elaboradas e customizadas, o JSP passa a ser a melhor opção.

Usando JSP, um novo leque de opções passou a existir e uma dessas opções passou a ser a possibilidade de usar Ajax. Ajax, para quem nunca ouviu falar, não é uma linguagem, uma API, tão pouco um framework, Ajax é o acrônimo de Asynchronous Javascript And XML e nada mais é que um conjunto de técnicas usadas para criar aplicações web interativas (RIA). Um dos pilares do Ajax é permitir comunicação assíncrona entre cliente e servidor utilizando requisições HTTP.

O Oracle BPM oferece uma maneira bem interessante de usar Ajax nas páginas JSP, mesmo não sendo nativa e também não tendo nada a respeito dizendo na documentação, é possível fazer a integração da camada de apresentação de um processo BPM com o próprio processo de uma maneira bem tranquila.

Para exemplificar isso melhor, criei um projeto bem simples no Oracle BPM, que na verdade só serve para mostrar como funciona essa integração entre páginas JSP e métodos dentro de um BPM Object através de Ajax.

Primeiros passos


Para começar, criei um BPM Object bem simples, que possui 3 atributos: name (String), mail (String), documents (String[]). Os dois primeiros atributos, que representam o nome e o email de alguém, são do tipo String e o terceiro atributo, que no caso representa os documentos de uma pessoa, é do tipo Array de String. Chamei esse objeto de: BpmObject.

Nesse mesmo objeto (BpmObject), criei ainda um método, esse método será responsável por retornar os documentos de um usuário. Na verdade esse é o método que irei chamar via requisição Ajax através de uma página JSP. O nome desse método ficou definido como getDocuments().

No futuro precisarei alterar esse objeto, mas eu explico depois.

Criando a página JSP


No Oracle BPM, para informar que a apresentação de determinado BPM Object deva se dar por meio de uma página JSP, se faz por necessário a utilização de Screenflows. Screenflow é um fluxo semelhante ao de um processo normal, mas a principal diferença é que o mesmo é executado por um participante único, ou seja, dentro de um Screenflow não existem lanes.

Após ter criado um processo normal, apenas com uma atividade do tipo Global Creation (para criar uma instância do processo) e também com uma Interactive Activity (para apontar para o Screenflow), parti para criação do Screenflow de fato. O Screenflow em questão, será tão simples quanto o processo no qual ele está associado, no caso contará apenas com uma única atividade do tipo Interactive Component Call, que será a responsável por “chamar” uma página JSP associando-a ao BPM Object criado no passo anterior.

Para chamar uma página JSP, se faz por necessária associar um BPM Object a mesma, então nesse caso criei um váriavel de instância do tipo BpmObject (o mesmo criado no primeiro passo) e dei o seu nome de bpmObject. Após isso, criei uma página JSP dentro de: /projetoBPM/webRoot/customJSP/ajaxPage.jsp.

O nome da página em questão é ajaxPage.jsp, e por enquanto ela irá possuir o seguinte código:

 Java |  copiar código |? 
01
02
<%@ page session="true"%>
03
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%>
04
<%@ taglib uri="http://fuego.com/jsp/ftl" prefix="f"%>
05
 
06
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
07
<html xmlns="http://www.w3.org/1999/xhtml">
08
    <head>
09
        <title>Teste Ajax/title>        
10
        <script type="text/javascript" src="<f:webResources relativePath='js/prototype-1.6.0.3.js'/>"></script>
11
    </head>
12
    <body leftmargin="0" topmargin="0">
13
 
14
    Teste Ajax
15
    <br/><br/>
16
    Nome: <c:out value="${bpmObject.nome}" /> 
17
    <br/><br/>
18
 
19
    <div id="teste"></div>
20
 
21
    </body>
22
 
23
</html>

Então, relembrando os passos até aqui:

1) Criação de BPM Object com 3 atributos e um método;
2) Criação de processo com uma atividade do tipo Global Creation e outra do tipo Interactive Activity;
3) Criação de Screenflow;
4) Associação (Implementation Type) da Interactive Activity do processo ao Screenflow criado;
5) Criação de atividade do tipo Interactive Component Call no Screenflow;
6) Criação de váriavel de instância no Screenflow com o tipo sendo o mesmo do BPM Object que foi criado no primeiro passo;
7) Definição do Implementation Type da Interactive Component Call como BPM Object Interactive Call;
8) Associação do BPM Object criado como váriavel de instância da Interactive Component Call do Screenflow;
9) Definição da página ajaxPage.jsp como JSP Presentation da Interactive Component Call do Screenflow.

Feito os passos acima, a estrutura do processo está pronta para criação da página JSP que irá fazer a requisição via Ajax a um método do BPM Object que foi criado no primeiro passo.

Fazendo a requisição Ajax e explicando alguns components da taglib do Oracle BPM


Para criação do mecanismo que irá fazer a requisição Ajax, se faz por necessário a utilização da taglib do Oracle BPM, sem ela não seria possível usar Ajax, ou então seria bastante árduo fazer tal integração.

Por exemplo, para incluir a biblioteca Prototype, que no caso será a responsável por fazer o “trabalho sujo” e criar o objeto XMLHttpRequest para fazer a requisição assíncrona, utilizei a tag f:webResources (linha 10). Esta tag inclui os resources inclusos no projeto BPM, sem que seja necessário informar explicitamente o context path da aplicação para inclusão de imagens, CSS ou Javascripts.

Outra tag importante é a f:invokeUrl, que no caso irá gerar a URL para execução de um método dentro de um BPM Object. Dessa forma, a página JSP precisa ser alterada, pois agora irá contar com uma função Javascript que irá fazer a chamada via Ajax ao método getDocuments() do BPM Object criado no primeiro passo, retornando o output do método para div teste.

Página JSP alterada:

 Java |  copiar código |? 
01
02
<%@ page session="true"%>
03
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%>
04
<%@ taglib uri="http://fuego.com/jsp/ftl" prefix="f"%>
05
 
06
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
07
<html xmlns="http://www.w3.org/1999/xhtml">
08
    <head>
09
        <title>Teste Ajax/title>        
10
        <script type="text/javascript" src="<f:webResources relativePath='js/prototype-1.6.0.3.js'/>"></script>
11
        <script>
12
        function callAjaxMethod () {
13
		var bpmUrl	='<f:invokeUrl var="bpmObject" methodName="getDocuments" />';		
14
		return bpmUrl;
15
	}        
16
 
17
	new Ajax.Updater('teste', callAjaxMethod());
18
        </script>
19
    </head>
20
    <body leftmargin="0" topmargin="0">
21
 
22
    Teste Ajax
23
    <br/><br/>
24
    Nome: <c:out value="${bpmObject.nome}" /> 
25
    <br/><br/>
26
 
27
    <div id="teste"></div>
28
 
29
    </body>
30
 
31
</html>
32

Repare que foi criada a função JS callAjaxMethod. Abaixo dessa função existe ainda a função JS Ajax.Updater, que no caso é uma função da biblioteca Prototype que irá fazer a chamada ao método do BPM Object, retornando seu output para a div teste.

Criando um output para o método getDocuments do BPM Object


Finalmente essa é a última parte desse pequeno tutorial. Agora a única coisa que falta é criar um output para o método do BPM Object que irá ser chamado via requisição Ajax.

Antes de mais nada, preciso dizer algo a respeito da tag f:invokeUrl, pois para ela funcionar corretamente existem algumas peculiariades.

Para um método de um BPM Object ser reconhecido por esta tag, ele deve ter uma das quatro assinaturas abaixo:

No caso, eu optei por utilizar a primeira opção, pois para usar a função Ajax.Updater da Prototype, eu preciso escrever diretamente no output do método, ao invés de setar as informações necessárias através dos seus atributos.

Em virtude disso, o método getDocuments do objeto BpmObject agora passará a ter a seguinte assinatura:

 Java |  copiar código |? 
1
2
getDocuments(Fuego.Net.HttpRequest request, Fuego.Net.HttpResponse response)
3

Agora, finalmente o código do método getDocuments, que ficará da seguinte maneira:

 Java |  copiar código |? 
1
2
for (String doc : documents) {
3
    response.bodyTextContent(arg1 : doc);
4
}
5

No código acima, estou percorrendo o atributo documents (array) e imprimindo no output todos os documentos definidos para aquele atributo, dessa forma, quando a função callAjaxMethod é chamada na página JSP, ela automaticamente chama (assincronamente) este método contido dentro do BPM Object, imprimindo todos os documentos definidos para dentro da div com o ID teste.

Conclusão


Utilizando os recursos corretos do Oracle BPM, como sua taglib e seus componentes, não é muito difícil fazer uma tela de apresentação mais interativa usando Ajax. No exemplo acima, foi criado um projeto bem simples, apenas para ilustrar, com o intuito de mostrar a atualização do conteúdo de uma div feita assincronamente através de uma requisição Ajax.



BPM

Ponto para o Rails!

É muito curioso ver todo o frenesi e o burburinho que o Rails (RoR) vem causando entre os desenvolvedores mundo a fora, pelo menos aos que estão próximos a mim isso é nítido, as pessoas ficam maravilhadas, quase em êxtase! Acho isso fantástico, pois de certa forma o RoR tem feito com que uma série de preconceitos sejam quebrados e esquecidos. E qual o principal motivo para tudo isso? A simplicidade e a praticidade.

Linguagens de programação tendem a ser parecidas com religião ou com times de futebol, a pessoa simplesmente escolhe uma e defende aquilo com todas as forças, geralmente de forma cega. Eu particularmente acredito que, para defender ou criticar algo, se faz por necessário conhecer profundamente aquilo que você defende ou critica, pois só assim você terá argumentos para apontar falhas ou reconhecer méritos. Sou, ainda, a favor da filosofia “cabeça aberta”, que em poucas palavras quer dizer: não tenha medo, muito menos preconceito, de conhecer algo novo, conheça para a partir disso você ter uma opinião formada se aquilo te agrada, ou não.

É comum acontecer em fóruns e em listas de discussão debates sobre “qual linguagem é melhor”, na maioria das vezes as pessoas atacam uma linguagem, ou defendem outra, simplesmente baseadas em sua opinião pessoal, ou melhor, baseados na falta de conhecimento. As pessoas não conseguem enxergar que todas têm seus prós e contras, como tudo na vida, e que a partir de uma situação real que é possível avaliar a melhor opção.

Eu comecei a programar através do PHP e hoje em dia trabalho basicamente só com Java. Programadores Java tendem a achar PHP um lixo, na maioria das vezes com embasamentos e teorias totalmente furadas, que demonstram tremenda falta de conhecimento. Eu concordo que o PHP tem uma má fama devido a linguagem ter demorado a amadurecer, como também concordo que o nível dos programadores em PHP no geral é baixo, é duro admitir, mas no geral é assim, provavelmente pela facilidade que a linguagem proporciona e também por sua curva de aprendizado ser bem mais baixa que a do Java, por exemplo. Mas isso quer dizer que o PHP é ruim? Eu poderia enumerar uma série de vantagens que o PHP tem em relação ao Java, da mesma forma que o Java tem uma série de outras vantagens em relação ao PHP, mas esse não é o foco do tópico, o foco é justamente o contrário.

Uma “nova” era


E para acabar, ou pelo menos ajudar bastante, surge o famoso framework Ruby on Rails, o hype do momento tratando-se de linguagem de programação! Ruby on Rails é um framework de desenvolvimento web que prega o conceito de que algo deve ser simples, prático e prazeroso de fazer, dessa forma inúmeros benefícios são alcançados, como: códigos com mais qualidade, tempo de desenvolvimento mais curto e comunidade participativa. Ruby on Rails não é uma linguagem de programação, é um framework, que foi desenvolvido em cima da linguagem Ruby, que é uma linguagem de programação criada por um japonês em 1995 baseada nos pontos fortes de várias linguagens da época. Reparou no trecho “…que havia de melhor em outras linguagens…”? Ou seja, o próprio criador da linguagem era (ou é) totalmente desprovido de preconceitos, e com isso conseguiu identificar os pontos fortes e fracos de várias linguagens com o intuito de criar uma, que no seu modo de ver, seria mais eficiente.

Complexidade não é sinal de qualidade


Uma linguagem de programação, um framework ou uma API, tem como principal objetivo (pelo menos deveria) fornecer uma maior praticidade aos desenvolvedores em solucionar problemas. Essa deveria ser a premissa básica para que uma determinada linguagem ou plataforma fosse adotada em um projeto, entretanto nada impede que N linguagens ou plataformas trabalhem de forma conjunta, desde que proporcionem alternativas para descomplicar o problema.

Só para esclarecer: simplicidade, praticidade, produtividade e facilidade nesse caso são sinônimos!

Outro ponto a ser observado é que a engenharia de software é um assunto relativamente novo, principalmente se formos comparar as outras engenharias, como a civil, e por isso é tão comum observarmos novas metodologias, padrões e linguagens surgindo a todo momento. Mas o que elas tem em comum é que todas tem como objetivo resolver os problemas da maneira “menos complexa” que for possível, é claro que outros fatores são levados em consideração, entretanto se paramos para pensar a simplicidade é sempre a prioridade.

E é por isso que o RoR está na crista da onda, pois talvez nenhum framework descomplique tanto as coisas como ele, e o melhor é que isso é contagioso, pois a todo momento surgem mais e mais frameworksRoR like“, em PHP existe uma penca deles, como: Akelos, Code Igniter, Cake, Kohana. Até o sempre conservador Java se rendeu ao RoR e lançou o Groovy (JSR 241) e consequentemente o Grails, que é um framework web baseado em quem? No Rails!

Maçãs são maçãs e bananas são bananas!


O título acima parece estranho, mas ele serve para deixar claro o seguinte: comparar linguagens não é algo inteligente, ao invés disso, procure conhecê-las e tirar proveito do melhor de cada uma. PHP é PHP, Java é Java, Python é Python! Assim como maçãs são maçãs e bananas são bananas, portanto não cabem comparações. Parece óbvio, e na verdade é, mas mesmo assim existem pessoas que ainda insistem em levar essa discussão adiante, onde dificilmente é tirado algum proveito.

Só para deixar claro, eu nunca desenvolvi uma aplicação sequer usando o RoR, já usei alguns frameworks “RoR like” e tive ótimas experiências, entretanto não acho que o RoR substitui o Java, o PHP, ou até mesmo o .NET, como eu já disse, cada um tem o seu propósito e por isso deve haver um equilíbrio na tomada de decisões sobre “o que escolher?”, fatores como: experiência com determinada linguagem, documentação, maturidade, infra-estrutura, segurança não podem ser esquecidos de forma alguma, pois no final é a sinergia entre vários fatores que determina as opções a serem escolhidas.

É normal, e de certa forma até compreensível, nos deixarmos levar pela emoção de conhecer um novo mundo e com isso embarcamos no erro de que a partir daquele momento tudo será feito “daquela forma”, com “aquela nova linguagem”, e isso é um erro, dos graves! Nesse ponto, a experiência, o conhecimento e o equilíbrio fazem toda a diferença na tomada de decisão mais acertada.

Só para finalizar, gostaria de ressaltar que nada impede que existam linguagens e frameworks ruins, é claro que eles existem, mas mais uma vez, para termos essa certeza é preciso conhecer. Da mesma forma que, não é só porque devemos abrir a nossa cabeça e olharmos para os lados, ao invés de olharmos só para frente, que devemos deixar de considerar nossas preferências e aquilo com que temos mais facilidade. Preferência e preconceito não são sinônimos.

Tecnologia, Software & Desenvolvimento