sexta-feira, março 20, 2009

RESTFul via Super Pipes

Hoje consegui finalmente ler os Pipes do Yahoo e produzir uma saída singela, porém expressiva para nosso propósito: Condensar tudo o que nossa equipe faz durante o dia (commits de SVN, builds automáticos ou manuais, backups, emails, agendas, atualizações de wikis, worklogs do Jira, blogs, etc) e ejetar essa saída em....bem, ainda não sei exatamente :)

O Super Pipe

O pipe que montei foi este abaixo:



que na prática, é responsável por ler feeds diversos de vários locais (nos quais nossa equipe produz informação - por exemplo, um commit do SVN gera um Feed com um comentário de log, o qual é lido pelo pipe) e ejetar uma saída padronizada (em laranja na figura).

Essa saída é um típico JSON, que então uso como entrada na nossa arquitetura RESTFul.

Arquitetura

Na verdade, esse JSON é apenas uma das entradas, uma vez que outras são provenientes de locais que (ainda) não geram Feeds. Por exemplo, algumas tabelas de banco de dados atualizadas por sistemas de legado e calendários internos não publicáveis.

Todas essas entradas são interpretadas pelo que chamei de Producers, ou seja, classes produtoras de informação... que podem vir de qualquer lugar.

Os producers colocam as informações em uma base (ainda não sei se vou usar JMS ou vou fazer de outra forma para processar de forma assíncrona ou sei lá como).

Estando nessa base, os chamados Consumers são responsáveis por ler as informações que têm interesse e gerar algum resultado útil, tal como... hum, deixa eu ver... atualizar os Twitters pessoais ou da empresa ;) ou mesmo enviar SMS para os celulares dos plantonistas, no caso de emergências em clientes (por exemplo, o monitoramento JOPr indicar uma tendência para consumo de memória excessivo ou então a queda de um servidor JBoss em produção).

Um esboço primário disso é mostrado abaixo:



Observa-se que os producers e consumers são estensíveis. Na prática, estou configurando eles via um padrão "Quasi-Command", os quais são automaticamente escaneados e carregados se estiverem no classpath da aplicação.

NOTA: Sim, sim, eu sei. Também discuti com meu colega J. a possibilidade de usar um ESB (como o JBossESB) para isso. Mas daí o trabalho seria maior (no sentido de montar toda a plataforma operacional) e, principalmente, eu não teria a chance de voltar a programar depois de quase meio ano parado.

E o RESTFul?

Toda a arquitetura é montada com base em HTTP, usando uma sopa de letrinhas, orquestrada pelo RestEasy e alguns frameworks para trabalho com XML e JSON (mas não usei JAXB - bom, pelo menos não ainda), com ênfase para XPath, para extração e manipulação de dados (como JSON convertido em XML/DOM).

Finalizando

Nessa sexta, devo colocar a aplicação na nossa área Incubator, e começar a ajustar os ponteiros.

Até agora, foi tudo desenvolvimento local, sem testes profundos com estilo...hum, cowboy (putz).

A partir da outra semana, a coisa deve ficar mais bonitinha :)

quarta-feira, março 18, 2009

Proxy AJP + No-Ip = Felicidade (ou Quase Isso)

Agora são 3:42AM, e não fui dormir ainda porque fiquei o dia inteiro atrás da porcaria da integração Yahoo Pipes ao nosso componente REST para o Google Calendar.

O problema começou porque o componente WebServices do Pipes não usa um MediaContent simples como "application/xml" ou "application/json". Ele insiste em usar algo mais exótico, como "application/x-www-form-urlencoded".

E aí a vaca vai pro brejo, pois os providers nativos do RestEasy não interpretam esse tipo de conteúdo, uma vez que ele é codificado.

Então, tive que partir para a criação de um provider customizado...

XStream

Mas pra variar, o Jettison parece não escrever Json com esse tipo de codificação, e então tive que apelar para o XStream, também lá da CodeHaus.

Ao juntar os dois, consegui parsear o Json e produzir meus objetos Java a partir do stream HTTP gerado pelo Yahoo Pipes. E fiquei quase feliz. Eu disse quase.

Trabalho x Casa

No trabalho, os meus Pipes do Yahoo apontam para nosso endereço http://jboss.lm2.com.br/xxx, qual é válido na Internet (ou seja, para os Pipes do Yahoo acessarem).

