8
12 : : www.mundoj.com.br : : O desenvolvimento em nuvem carrega diversos detalhes e configurações de aplicações tanto para otimizações quanto para o simples envio para a estrutura em nuvem. Aqui abordaremos como desenvolver aplicações para a estrutura Google e como gerenciar nossas aplicações. Luiz Felipe Gomes Teixera É desenvolvedor Java na IPNET Soluções com ênfase em aplicações em cloud computing, é graduando em Análise e Desenvolvimento de Sistemas no Instituto Infnet. Possui 4 anos de experiência em programação e é otimista sobre o desenvolvimento em nuvem. Possui as certificações SCJA, SCJP. Google App Engine GWT Uma introdução ao com Desenvolvendo Java em Cloud Computing.

Desenvolvendo Java em Cloud Computing. · public void doGet (HttpServletRequest req, HttpServletResponse resp) throws IOException resp ... varredura no mesmo como o tratamento que

Embed Size (px)

Citation preview

Page 1: Desenvolvendo Java em Cloud Computing. · public void doGet (HttpServletRequest req, HttpServletResponse resp) throws IOException resp ... varredura no mesmo como o tratamento que

12

: : www.mundoj.com.br : :

O desenvolvimento em nuvem carrega diversos detalhes e configurações de aplicações tanto para otimizações quanto para o simples envio para a estrutura em nuvem. Aqui abordaremos como desenvolver aplicações para a estrutura Google e como gerenciar nossas aplicações.

Luiz Felipe Gomes Teixera É desenvolvedor Java na IPNET Soluções com ênfase em aplicações em cloud computing, é graduando em Análise e Desenvolvimento de Sistemas no Instituto Infnet. Possui 4 anos de experiência em programação e é otimista sobre o desenvolvimento em nuvem. Possui as certificações SCJA, SCJP.

Google App Engine GWTUma introdução ao

comDesenvolvendo Java em Cloud Computing.

Page 2: Desenvolvendo Java em Cloud Computing. · public void doGet (HttpServletRequest req, HttpServletResponse resp) throws IOException resp ... varredura no mesmo como o tratamento que

13

desenvolvimento de aplicações em Java mais elabora-das e com mais recursos estão nos obrigando cada vez mais a escalar nossos servidores de aplicações, o que

nos leva muitas vezes a ter que realizar outras configurações na nossa infraestrutura. Contudo o mercado para se adequar a estas necessidades começou a utilizar o conceito de Cloud Computing, que hoje já tem o seu espaço e está se desenvolvendo cada vez mais. As principais e mais conhecidas empresas que disponibili-zam esse tipo de plataforma para desenvolvimento são a Google e a Amazon, que além de disponibilizar um servidor de aplicação completo e escalado também fornece um banco de dados em for-mato NoSQL para persistência de dados.

Ferramenta Google App Engine (GAE)

O Google, por sua grande expansão mundial, foi um dos primeiros a implantar uma plataforma em cloud aberta para desenvolvimento de aplicativos integrados à plataforma. Atualmente, essa infraestru-tura possibilita a utilização da linguagem Java ou python.

Para o desenvolvimento Web a plataforma GAE disponibiliza também um endereço de hospedagem da sua aplicação. Onde a url para acesso segue da seguinte forma: <suaaplicação>.appspot.com. O ambiente de execução em Java do GAE permite que você crie seu aplicativo usando tecnologias Java convencionais. Qual-quer outra linguagem que use um interpretador ou compilador com base na JVM, como javaScript ou Ruby, também pode ser integrado à plataforma.

Para Saber Mais

Para criar uma conta no GAE, você deve acessar o link , e possuir uma conta de

e-mail do Gmail para se registrar. Após o registro você poderá criar até 10 aplicações na sua conta.

