Serviços Liferay SOAP com Groovy
Muito mais simples, né? Pena que não funciona no
Liferay :-(
Primeiro, porque a API utilizada pelo GroovyWS (Apache CXF) não
suporta sobrecarga de métodos
e os WSDLs do Liferay estão recheados disso. Segundo, porque
a mesma API não
suporta serviços
RPC/encoded
e o ServiceBuilder gera tudo assim.
Uma pena, senão seria uma
baita mão na roda, né não? Se tiver
alguma ideia de como transpor esta dificuldade, por favor, deixe-nos um
comentário. Usar outra API Java para XML não vale
;-)
[]s
Liferay e seus Web Services
Quem acompanha de perto a rotina da SEA, seja pelo Twitter, pelo site ou nos corredores da vida, já sabe o quão envolvidos estamos com o Liferay Portal Server. Tornamo-nos sua primeira parceria oficial no Brasil e comemoramos agora o título de primeira parceria nível Gold da América Latina.
Neste tempo, vários projetos foram desenvolvidos e o
aprendizado foi enorme, No intuito de divulgar a tecnologia,
disponibilizamos alguns
slidecasts básicos,
fizemos alguns posts,
mas ainda ficamos na
dívida de uma continuação mais
avançada, que eu espero reverter a partir de agora.
Arquitetura Liferay
Internamente, o Liferay nada mais é do que um monte de
entidades de negócio que compartilham serviços
entre si para a composição do que chamamos de portal.
Cada portlet presente constitui-se de algum conjunto de
serviços que podem ser acessados por outros portlets do
portal ou mesmo por outros aplicativos externos ao servidor.
Esses serviços, geralmente criados a partir de uma
ferramenta interna da Liferay chamada de Service Builder,
compartilham de uma arquitetura padrão, que
até podemos tratar em outro post. Isso quer dizer que, se
você aprender a trabalhar com uma entidade de
negócio do Liferay, você automaticamente
terá aprendido a lógica por trás de
todas as demais entidades. Em síntese, a arquitetura
escolhida define uma estratégia de classes
utilitárias, service locators
e a possibilidade de
exposição local e remota da interface de
serviços em criação.
Dito isso, este post trata de como podemos utilizar a camada de Web
Services do
Liferay para acesso remoto à sua interface
pública de serviços.
Liferay Web Services
Todos os testes apresentados a seguir foram realizados numa
instalação virgem do liferay-portal-5.2-ee-sp4 e
num Eclipse Galileo com todo aquele suporte a JEE.
Primeiro de tudo, vamos ver a lista de serviços
disponíveis para acesso remoto. Para isso, inicie o Liferay
e acesse http://localhost:8080/tunnel-web/axis

Perceba que cada Web Service possui, além de um link para
seu WSDL, um conjunto de operações que podem ser
invocadas.
O próximo passo é a criação
das classes que farão o acesso a esses Web
Services. Você pode fazê-las na mão ou
utilizar-se de alguma ferramenta de apoio. Como não sou
mané, vou gerar todo este código utilizando um
recurso do próprio Eclipse.
Com o Eclipse abert, clique em File > New > Other
> Web Services > Web Service Client.

Em seguida, escolha o Web Service a ser acessado, copie o link de seu
WSDL para o clipboard (Ctrl + C) e informe-o na primeira tela de
criação do Web Service Client.


Clique em Finish
e aguarde a geração do código de
acesso ao Web Service escolhido.