Mas em casa, a coisa é diferente. E tive que configurar meu Wireless e meu Modem ADSL para expor meu Tomcatezinho para Web.

Porém, o SpeedStream aqui da GVT me deu uma dor de cabeça do (...) e parece que os Forward das portas não funcionavam.

Cansado, apelei para o Putty, e acessando de um IP externo, percebi que meu Tomcatezinho realmente estava publicando as portas para a Web.

E fique um pouco mais quase feliz.

AJP + NO-IP = Felicidade (Quase)

A dúvida então era: Como manter uma URL única nos meus WebServices dos Pipes do Yahoo, tanto quanto eu estivesse desenvolvendo no ambiente de trabalho, ou em casa ou... em qualquer outro lugar?

A resposta veio com a duplinha AJP e No-Ip.

Via putty, configurei nosso servidor Apache para montar um balanceador, formado pela minha máquina enquanto eu estivesse dentro da rede da empresa, e outro nodo formado pelo... meu mesmo note, quando eu tivesse em casa ou em qualquer outro lugar.

Fiz isso usando o DNS do No-Ip, apontando para meu link pessoal. Veja abaixo como ficou:


BalancerMember ajp://192.168.20.233:8010 route=jvm1
BalancerMember ajp://mmrack.no-ip.info:8010 route=jvm1


Testei e funcionou, e fique quase feliz.

E por que quase? Porque agora são 04:00AM, e quando eu chegar atrasado no trabalho vão reclamar de mim, e ainda por cima, terei que validar meu processo de Json x Java para ver se tudo realmente está Ok.

Uma hora dessas eu canso.

terça-feira, março 17, 2009

A Maldita Anotação @LocalBean


Há pouco mais de um ano, eu estava postando sobre as novidades do EJB 3.1 - nossa, como o tempo passa! - e falava que a idéia do Bill (Burke) parecia que não iria vingar. Mas vingou.

Como todos já sabem (?), no Java EE 6 teremos o suporte à publicação local de EJBs, os quais poderão ser simples classes POJOs que não implementam nenhuma interface e que sejam anotadas com pouco mais do que @Stateless (@Stateful).

Isso seria muito legal, nao fosse o "pouco mais", conforme a página 84 (seção 4.4.2.2) da PFD (Proposed Final Draft) da JSR 318, que fala da maldita anotação @LocalBean.

A (Maldita) Anotação @LocalBean

Essa anotação não existia até agora, e é necessária para avisar o Container Java EE que o POJO em questão está sim publicando um EJB para acesso local.

Segundo a especificação isso é necessário porque podem existir EJBs que não desejam publicar um acesso local à sua funcionalidade de negócio e, situação que poderia incorrer em comportamentos anômolos durante o uso da aplicação...

Para mim isso soa como aquelas malditas e antiquadas interfaces LocalHome, RemoteHome e outras da série EJB 2.x, e em nada isso me sinaliza uma solução elegante para o problema.

Talvez minha mente obtusa não consiga enxergar muito longe e por isso eu esteja errado. Mas o é fato que colocar mais esta anotação incha ainda mais a especificação (copiando as palavras de Rod Johnson) e implica que EJBs pré-existentes tenham que ser, no mínímo, recompilados para funcionar (talvez até não, mas com certeza um re-empacotamento com descritores XML sobreescrevendo alguns comportamentos, isso sim).

O Bugs que Funcionavam

Quem acompanhou a Issue 751 e outras do JBossAS, sabia que na versão 4.0.5 era perfeitamente possível (e perfeitamente "funcionável") termos um EJB (ou uma interface) anotado com @Local e @Remote ao mesmo tempo.

Na versão 4.2 isso foi "corrigido" para, justamente (como dizia o Juvenal), aderir à especificação. Para mim, isso foi um caos - simplesmente tive que refazer vários dos meus EJBs nos processos de migração.

Ruby on Rails, Grails (e Outros da Série Convention Over Configuration)

Frameworks novos usam muito bem a prática da convenção ao invés da configuração. No mundo EJB (e Java EE), eu adoraria ver isso em prática.

Sim, demos um passo com a padronização (ainda rudimentar) do JNDI para os containers, porém precisaríamos caminhar mais rápido nesse cenário.