Após a criação de uma conta, deve-se utilizar o Googlipse para criar suas aplicações, que é um plugin que se integra ao eclipse para facilitar a criação de aplicativos para a plataforma GAE. A ferramenta utilizada para auxílio ao desenvolvimento com GWT é o GWT Designer, que é um plugin do eclipse adicional, que permite ao desenvolvedor criar interfaces ricas em modo visual, o que facilita a criação de interfaces de acesso de aplicativos e eventos. Pode ser obtido em: http://code.google.com/webtoolkit/tools/gwtdesigner/installation/index.

Existem abstrações para o framework GWT. A mais co-nhecida e utilizada no mercado é o Vaadin que pode ser encontrado em http://vaadin.com, o mesmo já possui vários objetos com a integração do GWT e alguns adicio-nais que completam a formação de uma interface rica com todos os recursos visuais utilizados geralmente com ajax e javascript.

Googlipse é o plugin criado pela Google para facilitar o desenvol-vimento de aplicações com as definições solicitadas pela platafor-ma GAE para hospedar uma aplicação. O plugin está disponível para diversas versões do Eclipse e pode ser obtido em http://code.google.com/appengine/downloads.html.

Após realizar a instalação, você possuirá integrado ao seu eclipse o Jetty (servidor de aplicação), ferramentas para testes unitários (Junit) e uma SDK que compõe o desenvolvimento para Cloud Computing utilizando GAE.

Para criar a primeira aplicação, selecione New > Project > Google > Web Apllication Project. Após avançar, selecione o nome do projeto e pacote e desative a opção Use Google Web Toolkit, que nesse primeiro momento não será abordado. Após isso, um novo projeto será adicionado ao eclipse já com um servlet criado e ma-peado como é apresentado na figura 1.

Figura 1. Novo projeto utilizando o plugin Googlipse.

Page 3: Desenvolvendo Java em Cloud Computing. · public void doGet (HttpServletRequest req, HttpServletResponse resp) throws IOException resp ... varredura no mesmo como o tratamento que

14

: : www.mundoj.com.br : :

A estrutura do projeto é a seguinte:

Alias para seus pacotes com suas Classes Java, Servlets etc.

configurações XML para persistência

SDK para o desenvolvimento em cloud

Java Runtime

pasta direcionada ao acesso a sua aplicação (antigo Web-Content)

contém a pasta lib para agregar drivers e frameworks no seu projeto além dos arquivos appengine-web.xml, logging.properties e web.xml.

O arquivo contido em META-INF com o título de jdoconfig.xml possui as configurações para tratamento de persistência em cloud utilizando JDO com BigTable que é uma base NoSQL.

A princípio, a aplicação Hello Word já está criada e você pode realizar o teste da mesma com o servidor de aplicação integrado. Selecione a pasta do projeto e selecione Run Web Application.

Seu servidor de aplicação irá iniciar e será informado em seu console que o servidor já está rodando na porta 8888, no en-dereço local de sua máquina, acesse para realizar o teste http://localhost:8888.

Persistência - O que é GQL?

A hospedagem GAE foi desenvolvida para utilizar sua aplicação 100% em cloud. Logo a preferência é que você utilize a persis-tência de dados também na mesma infra que a disponibilidade da aplicação. Para isso é disposto para todas as contas registradas um banco NoSQL para qualquer aplicação que você crie.

A ferramenta SDC (Security data Connector) permite que você acesse seus dados hospedados em um servidor local para o trata-mento em cloud, mas essa ferramenta-formato não será abordado neste artigo.

Como persistir em Nuvem?

Existem algumas especificações para o desenvolvimento em nu-vem integrado na sua aplicação. A plataforma GAE disponibiliza preferencialmente dois: JDO e JPA.

Estes podem ser verificados aqui http://code.google.com/appengi-ne/docs/java/datastore/jdo/ e http://code.google.com/appengine/docs/java/datastore/jpa/. Um conceito diferente do armazenamen-to que é realizado num banco local é a necessidade de criação de uma entidade para ser persistida no banco, além de registrada anteriormente. Caso esteja acostumado a criar aplicativos mode-lando a estrutura do banco de dados primeiro (ou seja, imaginar

