[3/25] Building a RSS Reader with Quartz Plugin – Grails Tutorial 4

Are you reading my blog’s feed? Be the first to know when I publish some interesting article signing up to my feed and following me on twitter!

 

Groovy Version: 1.6
Grails Version: 1.1
Plugin Version: 0.4.1-SNAPSHOT
Plugin Docs: http://grails.org/plugin/quartz
Download Resources: source code screencast 1 screencast 2

Hello,

In this tutorial, we’ll talk about the Quartz plugin used to schedule jobs executions in your application. The plugin is build on top of the Quartz Job Scheduler Library from OpenSymphony. OpenSympony is the company that built the WebWork framework, that is now called Struts2 after Apache “aquisition”.

“Scheduling jobs” is very useful in your application to cover background needs. Some tasks you’ll need to execute undercover your application some times (invalidating old users that have not logged for more than 1 month) or even async processes that you’ll have to do if you do not have a JMS infrastructure, for example, sending e-mails to a lot of people.

In our example, we’ll build a simple RSS Reader that will use the quartz plugin to schedule fetchs it will be done in the feeds and insert in the database. Our application will mainly have one domain class called Post (seen in the last tutorial), a Feed domain class to store our feeds and a similar RSS Parser from technorati.  (Yes, I love the RSS format).

Initially, we’ll create the app, install the quartz plugin, create the domain classes and the Feed scaffold structure

grails create-app feedreader
cd feedreader
grails install-plugin quartz
grails create-domain-class Post

We’ll insert the Post domain class code

class Post {
    String title
    String link
    String body
}

We have to create the Feed domain class and its scaffold structure.

grails create-domain-class Feed
class Feed {
    String word
    String url
}

Scaffolding…

grails generate-all Feed

screencast-1
screencast

After this, we’ll create our Technorati Feed Parser from this code above.

class TechnoratiService {
    boolean transactional = false
    def parseAndSave(rss) {
        def rssObj = new XmlSlurper().parse(rss)
        rssObj.channel.item.each {
            def post = new Post(title: it.title.toString(),
                    link: it.link.toString(),
                    body: it.description.toString())
            post.save()
            println "Post [${post}] saved."
        }
    }
}

We’ll run our application using the grails run-app command and insert some feeds. Note that we’ve configured our datasource to use hsqldb storing in the filesystem instead of regular memory setup. 

Note that we have one JobController that Quartz install for us, forget about it, ok? We’ll create our own job after the second screencast.

screencast-2
screencast

Now, we have to understant some quartz properties and commands. 

When we install the quatz plugin, it installs another command for us the grails create-job MyJob, with it we’ll create our FeedParserJob. Note that we use convention over configuration with all jobs having *Job names. 

grails create-job FeedParser

Job classes have to implement the execute() method. This method is the one that Quartz will trigger when it’s time to execute the job. To define when the job it will be executed and what’s the interval between executions, I suggest you read the plugin documentation witch shows N ways to do this. In our example we’ll use a cron expression similar to *N*X OS systems setting our job to execute once in five minutes.

Our cron expression will be like this:  “0 0/5 * * * ?”

Depending on your jobs requisites, it may run concurrently with another instance of it or not. In our case, we’ll not start other job execution if the last on is still running. To prevent this behavior, we can set the concurrent property to false

def concurrent = false

Our job will essentially look for the feeds we’ve inserted on the database, and for each one it will call the Technorati service asking for new Posts. The final source for our job is the one below:

class FeedParserJob {
    def concurrent = false
    def cronExpression = "0 0/5 * * * ?"
    
    def technoratiService

    def execute() {
        def feedList = Feed.findAll()
        for (Feed feed : feedList) {
            println "Reading feed ${feed.word} @ ${feed.url}"
            technoratiService.parseAndSave(feed.url)
        }
    }
}

As you can see in the example above, you can inject any spring bean in your job, just declare it as I did with my TechnoratiService! :) (this is really great!)