Analise o código gerado e veja o tamanho do galho que a
ferramenta nos quebrou.
Por fim, utilizando as classes geradas, implemente o código
para acesso ao serviço remoto (clique na imagem para
ampliar).
![]() |
Pode até ser trabalhoso, mas é bem mais simples do que pensou, não? Como exercício, tente cadastrar, via Web Service, um novo artigo (JournalArticle) no portal.
[]s
Workshop/Dojo de Liferay na SEA 3
Para facilitar a comunicação e entender melhor o ambiente do cliente, facilitando também o feedback, é comum que a equipe de determinados projetos esteja quase sempre locada no próprio cliente. Por isso mesmo é que são buscadas diversas formas de se transmitir o conhecimento adquirido e as experiências entre os colegas e até com a comunidade. Entre estas formas de disseminar o que aprendemos nos nossos projetos, estão os blogs, filmes, trabalho em par e os Dojos. Neste contexto, resolvemos marcar em nossas agendas um horário na semana para falar de Liferay. O formato da reunião ainda está sendo moldado, e a primeira já aconteceu, na última sexta-feira, dia 9 de abril. Neste workshop-dojo de Liferay na SEA, Ian e Wesley começaram um bate-bola sobre Liferay para nivelar a turma presente. Abordaram temas como: Ferramenta para gerenciar conteúdo, uma forma de permitir atualização de um site, sistema ou portal, com informações, sem necessidade de conhecimentos específicos de desenvolvimento ou webdesign. O Liferay tem essa função - também. Applet java móvel: appLET PORTátil - daí o nome port+let. Basta baixar a versão community do Liferay já com o TomCat, na sua versão mais recente, e descompactar em sua máquina. Uma dica é descompactar na pasta Sites do Mac. E para acessar o servidor, abra o terminal, acesse a pasta do tomcat (dentro da pasta do Liferay portal), e procure a pasta bin, dentro dela, execute startup.sh ou o catalina.sh, assim: ./catalina.sh run Simples, baixe o plugin SDK no site do Liferay, e descompacte em seu computador, de preferência próximo à pasta do Liferay+tomcat. Localize o arquivo build.properties, dublique-o (para não modificar o original), e altere o nome de sua cópia para algo como build.seu_nome_de_usuario.properties. Agora abra o arquivo em um editor de texto/código, localize a linha referente à versão que você utiliza e aponte para a pasta do tomcat no seu computador: app.server.dir=/pasta_onde_está_seu_tomcat. Basta alterar a primeira linha, as demais são auto-referenciadas. Salve e feche. Via terminal, vá até a pasta "theme" dentro da pasta dos plugins, para criar o projeto do seu tema. Utilize o comando ./create.sh exemplo "Este é um Exemplo" (onde "exemplo" é o nome do projeto, tem que ser em letras minúsculas; e "Este é um Exemplo" será o nome para exibição do projeto e pode ter letras maiúsculas, acentos, etc. Aqui cabe uma dica extra. Às vezes, o comando não funciona de primeira, pois falta dar permissão para executar o create.sh: chmode +x create.sh ou se preferir dar permissão para todos os arquvios .sh, use chmode +x *.sh (dúvidas? procure o Funke) Ao fazer isso, é criada uma estrutura do projeto vazia. Mas não há necessidade de começar do zero, quando se pode apenas alterar o que é necessário, à partir de um tema completo pré-existente. Para "copiar" o tema Classic para o seu projeto, basta fazer uma alteração no build.xml: modifique o arquivo, sobrescrevendo "_styled" por "classic". Ao fazer o deploy, ele trará toda a estrutura do tema Classic, e nela, uma pasta _diff onde você poderá colocar apenas os itens que for alterar, e no deploy, estas alterações irão se sobrepor aos itens herdados do tema clássico, no seu tema. Dentro da pasta do tema, há a pasta _diff, além das pastas dos itens do tema, como css, images, templates, etc. Para fazer alguma modificação no seu tema novo, basta copiar o item a ser alterado, mantendo a estrutura de pastas, para a pasta _diff. Não altere os itens originais, apenas os que você copiar para a pasta _diff. Assim, você poderá fazer um deploy para verificar no próprio portal, as alterações feitas. Uma dica sobre CSS: quando for modificar os arquivos CSS, basta alterar o arquivo custom.css, pois ele foi criado exatamente para suas customizações. Ele é carregado por último e o que estiver nele, irá alterar as configurações de CSS dos demais arquivos. Os arquivos CSS estão organizados de modo que se você queira alterar algo relacionado à navegação, basta abrir o css de navegação, copiar e colar no seu custom.css apenas aquilo que você vai alterar. Os arquivos servem de referência para suas alterações. Depois de ter feito alguma modificação em seu tema, por exemplo, modificando a cor do fundo ou o tamanho das fontes no arquivo custom.css na pasta _diff/css do seu tema, você deve estar na pasta do seu tema (via terminal), e usar o comando ant deploy. É uma boa idéia ter o ant instalado, para que isso funcione. Outra dica é ter o port instalado caso você use um Mac, isso permitirá portar os comandos de unix para o Mac. É isso aí, foi muito interessante e instrutivo, e vamos repetir nesta sexta-feira mais uma rodada sobre Liferay. Para quem quiser buscar mais informações sobre o Liferay, a dica é acompanhar os slidecasts do minicurso de Liferay do Alê: 1 e 2, _3_ e _4_, e também buscar na própria comunidade do Liferay, que tem muito material informativo (em inglês), desde fórums a artigos em pdf.
Desenvolvimento de portlets com Rails - parte 2
No último post apresentamos uma forma de desenvolver portlets em Rails, falamos sobre a variável de ambiente GEM_HOME, que define um path único para as gems de todas as versões do Ruby (incluindo o JRuby), dessa forma não precisamos replicar a instalação das gems nas outras versões e tudo fica muito bem, porém na prática a teoria é outra. Tivemos alguns problemas relacionados a gem PG. Em algumas máquinas o ruby ficava confuso sobre usar a versão jdbc ou a nativa da gem, mesmo configurado para usar uma ou outra. O erro era o seguinte:
NameError: uninitialized constant ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::PGconn
Para resolver esse problema tivemos que comentar a variável de ambiente GEM_HOME e instalar a versão java com o jgem, mantendo então as gems nativas do JRuby em seu próprio diretório de gems.
Prometemos um post sobre o liferay_models, mas ainda não será dessa vez. Nós criamos o projeto no github com algumas classes básicas, mas boa parte dele ainda está presa ao nosso projeto, isso deverá ser resolvido nas próximas semanas. Mas para não passar em branco, podemos adiantar algumas coisas sobre o projeto, como por exemplo as dependências da classe user_ do liferay, representada na imagem abaixo:
No liferay, por mais simples que um usuário seja, ele necessita de todas as dependências apresentadas, mais algumas que ainda não foram adicionadas. É nesse cenário que o liferay_models entra em ação, abstraindo as tabelas e os comportamentos das entidades, o que torna mais fácil a integração de um portlet escrito em Rails com o portlet container.
O fato de não utilizar o ambiente de extensão e desenvolvimento do portal implica em alguns problemas, como por exemplo, a integração com o apache lucene. Este framework é responsável por realizar a indexação de todo o conteúdo do portal, agilizando as consultas e melhorando a performance. Como o liferay_models trabalha diretamente com o banco de dados, sem passar pelas apis do portal, o conteúdo persistido por ele não é indexado pelo lucene, acarretando em alguns problemas como a ausência deste conteúdo nas pesquisas feitas nos serviços do portal. Estamos trabalhando nesse problema utilizando o jruby-lucene, que é uma api para manipular o lucene em ruby. Uma outra solução seria utilizar o solr, mas isso também fica para um próximo post.
Falamos também do projeto rails-portlet que é uma ponte entre o projeto rails e o portlet container. Durante o desenvolvimento nós tivemos a necessidade de realizar upload de arquivos, e descobrimos de uma forma pouco agradável que o projeto não o suportava. Dessa forma começamos a saga da adição deste suporte a forms multipart ao rails-portlet, e como já era esperado, tivemos problemas.
1 - Apache fileupload vs Liferay
Round 1:
Tentamos utilizar o projeto fileupload da apache para receber os arquivos no lado servidor, mas tivemos a infelicidade de descobrir que o liferay eliminava (o.O) esses parâmetros antes da execução do rails-portlet, o que inviabilizava o uso do projeto da apache.
Round 2:
Utilizamos uma api do próprio portal para recuperar os arquivos, mas eles eram apagados antes do rails-portlet chamar o projeto em rails.
Round 3:
Já que os arquivos eram apagados, decidimos armazená-los na sessão durante a montagem da requisição para a aplicação rails, resolvendo o problema.
2 - Rack vs request multipart
Round 1:
Uma vez resolvido os problemas com o liferay, foi a vez do Rack atrapalhar, tratando os parâmetros do tipo string também como arquivo.
Basicamente o que acontecia era o seguinte:
O servidor recebia isso:
Parameters: {
"pessoa_fisica"=>{
"cpf"=>#<File:/tmp/RackMultipart4952-35>,
"foto"=>#<File:/tmp/RackMultipart4952-37>
}
}
Ao invés disso:
Parameters: {
"pessoa_fisica"=>{
"cpf"=>"123.456.789-00",
"foto"=>#<File:/tmp/RackMultipart4952-37>
}
}
O campo cpf, que era um textfield, virava um arquivo ao invés de simplesmente uma string.
Round 2:
Para resolver esse problema, tivemos que alterar novamente o rails-portlet, definindo o content-type dos campos do tipo string para null, pois o Rack na versão atual (1.1.0) trata qualquer parâmetro com content-type como binário, gerando o resultado apresentado acima.
Apesar dos problemas, conseguimos adicionar o suporte. Já temos no backlog uma lista de melhorias e novas funcionalidades, mas isso continua no próximo episódio.
Equipe CFA.
Desenvolvimento de portlets com Rails 3
No final do ano passado fechamos um contrato com o Conselho Federal de Administração (CFA) para o desenvolvimento do cadastro integrado de administradores do Brasil dentre outras funcionalidades. Além da implementação, o CFA também tinha a necessidade de uma ferramenta capaz de prover recursos de CMS, comunidades, fóruns, etc. Tendo em vista esse cenário ficou decidido que o Liferay iria ser a ferramenta de portal utilizada enquanto o desenvolvimento dos portlets seria feito em Ruby/Rails.
Como seria possível desenvolver um portlet Ruby em uma plataforma Java? o.O? Utilizando JRuby é claro! Dentre os projetos que viabilizavam uso do Ruby/Rails em portlets java, o rails-portlet foi o que apresentou a melhor proposta. E como ele funciona?
- 1 portlet java
- O projeto feito com o Rails empacotado com a gem warble, rodando com o JRuby
- Comunicação HTTP entre o portlet e o projeto Rails
- Rails inacessível sem o portlet
O portlet java, que é provido pelo projeto rails-portlet, é adicionado ao portlet container e irá conversar com a aplicação feita em Ruby, isso facilita muito o trabalho, pois conseguimos desenvolver tudo em Ruby e com alguns comandos geramos o .war do portlet.
O projeto feito com o Rails tem algumas particularidades, a mais proeminente é o mapeamento das rotas, pois no projeto original cada método de controller gerava um novo portlet, um mapeamento fixo, por exemplo:
map.portlet_exemplo(
‘portlet_exemplo’, :controller => :controller_1, :action => :method_1
)
Com as contribuições que nossa equipe fez ao projeto, nós conseguimos criar rotas que abrangem N controllers, o que melhorou bastante o processo de reaproveitamento de código, exemplo:
map.portlet_exemplo(
‘portlet_exemplo/:controller/:action’, :controller => :controller_1
)
Nessa caso, utilizamos um namespace ‘portlet_exemplo’ para definir o portlet e definimos que o controller padrão será o :controller_1 e o método padrão será o :index, que no caso, não precisa ser informado. Os wildcards :controller e :action serão substituídos pelos valores passados por parâmetro na URL, por exemplo:
http://…/portlet_exemplo
controller_1, método index
http://…/portlet_exemplo/meu_controller
meu_controller, método index
http://…/portlet_exemplo/outro_controller/outro_metodo
outro_controller, método outro_metodo
Outra necessidade é a utilização da gem caterpillar que é a responsável por gerar automaticamente os xmls de configuração do portlet e do liferay, além de empacotar utilizando o warbler e realizar o deploy. Essa gem tem como dependência a gem lportal, que contém as tabelas do liferay na forma de modelos do ActiveRecord. Infelizmente o lportal não atendeu as nossas necessidades pois ele apresentou algumas problemas básicos, talvez por inatividade do projeto. Dessa forma nós criamos o projeto liferay_models, que ainda não está público, e que é assunto para um outro post.
Após o panorama geral, vejamos como criar um portlet em Rails.
1) Instalar e configurar o GEM
criar variável de ambiente $GEM_HOME=/caminho/das/gems/sem/a/pasta/gems
* Atenção: O caminho das gems não inclui a pasta gems.
Por exemplo:
export GEM_HOME=/usr/lib/ruby/gems/1.8
1) Instalar e configurar o JRuby
download
http://jruby.kenai.com/downloads/1.4.0/jruby-bin-1.4.0.zip
criar variável $JRUBY_HOME=/… e adicionar no path $JRUBY_HOME:$JRUBY_HOME/bin
1.5)
apt-get install ruby-dev
Ubuntu:
apt-get install libpqxx3-dev
Debian:
apt-get install libpq-dev libpgsql-ruby
2) Instalar gems
gem install jruby-openssl
gem install jruby-jars
gem install hpricot
gem install warbler
gem install caterpillar
gem install lportal
gem install uuidtools
gem install rails -v=2.3.3 (Até o momento o caterpillar só funciona com essa versão do rails, estamos trabalhando nisso)
* no caso de utilizar postgres
gem install pg
gem install activerecord-jdbcpostgresql-adapter
3) Criar projeto
rails nome-projeto
cd nome-projeto
ruby script/generate controller example index
- Configure a rota
map.example(‘example/index’, {:controller => ‘example’, :action => ‘index’})
- Adicionar as dependências das gems no config/environment.rb
config.gem "caterpillar"
config.gem "lportal"
- Configurar config/database.yml
development:
adapter: postgresql
database: lportal
username: postgres
password: postgres
host: 127.0.0.1
timeout: 5000
production:
adapter: jdbcpostgresql
database: lportal
username: postgres
password: postgres
host: 127.0.0.1
encoding: unicode
- Ativar caterpillar
ruby script/generate caterpillar
- No arquivo config/portlets.rb adicione
portlet.container.root = ‘/../Programas/liferay-portal-5.2.3/tomcat-6.0.18/’
portlet.category = ‘Rails-apps’ (ou um nome que você preferir)
- Deploy
* Teste a conexao com:
caterpillar portlets
- Gerar o arquivo warble.rb
warble config
- Adicionar essa configuração no warble.rb
config.gems << "activerecord-jdbcpostgresql-adapter"
config.gems << "lportal"
# Precisa fazer apenas uma vez
caterpillar jar:install (Coloca o portlet genérico que trata as requisições no liferay)
# Sempre que mudar alguma configuracao e for testar a aplicação no liferay
caterpillar xml
caterpillar warble (nesse momento não pode ter nenhuma gem nativa no environment.rb, exemplo pg)
# Utilizado para atualizar os arquivos no container
caterpillar deploy:xml
caterpillar deploy:war
Após realizar os passos acima, inicie o Liferay e acesse a aplicação. Selecione o portlet rails que se encontra na categoria que foi configurada. Pronto, nós temos nosso portlet rails rodando!
Esse foi o primeiro de uma série de posts sobre o assunto. Fiquem no aguardo.
Equipe CFA:
Túlio Ornelas, Pedro Dias, Bruce Rodrigues e Renan Mendes.
Portlets JSP 2
Como presente de Natal, fiquem com o 4º capítulo do nosso minicurso de Liferay.
Customizando o Liferay 1
segue mais um capítulo do minicurso online de Liferay que estamos fazendo aqui no blog. Os primeiros capítulos estão disponíveis em http://tinyurl.com/LiferayNaSEA
Nesta edição, discutimos conceitos básicos para customização do portal. Não entramos ainda no nível de código, mas chegaremos lá. Baby stetps, baby. Baby steps…
Mini-curso online de Liferay 4
O conteúdo em si não foi muito profundo mas, de tão positivo que foi o feedback da turma, acabei resolvendo gastar um pouco mais de esforço para deixá-lo para prosperidade. O resultado foi uma sequência de slidecasts que hoje começo a disponibilizar.
Nesta primeira leva, teremos 2 apresentações. Ambas são bem introdutórias, mas essenciais para tratar com quem nunca ouviu falar no assunto. Nos próximos episódios, falarei um pouco mais de desenvolvimento de portlets, não apenas em Java, como também em outras tecnologias, como Ruby e PHP.
Foi minha primeira experiência na gravação de *casts. O resultado não ficou 100%, mas já quebra o galho. O importante é a melhoria contínua.
Feedbacks, como sempre, são mais que bem-vindos.
[]s
LinguÁgil 2009 1
A proliferação de tecnologias para o
desenvolvimento de aplicações web vem gerando
exaustivas discussões sobre qual adotá-las em
seus projetos. Java, PHP e Ruby estão entre as 10 linguagens
de programação mais utilizadas no mundo, segundo
a TIOBE Programming Community. Em paralelo, os mesmos profissionais
buscam melhorar seus serviços adotando metodologias que ao
mesmo tempo permitam o controle de seus projetos, gerem valor agregado
aos clientes e evitem excesso de burocracia.
Diante desse cenário, os grupos AgileBahia, JavaBahia,
PHPBahia e RailsBahia realizarão em Salvador a
edição 2009 do LinguÁgil - Misturando
Linguagens e Agilidade, parte da XII Semana de Informática
da Unime. Inédito na Bahia, o evento reune algumas das
principais comunidades de TI, buscando estimular aprendizado e
discussões em torno de linguagens de
programação e metodologias ágeis.
Local:
Unime - Lauro de Freitas - Bahia
Palestrantes/instrutores
Alberto “Spock” Lemos
(Globalcode), Alexandre Gomes (SEA Tecnologia), Dairton Bassi
(Neurobox), Daniel Lopes (Área
Criações), Felipe Ribeiro (UFCG), Felipe
Rodrigues (Fratech), Henrique Landim (Partner Process) e outros
Palestras
GRATUITAS (14/11)
Agile, Manifesto 2.0, Ruby On
Rails, PHP/Frameworks, JSF 2.0/Scrum Toys, Linguagens para a JVM,
Pentaho
Oficinas/Coding-Dojo
(12 e 13/11)
Coding-Dojo Agile, Java/Web com Demoiselle,
Integração Contínua/Maven (a
confirmar), Python (a confirmar)
Mini-cursos
(R$ 60 a R$
120)
12/11 - Métodos Ágeis, JSF, Portlets com Liferay,
TDD/Java, Ruby
13/11 - XP, Scrum, Pentaho, PHP/TDD, Rails
Inscrições:
Com desconto até 05/11
Preços promocionais para estudantes e membros do AgileBahia
/ JavaBahia / PHPBahia / RailsBahia
Programação detalhada,
inscrições e mais
informações em www.linguagil.com.br