tabelas e seus relacionamentos primeiro), então a modelagem de dados com um armazenamento de dados sem esquemas, como o Bigtable, necessitará que você repense na maneira como faz as coi-sas. No entanto, caso você crie seus aplicativos começando com um modelo de domínio, então você irá perceber que a estrutura sem usar esquemas do Bigtable é mais natural.

Muitos frameworks de persistência, como Hibernate, realizam a criação das entidades para serem persistentes em um banco de dados e opcionalmente, caso seja necessário, é possível utilizar um armazenamento direto com a api jdbc. O que já não é possível utilizando GAE. Todo dado a ser persistido deve ter sua classe persistente registrada na aplicação para que a persistência seja utilizada.

Iremos utilizar neste artigo a API Objectify que não é desenvolvida diretamente pela Google, mas é validada para todos os serviços em GAE e por possuir um tratamento mais amigável é a mais co-tada entre os desenvolvedores. Dentre essas apis também pode ser utilizada a API do datastore que utiliza um tratamento de baixo nível para realização do tratamento de banco de dados.

Para a documentação e download da api Objectify, acesse http://code.google.com/p/objectify-appengine/. Após realizar o downlo-ad da mesma, adicione ao buid-path do seu projeto.

Para deixar uma classe persistente é necessário implementar a interface serializable e direcionar um atributo da classe para ser o id no banco preferencialmente como Long ou int. Os gets e Sets não precisam ser padrões para esta utilidade. O import da anotação Entity deve ser realizado diretamente da api objectify (Listagem 1).

Listagem 1. Implementação da classe para persistência.

import java.io.Serializable;

import javax.persistence.Id;

import com.googlecode.objectify.annotation.Entity;

@Entity

public class Cadastro implements Serializable {

@Id Long id;

private String nome;

private String email;

private String senha;

//gets e sets

}

Com esse formato, a classe Cadastro já pode ser persistida no DataStore disponibilizado para a aplicação. Para realizar o efetivo cadastro de um determinado usuário, é necessário realizar o regis-tro da classe que realiza a criação da entidade no banco de dados como é apresentado na Listagem 3.

Page 4: Desenvolvendo Java em Cloud Computing. · public void doGet (HttpServletRequest req, HttpServletResponse resp) throws IOException resp ... varredura no mesmo como o tratamento que

15

Listagem 2. Interface para cadastro. Listagem 3. Servlet para cadastro.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>Cadastro</title> </head>

<body> <h1>Cadastro</h1> <form action="mundojava"> Nome : <input type="text" name="nome"> Email : <input type="text" name="email"> Senha : <input type="text" name="senha"> <br/> <input type="submit"> </form> <table> <tr> <td><a href="mundojava">MundoJava</a></td> </tr> </table> </body></html>

package com.mundojava;

import java.io.IOException;

import javax.servlet.http.*;

import com.googlecode.objectify.Objectify;

import com.googlecode.objectify.ObjectifyService;

import com.model.Cadastro;

public class MundoJavaServlet extends HttpServlet {

public void doGet(HttpServletRequest req, HttpServletResponse resp)

throws IOException {

resp.setContentType(“text/html”);

String nome = req.getParameter(“nome”);

String email = req.getParameter(“email”);

String senha = req.getParameter(“senha”);

Cadastro novoCadastro = new Cadastro();

novoCadastro.setNome(nome);

novoCadastro.setEmail(email);

novoCadastro.setSenha(senha);

//registro de classe no banco DataStore

ObjectifyService.register(Cadastro.class);

//inicia o servico de persistencia

Objectify ofy = ObjectifyService.begin();

//Faz a inserção no Banco de dados

ofy.put(novoCadastro);

}

}