That’s it, if you run you application you’ll see that every 5 minutes (minutes 0,5,10,15…) the job will be called and every posts technorati returns will be inserted on your database. Note that in this simple example we did not check if the post had been already inserted in the database before inserting it, this will just grow our database with a lot of instances representing the same post. This can be avoided checking if the post already exists before inserting it  (just check if you have any Post with the same link), but I’ll left this for you!

Before finish this, let’s just improve a little bit our post list view.

 

Tela de posts

 

 

Now, try to enrich its interface, adding some ajax to get only the new posts since the last fech! Maybe you can start from this your new Google Reader killer! :P

Now, let me know, are you using this plugin in your production environment? What for? What kind of jobs you do with it? 

Thanks!

Are you reading my blog’s feed? Be the first to know when I publish some interesting article signing up to my feed and following me on twitter!

 

Next tutorial: [4of25] Jasper Plugin

Past tutorials:
        [2of25] Searchable Plugin
        [1of25] AcegiSecurity Plugin

Plugins para o GRails que eu recomendo 13

Brincando um pouco aqui com o Grails, pensando em uma aplicação “imaginária”, vi alguns plugins bem bacanas, que seriam úteis para esta e para, talvez, grande parte de aplicações por ai :) Segue 10 plugins que eu recomendo++:

  • OpenId Plugin

Se a sua aplicação não tem graaaaandes exigências e necessidades quanto a login, aproveite e utilize o mecanismo do OpenId, que descentraliza o login das aplicações. Vários sites implementam a especificação da OpenId e você pode logar em qualquer site que utilize este recurso com a openid cadastrada em qualquer um deles. Se você ainda não tem a sua, eu recomendo o serviço do MyOpenId. Uso ele e não tenho do que reclamar.

Url de documentação do plugin: http://www.grails.org/OpenID+Plugin

  • Acegi Security

Já se você tem grandes necessidades (que também dá pra implementar com o OpenId, mas fica mais chato), eu recomendo o Acegi Security Plugin, que usa o SpringSecurity por trás. É bem trivial e fácil de ser usado/configurado. Escrevi um tutorial passo-a-passo para utilizar ele no GrailsBrasil.com que está disponível neste link aqui.

Url de documentação do plugin: http://www.grails.org/AcegiSecurity+Plugin

  • Taggable

Este plugin facilita pra caramba se alguma entidade de seu sistema será “tagueável” (palavra do cão). Fornece a ‘infra-estrutura’ para adicionar e remover tags, além de contadores de tags, bem úteis para se implementar uma TagCloud.

Url de documentação do plugin: http://www.grails.org/Taggable+Plugin

  • Autocomplete e Star Rating

Estas duas funcionalidades vem em um único plugin, que traz muita, mas MUITA coisa bacana para enriquecer sua aplicação, é o RichUI Plugin (também já escrevi algo sobre ele no GrailsBrasil.com). Sinceramente, acho é o mais completo plugin na parte de interfaçe e interatividade.

Url de documentação do plugin: http://www.grails.org/RichUI+Plugin

  • RSS Feeds

Outro plugin indispensável, com ele você consegue gerar de uma maneira *bem* fácil feeds para seu site!

Url de documentação do plugin: http://www.grails.org/Feeds+Plugin

  • Avatar

Bom, denovo “para que”. Para que implementar um mecanismo de upload, de avatares para seu site, se hoje um dos sites que está em evidência por aí é o gravatar? Este site é bem banaca, e você vincula ao seu e-mail sua foto e pronto! Quando você entrar em um site “compliant” com o gravatar (com este plugin seu sistema se torna), os avatares simplesmente “aparecem” com o uso de uma simples taglib!

Url de documentação do plugin: http://www.grails.org/Avatar+Plugin

  • Mail

Um jeito muito fácil de se enviar e-mails. Disponível através de uma closure simples ou via service!