Anotações como @Stateless ou @Stateful são muito legais, mas poderiam simplesmente não existir, idem. E também poderíamos ter que nunca conhecer uma @LocalBean e nem mesmo se preocupar no projeto do sistema se vamos usar @Remote ou @Local sobre nossos elementos.

Com o andar da carruagem, simples modificações no container de IOC poderiam fazer todo esse mexe a qualquer momento, não exigindo a definição a priori, do comportamento de nossos beans no servidor de aplicação.

A (Longa) Estrada da Vida

A conversa poderia seguir indefinidamente, ao ponto de realmente modelarmos sistemas complexos segundo os princípios DDD, sem se preocupar com aspectos verticais no Stack (transações, contextos, clusters, local, remoto, etc, etc, etc). Em suma, um "mundo POJO" seria simplesmente lindo.

E isso não é utopia. Já podemos fazer muito disso com frameworks atuais e com o suporte a linguagens dinâmicas na Java 7, as coisas podem ir muito além. Muito além mesmo!

O "brabo" é fazer as pessoas pararem de pensar em novas e lindas Annotations.

quarta-feira, março 11, 2009

Automatizando o Twitter - O código-fonte

Aqui, continuo o post anterior sobre a automatização do Twitter, colocando o Screenshot dos resultados e, claro, o fragmento de código essencial do Eclipse.

O Resultado no Twitter.com



Nada demais :|

O Código-fonte da aplicação REST



Percebe-se que o código é simples, declarando um @Path para o serviço, e uma operação GET (na verdade que gostaria de fazer via PUT, mas isso vejo depois...)

Para executar, basta deployar a aplicacação (que é um .WAR simples - igualzinho aos exemplos que vem no RESTEasy) e acessar a URL, no browser ou via utilitário wget, como abaixo:

wget "http://localhost:8081/treelayer-twitter/twitter/status/mmrack@minhasenha/Atualizando meu status via RESTEasy, agora com o WGET do Linux."

Que produziu isso:



Enfim

Ou seja, segue o baile agora pra publicar minha aplicação REST na Web, e usar os Pipes do Yahoo pra manter meu Twitter atualizado com minhas demandas diárias.

terça-feira, março 10, 2009

Automatizando o Twitter

É incrível, mas eu ainda não tinha conta no Twitter. Hoje crei.

Mas o Twitter é uma coisa difícil para mim, pois não tenho tempo para ficar criando as shortmessages que ele precisa...bem, pelo menos não com a velocidade que ele espera.

Assim, qual a solução para eu ficar online nele? Automatização, claro.

O Projeto

Meu plano é o seguinte: Colocar tudo que eu faço durante o dia (commits em SVN públicos ou privados, gerência de projetos, atualização de documentos, Wiki, comentários em fóruns, posts de blogs, etc, etc, etc) e uma bacia, e tirar dela o que me interessa para então colocar isso no Twitter.

Mas como fazer isso? Mashups, claro!

Os Mashups

Primeiro, minha bacia pode ser os Pipes do Yahoo. Assim, posso criar uma série de tubinhos que conectam nas minhas fontes de dados acima e publicam um status final, a tal de shortmessage que o Twitter precisa.

Feito isso, uso um operador de Webservice do Pipes para chamar uma URL... e bem, esta URL é o legal e explico ela logo depois de...falar do JTwitter ;)

JTwitter

Procurei (tudo bem, talvez eu tenha procurado pouco) e não achei uma forma de chamar um REST do Twitter de forma fácil, seja pelo Pipes ou então pelo site do Twitter.

Então partir para as suas APIs... Escolhi o JTwitter por gostar do nome.

Depois, criei rapidamente um projetinho no Eclipse e, com ele, publiquei um update no Twitter pra ver se funcionava. Funcionou.

Meu Webservice Pessoal para o Twitter

Peguei minha classezinha acima e transformei ela em um Webservice - tudo bem, ainda não é um Webservice, mas é a tal de URL acima que eu comentei.

Com os pipes do Yahoo, eu acesso minha URL pessoal (ou Webservice) e passo os dados (da bacia) como parâmetro. Voilá, Twitter atualizado.

Resultados

O resultado é sequencias e sequencias de shortmessages no Twitter de forma automatizada, sem stress para mim e dando respaldo àqueles (vai crase mesmo?) que dizem que nós, informatas, precisamos estar sempre online.

Adoro essas coisas :)