Agora, iremos subir nossa aplicação para nosso servidor em cloud. Para realizar isso, iremos selecionar com o botão direito o diretó-rio da aplicação e ir à opção Google > deploy to app engine. Após selecionar essa opção, é necessário configurar sua aplicação para seu e-mail autenticado no GAE juntamente com o id da aplicação. A aplicação deve ser criada anteriormente a ser disponibilizada no GAE, pois o id da mesma é utilizado quando realizamos o deploy da mesma (figura 2).

Figura 2. Configurando o deploy para Cloud Computing no GAE.

Page 5: Desenvolvendo Java em Cloud Computing. · public void doGet (HttpServletRequest req, HttpServletResponse resp) throws IOException resp ... varredura no mesmo como o tratamento que

16

: : www.mundoj.com.br : :

Podemos acessar o sistema de cadastro em mundojava.appspot.com para verificar o funcionamento da mesma.

Uma parte interessante do armazenamento no GAE é o painel de administração fornecido para o controle de dados persistidos e inserção de dados usando GQL. Essa interface poder ser acessada no endereço http://appengine.google.com. Após realizar o login,

selecione sua aplicação e após isso selecione o item Data Viewer.

Após verificar que os dados foram criados como visto na figura 3, podemos realizar filtros de busca a partir da aplicação, o tratamen-to de do select tratado pela api objectify também é diferente do convencional. É utilizada a notação de filtros (Listagem 4).

Figura 3. Administração do banco de dados No-SQL.

Figura 3. Administração do banco de dados No-SQL.

Listagem 4. Select no DataStore do GAE.

//o método filter é responsavél por fazer as querys de busca

//o primeiro parametro é o nome do atributo da entidade

//o filtro retorna um array list

//registro de classe no banco DataStore

ObjectifyService.register(Cadastro.class);

//inicia o servico de persistencia

Objectify ofy = ObjectifyService.begin();

Query<Cadastro> q = ofy.query(Cadastro.class).filter(“nome”,”joao”);

ArrayList<Cadastro> findCadastro = new ArrayList<Cadastro>();

for (Cadastro cadastro : q) {

findCadastro.add(cadastro);

}

A busca retorna um Array com todas as informações encontradas referente àquela busca realizada e esse fator torna necessária a varredura no mesmo como o tratamento que é realizado em um ResultSet convencional.

GWT – Poderoso e fácil de usar

O Gwt é uma ótima ferramenta para criar web applications de uma forma elegante e prática. A formatação do Gwt já foi elaborada em foco com a utilização da plataforma GAE, pois a padronização da estrutura do projeto facilita escalar a aplicação desenvolvida. Esse framework aos poucos está ganhando seu espaço por sua facilidade de uso e padronização de estruturas de projetos, sendo uma alternativa ao JSF para o desenvolvimento orientado a com-ponentes.

Para utilizar o framework, selecione um novo projeto Google e, após isso, marque o checkBox referente ao uso do Google Web Toolkit no seu projeto. A estrutura a ser criada é um pouco di-ferente da convencional, figura 4, verificada nos projetos Web. Como carro-chefe, o GWT utiliza o protocolo RPC para qualquer tipo de chamada ao servidor que trata de forma mais elegante as requisições realizadas na camada Servidor.

A estrutura do GWT possui uma formatação que divide o seu projeto em:

Page 6: Desenvolvendo Java em Cloud Computing. · public void doGet (HttpServletRequest req, HttpServletResponse resp) throws IOException resp ... varredura no mesmo como o tratamento que

17

Cliente: todas as classes que ficam disponíveis para o cliente (Viewer).

Servidor: todas as classes que são usadas como servidor ou que realizam acesso a um.

Shared: todas as classes compartilhadas no seu projeto, como, por exemplo, uma validação de campos UI.

<Projeto>.gwt.xml: possui as configurações do módulo que está sendo desenvolvido.

Teste: pacote que armazena suas classes de teste.

Figura 4. Estrutura GWT.

Crie um novo projeto, selecione New Project > WindowBuider > GWTDesigner. É interessante após clicar em avançar selecionar o modelo ImageViewer que já apresenta um modelo de projeto desenvolvido com GWT + GWTDesigner como apresentado na figura 5.