Url de documentação do plugin: http://www.grails.org/Mail+Plugin

  • JMS

Se você quer escalar a sua aplicação, se quiser se tornar o próximo twitter, não esqueça da “assincronidade” (irmã da taguear). Processos pesados/lentos como envio de emails, ou posts remotos (twitter por exemplo), devem ser feitos de forma assíncrona, garantindo que o usuário não pague o preço de uma instabilidade no sistema dependente!

Url de documentação do plugin: http://www.grails.org/JMS+Plugin

  • Twitter

Ahhhh o twitter, simplesmente twiitter! De um tempo pra cá me apaixonei por esse site e pela dinamicidade e interatividade dele. Então que tal um belo mashup do seu novo site/sistema com o twitter? Afinal, quer um jeito mais bacana de seus followers saberem que você tem novidades?

Url de documentação do plugin: http://www.grails.org/Twitter+Plugin

  • Commentable

Este também é bem bacana (foi colocado esta semana (junto com o Taggable) pelo Greame Rocher no repositório). Permite de uma forma muito simples, adicionar comentários a suas entidades, seja qual for ela, basta ativar o método .addComment(usuarioQueComentou, comentario). Bem legal, vale a pena para começar.

Url de documentação do plugin: http://grails.org/Commentable+Plugin

A lista completa de plugins pode ser vista aqui.

E você, quais plugins você usa? Quais você recomenda?

Construindo um serviço síncrono-assíncrono – parte 2: Aplicação Legada 0

Bom, como já disse, não gosto muito de chamar de “legadas” as aplicações que serão ativadas pelo BUS em um arquitetura SOA. A não ser é claro, que realmente façam jus a este nome. O que não gosto é de construir uma nova aplicação que conterá realmente a lógica de negócio do zero, e ainda chamá-la de legada, e olha que isso é mais comum do que pensamos.

Enfim, a nossa grande aplicação que será ativada pelo BUS via JMS, seguindo o desenho deste post se chamará “ReverseIt”, e conterá uma lógica nuclear de inverter a string que receberá como parâmetro. Não vou entrar em detalhes dos detalhes da criação do projeto na IDE, mas basicamente será um “Web Service Project” com o facet do XMLBeans Builder Library, para que ele converta nosso XSD em objetos java facilmente. A aplicação está rodando em um domínio Weblogic Server puro, em localhost:30000.

Vamos definir um schema XSD (dentro da pasta schemas) que contenha a operação de request e de response para a operação. Obviamente como temos um parâmetro string para entrada e outro para saída, ficaria algo bem trivial, basicamente o escrito abaixo:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
        targetNamespace="http://blog.lucastex.com/reverseit" 
        xmlns:revit="http://blog.lucastex.com/reverseit" 
        elementFormDefault="qualified">

    <element name="reverseItRequest" type="revit:ReverseItRequest"></element>
    <element name="reverseItResponse" type="revit:ReverseItResponse"></element>

    (...) definição e descrição dos tipos (...)

</schema>

Agora vamos:

  • Criar um web service como de costume
  • Configurar entrada do serviço para ReverseItRequest
  • Configurar saída do serviço para ReverItResponse
  • Escrever a lógica para inversão da palavra
     

public ReverseItResponseDocument reverseIt(ReverseItRequestDocument request) {
    
    (...) 1- Pegar input do request
    (...) 2- Inverter a string
    (...) 3- Retornar no response 

}

Legal, mas até aí temos o nosso Web Service tão padrão quanto todos que já fizemos, vamos agora para as anotações, que vão garantir que o serviço trabalhe de forma assíncrona. Bom, como ele funcionará via JMS, uma coisa que temos que fazer é criar uma fila JMS onde serão colocadas as mensagens que este serviço irá consumir, e também uma fila de resposta, para que ele coloque as mensagens de response. Não podemos esquecer também da ConnectionFactory o nosso serviço. Estes foram os nomes que eu dei:

  • Fila de Request: reversit.jms.requestQueue
  • Fila de Response: reverseit.jms.responseQueue
  • ConnectionFactory: reversit.jms.connectionFactory
