Defining load order and dependencies to your grails plugins 0

Hello all,

I’m buiding a simple Grails Plugin that will use GORM dynamic finders and methods, but as we should know, the create-plugin grails command just install a fresh skeleton of your grails application, without any other dependencies.

First of all, you shoud install the hibernate plugin inside your plugin. Don’t worry, the hibernate will not be packaged with your plugin, but will be there to your plugin classes use.

grails install-plugin hibernate

So, now your plugin have the hibernate plugin installed and will be capable to use GORM facilities. But, if people wants to use your plugin, they will have to have hibernate plugin installed, correct? I know it cames by default in our grails application, but can be uninstalled. So we have to find some way to make our plugin dependent on hibernate plugin. Asking on the grails-user list and reading this topic in grails.org wiki, I remembered on two plugin configurations that can help us:

  • dependsOn
  • loadAfter

The dependsOn it’s a map inside our XptoGrailsPlugin that tells witch plugins our one depends, it takes the name of the respective plugin and its version, in my case, that’s what I did:

def dependsOn = ["hibernate":"1.1 > *"]

So, our plugin will depend on grails hibernate plugin, and at least the 1.1 version of it, none previous will be accepted and any future ones will be ok!

But sometimes this is not enougth, besides being dependent, our plugin uses dynamic finders, and runtime added method on our domain classes, so, it’ll only be successfully loaded after hibernate plugin load and adds this methods. To achieve this, we’ll use the other tag, the loadAfter to tell that our plugin will wait hibernate plugin to be loaded and the load itself.

def loadAfter = ['hibernate']

That’s it. Doing this we’ll make things work as we wanted.

PS.: just noticed, right now that Graeme Rocher pushed to github’s grails master branch, a commit that will install de default plugins into new plugin projetcs too. This sounds cool, and will avoid us the first step above, the plugin installation. Here is the commit id and link: 9cb23f5b835b633cf43079ca7e58e29c64bd3b3c

Working with Excel and Grails 2

I found this 2 links in grailsbrasil.com forum.
It’s a nice feature to include in your system for that situations when user have to input a large amount of data.

First example shows how user can upload the excel file, and your system automatically load all the spreadsheet data into domain objects. And this one, shows the reverse way, by loading your domain objects into an excel file using JExcelAPI.

Recommend!

[]s,

[4/25] Jasper Reports in Grails with Dynamic-Jasper 9

This tutorial will talk about producing Jasper PDF reports (or any other format you’d like) in you grails app.  I took a look in grails plugins portal I found two plugins that could be used to do this.  The Jasper Plugin and the DynamicJasper Plugin. Depending on what you really need you’ll choose one.

I see the JasperPlugin as a more customizable plugin since you’ll use it o link to an existing jasper report (.jrxml / .jasper) you have. You’ll have some work building it, modeling it and sometimes even “drawing” it, but if you really need to do your and just your jasper, I recommend this one (congratulations for the Brazilians responsible for this plugin).

Otherwise (and covered in this tutorial), if you just need a simple report for your domain classes (an poor-but-effective PDF view of your scaffold listing) like I need in one project here, the DynamicJasper Plugin is gonna let you rock!

It’s a simple, and versatile plugin that generate its output entirely dynamic. This means that you won’t need to open iReport and show us your drawing skills (as a good programmer, you may suck drawing!).

We’ll work only with the Entities Report that Dynamic Jasper offer us, if you need complex queries on the reports, I recommend you reading the “named reports” in the plugins official documentation.

Are you following me and 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!

Tutorial Info

Groovy Version: 1.6
Grails Version: 1.1
Plugin Version: 0.5
Plugin Documentation: http://grails.org/plugin/dynamic-jasper
Download: source code

Basic setup

Well, our example this time will be a simple agenda, so, let’s create our agenda app, install the dynamic jasper plugin and then create our domain class with some constraints.

grails create-app agenda
grails install-plugin dynamic-jasper
grails create-domain-class Contact

Our initial Contact class will be this one

class Contact {
   String name
   String nickname
   Date bornAt
   String email
   String website
   String phone
   String mobilePhone
   String gender

   static constraints = {
      name(maxLength: 255)
      nickname(nullable: true)
      bornAt(nullable:true)
      email(email:true)
      website(link:true, nullable:true)
      phone()
      mobilePhone()
      gender(inList:["M","F"])
   }
}

Running the application and making it reportable