Figura 5. GWTDesigner módulo de exemplo.

Figura 6. GWT designer.

Após a criação desse módulo, para que seja utilizado o plugin do GWT designer (figura 6), é necessário selecionar a classe que contém a camada visual e utilizar a aba Design que fica disposta nas abas auxiliares. Caso o mesmo ainda não esteja disponível, na camada de visualização selecione a opção Open with Window-Builder Editor, que a opção para designer ficará disponível.

Para que seja criado o acesso ao servidor, selecione no seu pacote do projeto a opção Google Web Toolkit e new GWT remote ser-vice. Essa opção irá criar uma estrutura RPC simples para fazer a comunicação com o servidor.

Para que a API Objectify seja utilizada é necessário que esta seja declarada no .xml que guarda as configurações do módulo como mostra a Listagem 5.

Page 7: Desenvolvendo Java em Cloud Computing. · public void doGet (HttpServletRequest req, HttpServletResponse resp) throws IOException resp ... varredura no mesmo como o tratamento que

18

: : www.mundoj.com.br : :

Listagem 5. Módulo GWT com objectify.

Listagem 6. Classe persistente – GWT com objectify.

Listagem 8. Interface de Serviço – GWT com objectify.

Listagem 7. Classe de Visualização – GWT com objectify.

<module> <inherits name=”com.google.gwt.user.User”/> <inherits name=”com.google.gwt.user.theme.standard.Standard”/> <inherits name=”com.googlecode.objectify.Objectify” /> <entry-point class=”com.mycompany.project.client.ImageViewer”/></module>

import javax.persistence.Entity;import javax.persistence.Id;@Entitypublic class Animal implements Serializable { @Id Long id; private String tipo; private String cor; public void setTipo(String tipo) { this.tipo = tipo; } public String getTipo() { return tipo; } public void setCor(String cor) { this.cor= cor; } public String getCor() { return cor; }}

package com.exemplo.myproject.client;

import com.google.gwt.user.client.rpc.RemoteService;

import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

// RemoteServiceRelativePath annotation precisa ser declarada para uso na

configuracao da URL //no servlet

@RemoteServiceRelativePath(“persistentservice”)

public interface PersistentService extends RemoteService {

void persistAnimal(String cor, String tipo) throws IllegalArgumentException;

}

package com.exemplo.myproject.client;

import com.google.gwt.core.client.EntryPoint;

//outros imports ...

public class GWTObjectify implements EntryPoint {

// Criando campos UI

VerticalPanel mainVerticalPanel = new VerticalPanel();

HorizontalPanel hp1 = new HorizontalPanel();

//....

// Instanciando a classe que realiza a chamada assincrona para o servidor

private final PersistentServiceAsync persistentService = GWT

.create(PersistentService.class);

public void onModuleLoad() {

//criando os inputs de texto

hp1.add(corLabel);

hp1.add(corTextBox);

//...

//adicionando à janela principal

mainVerticalPanel.add(hp1);

mainVerticalPanel.add(hp2);

mainVerticalPanel.add(submit);

hp1.setSpacing(5);

hp2.setSpacing(5);

mainVerticalPanel.setSpacing(5);

//Adicionando evento no botão. Quando clicado

//faz a chamada RPC usando o serviço de persistencia.

submit.addClickHandler(new ClickHandler() {

public void onClick(ClickEvent event) {

persistentService.persistAnimal(corTextBox.getText(),

tipoTextBox.getText(), new AsyncCallback<Void>() {

@Override

public void onFailure(Throwable excessao) {

System.out.println(“A chamada falhou “+ excessao);

}

@Override

public void onSuccess(Void result) {

System.out.println(“RPC bem sucedido”);

}

});

}

});

RootPanel.get(“container”).add(mainVerticalPanel);

}

}