Não vou entrar em detalhes da criação dos mesmos, não é este o foco da explicação.
Agora, vamos anotar nosso serviço para os resources criados.
@WLJmsTransport(serviceUri="ReverseIt", portName="ReverseItPort", connectionFactory="reverseit.jms.connectionFactory",  queue="reverseit.jms.requestQueue",  contextPath = "ReverseIt")
Nesta anotação WLJmsTransport, nós definimos o serviceURI e contextPath do serviço para que ele possa ser encontrado, também colocamos o connectionFactory e a queue de onde ele receberá as requisições, e também o nome do port que será criado no WSDL para este transporte. 
Uma coisa que pode intrigar caso alguém não esteja familiarizado com este conceito, é a doce pergunta: “Onde diabos o serviço sabe qual é a fila onde ele deverá colocar a resposta?”. Para isso, vale uma lida neste artigo sobre os padrões de resposta para mensageria assíncrona: Understanding Message ID and Correlation ID Patterns for JMS Request/Response . 
Prontinho, nosso serviço está funcionando de maneira JMS. Uma ponto muito (muito mesmo) legal e interessante, é que poderíamos expor este MESMO serviço via HTTP, apenas adicionando a anotação @WLHttpTransport com suas propriedades, e teríamos 2 ports diferentes na definição do WSDL.
Amanhã acho que consigo fazer a parte do Service BUS chamando ele, e transformando um request do terceiro (HTTP) para este nosso request (JMS). É nessa parte que tem o “pulo do gato” do produto.
Vamos deixar para testar assim que fizermos este passo.
Até,

Construindo um serviço síncrono-assíncrono com Aqualogic Service BUS 0

 

Bom, um dos cenários que eu mais tenho visto ultimamente em alguns dos lugares onde tenho passado, é quando o cliente quer disponibilizar um serviço para algum terceiro, porém faz questão (e está certo), que a partir do ponto de entrada do terceiro para o barramento de serviços do cliente esta requisição seja processada de forma totalmente assíncrona. 

Com isso, o cliente (que está processando a requisição) ganha em poder de processamento, e o terceiro (que está gerando a requisição) não percebe o que se passa “under the hood” (eu realmente gosto desta expressão), sendo para ele indiferente o que acontece durante o processamento.

Basicamente, este contexto é uma implementação de um Web-Service que utiliza como meio de transporte uma Fila JMS, ao invés do protocolo HTTP que é usado de costume.

Então, vou colocar aqui um exemplo de como fazer isso usando o Aqualogic Service Bus da Oracle (já era um produto da BEA).

Serão 3 pequenas aplicações para isto.

 

  • Aplicação Legacy (é um costume horrível chamar estas aplicações de “legadas” visto que em grande parte dos processos de implementação SOA nas empresas, elas são reconcebidas, ou sofrem pelo menos, muitas alterações): É a aplicação que efetivamente possui a lógica de negócio, receberá a requisição do cliente e devolverá a resposta já processada.
  • Configuração do Service BUS: Trata-se da exposição do serviço criado na aplicação legada no service BUS, como uma operação.
  • Aplicação Tester: É a aplicação que irá consumir o serviço da aplicação legada, através da operação e endpoint disponibilizado no Service BUS.

Um desenho bem feio, mas aproximado deste cenário poderia ser este abaixo (clique para ampliar)

 

 

Diagrama do exemplo

Diagrama do exemplo (clique para ampliar)

 

Bom, como meu tempo aqui se resume a pequenos intervalos onde eu poderia escrever isto, vou separar em 3 partes, uma para cada aplicação, um post para cada. Assim que der eu já começo!

Valeu!

Web Analytics