That’s it, you can run your application and test it if you want. Now we’re going to create our first report, the simplest one we can have. To do this just add this code to your domain class:

static def reportable = [:]

This map notation will tell what fields will be shown in the report and what options of it you’re configuring. As we do not specified any, all propeties will be there and the default report will be generated.

After this you can visit the report generator url at http://localhost:8080/agenda/djReport/index?entity=contact and this will generate a simple report file (no extension, you should add .pdf) of your contacts.

Very very simple, hã!

More options (personalization)

Now let’s configure some basic options of our report. First of all, I’ll not get all this properties in our agenda report, let’s get only the main fields (nick, phone, email):

def static reportable = [
   columns: ['nickname', 'email', 'phone']
]

You can run again the report, it will be similar to this one:

report

Now, there are some other basic options you might want to configure, like the filename, the report title and other stuff:

title: The report’s title, by default if you do not set anything it will be “[entity-name] report”.
fileName: The name that the response file generated will have
columns: the columns shown

def static reportable = [
   title: 'My agenda',
   fileName: 'agenda',
   columns: ['nickname', 'email', 'phone']
]

Second report

This three will help you start in this great plugin. Take a look in the plugin’s page to see all you can do.

It’s a simple but powerful plugin, you can adjust all the page layout, group properties, change the column titles, everything that does not involve the usual iReport drawing process.

Important Note

This note may be valid to other plugins either, but since grails 1.1, the installed plugins is not available in the project’s folder but in your HOME_DIR/.grails/1.1/projects/<project>/plugins

So, if you want to use advanced configuration of this (and others) plugin, you shoud enter its folder in ~/.grails/1.1/projects/agenda/plugins/, and get the configuration file of it, (in our case, DynamicJasperConfig.groovy) in its conf folder and save in our agenda/conf folder.

This file holds all plugin configuration and it can be used to setup the report layout and configure the named reports I said before.

Again, take a look in the plugin page and you’ll find everything you need! This is just an introduction of the plugin!

[]s,

Are you following me and 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!

Uma maneira bem ‘a-lá groovy’ de se acessar o último elemento de uma lista! 3

Oi,

Brincando com groovy e lendo alguns artigos durante o fim de semana na internet, vi umas coisas bacanas que facilitam o uso desta linguagem!

Uma coisa que achei bem legal foi uma dica de como acessar uma lista “de trás pra frente”. Isso mesmo, as vezes a gente precisa acessar o último elemento de uma lista certo? Como faríamos?

Vamos imaginar a lista abaixo:

def lista = []
lista << “first item”
lista << “second item”
lista << “third item”

Se eu quisesse imprimir seu conteudo para verificar, teria:

println lista[0] // “first item”
println lista[1] // “second item”
println lista[2] // “third item”

Para acessar o último termo, sem delongas iríamos ter que chamar posicionalmente o último elemento da lista, e para isso teríamos que conhecer seu tamanho. Teríamos:

lista.get(lista.size()-1); //Java
lista[lista.size -1] //groovy

Certo? A coisa bacana é que groovy tem todos os índices de um array/lista espelhados para a sua forma negativa. Ou seja. Se você acessar a segunda posição (lista[1]), irá ir para frente com o número inteiro. Se acessar a segunda posição negativa (lista[-2]), irá percorrer o segundo elemento de trás para frente!

Ou seja, para acessar o último elemento da lista, a forma mais rápida, fácil e com cheiro de groovy é fazer:

println lista[-1] //”third item”

Bacana hein! Valeu!

[]s,

The grooviest way to access the last item in a list 1

Hey!

Do you know that groovy provides a fuuny way to access the last item in a list? Let’s say you have the snippet above:

def lista = []
lista << “first item”
lista << “second item”
lista << “third item”

println lista[0] // “first item”
println lista[1] // “second item”
println lista[2] // “third item”

That’s ok hã. If you are using Java and needs to access the last item in this list, what should you do? I bet would be something like this (that is applicable to groovy):

lista.get(lista.size()-1); //Java
lista[lista.size -1] //groovy

I said “applicable” but doing this does not make me feel “groovier”… How about this trick?

lista[-1] //”third item”

That’s it! The indexes inside a list in groovy are “mirrored” backwards, so you can access the “first item from back to front” using the first negative integer! This is applicable to the rest of the entries:

println lista[-1] // “third item”
println lista[-2] // “second item”
println lista[-3] // “first item”

Take care!

[]s,

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