Após a adição do inherit se torna possível realizar a persistência dos dados, sendo necessária a criação da classe persistente e rpc que fará a chamada para uma das funções crud no servidor, Lis-tagem 6.

A criação da classe de visualização deve ser auxiliada pelo GWT designer que possui funções para criações de métodos e eventos como é apresentado na Listagem 7.

Toda chamada ao servidor necessita que seja criada uma interface de comunicação síncrona e uma assíncrona que se comunicam antes de realizar o callServer como é apresentado nas Listagens 8 e 9.

Page 8: Desenvolvendo Java em Cloud Computing. · public void doGet (HttpServletRequest req, HttpServletResponse resp) throws IOException resp ... varredura no mesmo como o tratamento que

19

Listagem 9. Interface assíncrona de Serviço – GWT com ob-jectify.

Listagem 10. Classe Servidor – GWT com objectify.

Listagem 11. Web XML – GWT com objectify.

package com.example.myproject.client;

import com.google.gwt.user.client.rpc.AsyncCallback;public interface PersistentServiceAsync { void persistAnimal(String cor, String tipo, AsyncCallback<Void> callback);}

package com.exemplo.myproject.server;

import com.exemplo.myproject.client.PersistentService;import com.exemplo.myproject.client.entities.Animal;import com.google.gwt.user.server.rpc.RemoteServiceServlet;import com.googlecode.objectify.Objectify;import com.googlecode.objectify.ObjectifyService;

@SuppressWarnings(“serial”)public class PersistentServiceImpl extends RemoteServiceServlet implements PersistentService { //Metodo precisa existir na Interface de servico e na Interface Assincrona public void persistAnimal(String cor, String tipo) { //registro da classe animal , na api objectify ObjectifyService.register(Animal.class); Objectify ofy = ObjectifyService.begin(); Animal animal = new Animal(); animal.setCor(cor); animal.setTipo(tipo); //insert com objectify ofy.put(animal); }}

<servlet> <servlet-name>persistenceServlet</servlet-name> <servlet-class>com.exemplo.myproject.server.PersistentServiceImpl </servlet-class></servlet><servlet-mapping> <servlet-name>persistenceServlet</servlet-name> <url-pattern>/gwtobjectify/persistentservice</url-pattern></servlet-mapping>

A classe que fica disposta no pacote server sempre deve possuir o complemento “Impl” mostrado na Listagem 10, que define a implementação do servidor e o framework utiliza essa notação para diferenciar se a classe é Server ou não depois de compilada.

O mapeamento do servlet deve sempre mapear a classe “Impl”, ou seja, apontar para o seu servidor. Que no nosso caso é o acesso ao banco de dados usando a api objectify (Listagem 11).

Após realizada essa configuração, seu projeto já está pronto para ser enviado para o GAE, que recebe o projeto usando GWT da mesma forma que um projeto comum. A velocidade para a criação das camadas UI são bem otimizadas assim como toda a manipulação do banco de dados que por se localizar na mesma infraestrutura e possuir formato No-SQL no facilita quanto a escalabilidade do banco de dados e custos de administração geral.

Considerações finais

Com o preço atual dos servidores e custos gerais que uma empre-sa possui, o desenvolvimento em cloud é uma ótima opção. Além do valor para a uma hospedagem mais completa ser baixo, possuir um banco de dados escalado e sempre funcionando juntamente com a aplicação mostra que desenvolver em cloud é a nova forma de desenvolver que ganha espaço a todo tempo e que futuramente estará aos redores de todo o mercado de trabalho e todo o univer-so de linguagens de programação.

Dentro desta estrutura de desenvolvimento, temos também a se-gurança que nossa aplicação rodará 24 x 7 sem nos preocuparmos diretamente com nossos servidores, resfriamento, custos de har-dware o que deixa a tecnologia mais atrativa para ser utilizada.

Referências

GUJ – Discussões sobre o tema do artigo e assuntos relacionados

Discuta este artigo com 100 mil outros desenvolvedores em www.guj.com.br/MundoJ