Série AngularJS: Aplicação JEE com AngularJS

Olá Pessoal,

No post de hoje vamos ver como persistir os dados que estão no nosso front-end com AngularJS em uma base de dados, mas o nosso back-end é Java usando Spring, Hibernate e Jersey.

Lets go…

Starting…

Vou considerar que você já conhece Spring e Hibernate, portanto o post irá direto ao assunto. Veremos apenas como fazer com que os dados do front-end chegue ao back-end. É necessário que você tenha o Jersey no Controller do lado do Server-side. Fiz um post sobre o AngularJS e Jersey.

Antes de começar

  1. Crie um projeto webapp, de preferência com o maven;
  2. Adicione as dependências do Spring, hibernate, banco de dados, Jersey;
  3. Tenha a lib do angular no projeto ou use a versão online.

O nosso projeto

É muito simples, apenas um formulário que cadastra um customer. Veja o projeto:

angularjcustomerproject

Vou considerar que você já tem a camada de serviço DAO e application-context do Spring devidamente criados e funcionando.

Adicionando Dependência no pom.xm Jersey-Spring

<dependency>

<groupId>com.sun.jersey.contribs</groupId>

<artifactId>jersey-spring</artifactId>

<version>1.8</version>

<exclusions>

<exclusion>

<groupId>org.springframework</groupId>

<artifactId>spring</artifactId>

</exclusion>

<exclusion>

<groupId>org.springframework</groupId>

<artifactId>spring-core</artifactId>

</exclusion>

<exclusion>

<groupId>org.springframework</groupId>

<artifactId>spring-web</artifactId>

</exclusion>

<exclusion>

<groupId>org.springframework</groupId>

<artifactId>spring-beans</artifactId>

</exclusion>

<exclusion>

<groupId>org.springframework</groupId>

<artifactId>spring-context</artifactId>

</exclusion>

</exclusions>

</dependency>

Configurando o Jersey-Spring

No arquivo web.xml deixe assim:

<servlet>

<servlet-name>jersey-servlet</servlet-name>

<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>

<init-param>

<param-name>com.sun.jersey.config.property.packages</param-name>

<!– Aqui é o package onde vai ficar o controller –>

<param-value>com.camilolopes.jersey.services</param-value>

</init-param>

<init-param>

<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>

<param-value>true</param-value>

</init-param>

</servlet>

Crie a classe CustomerController.java conforme a seguir:

@Controller

@Path(“/service”)

public class CustomerController {

@Autowired

@Qualifier(“customerService”)

private CustomerService customerService; //substituir pela sua classe de Service gerenciada pelo Spring

@GET

@Produces(MediaType.APPLICATION_JSON)

public List<Customer> getCustomer() {

List<Customer> list = customerService.getListCustomers();

return list;

}

@POST

@Consumes(MediaType.APPLICATION_JSON)

public void saveCustomer(Customer customer){

customerService.save(customer);

}

public CustomerService getCustomerService() {

return customerService;

}

public void setCustomerService(CustomerService customerService) {

this.customerService = customerService;

}

}

 

Se você viu o nosso post com Jersey e conhece WebService já sabe o que significa essa classe.  Em poucas palavras, é através dessa classe que o front-end e o back-end se comunicam através de um objeto JSON. Então quando o angular precisa enviar algo para o back-end ele vai precisar chamar algum serviço disponível nessa classe, e temos apenas dois: um GET e outro POST.

Criando o app.js

 

       $app = angular.module(‘app’,[‘ngResource’]);

$app.config(function($routeProvider,$httpProvider,$locationProvider){

//routes

$routeProvider.

when(‘/’,{templateUrl:’view/customers.html’,controller:customerController}).

when(‘/create’,{templateUrl:’view/form.html’,controller:customerController}).

when(‘/list’,{templateUrl:’view/customers.html’,controller:customerController}).

otherwise(

{

redirectTo:’/’

});

$httpProvider.responseInterceptors.push(function($q,$rootScope){

return function(promise){

return promise.then(function(response){

return (response);

},function(response){

$data = response.data;

$error = $data.error;

if($error && $error.text){

console.log(“ERROR: ” + $error.text);

}

else{

if(response.status=404)

console.log(“page not found”);

}

return $q.reject(response);

});

};

});

});

Esse código acima apenas cria rotas com base no que for chamado no browser. Por exemplo, se chamarmos /create vai ser carregado a página form.html e o controller  customerController que ainda vamos criar.

A outra função é, em caso de erro no response, podermos exibir um conteúdo customizado. A novidade que temos nesse arquivo é:

$app = angular.module(‘app’,[‘ngResource’]);

Lembra que nos posts anteriores passávamos [] para o segundo parâmetro do module? Agora estamos dizendo que vamos usar ng-resource para conectar a um WebService.  Adicione ao seu projeto angular-resource.js  ou use a versão online:

<script src=“http://code.angularjs.org/1.0.6/angular-resource.min.js”></script>

Criando customerController.js

Vamos agora criar o controller do angular, portanto crie um arquivo JavaScript chamado customerController.js. Não vamos organizar o projeto, pode colocar dentro de webapp mesmo:

function customerController($scope,$resource,$location){

//estamos criando um objeto e linkando com o webservice CustomerController.java

Customer = $resource(“rest/service/”);

//estamos criando uma função que carrega todos os customers.

$scope.loadAll = function(){

Customer.query(

function(data){

$scope.rows = data;

});

};

//quando chamado cria um novo customer e salva.

       $scope.newOne = function() {

var c = new Customer();

//estou atribuindo o nome digitado ao atributo do domain Customer.

c.name = $scope.nameCustomer;

c.$save();

};

}

No inicio parece estranho, mas é porque é diferente do que estamos acostumados. Coloquei a explicação em modo de comentário inline para facilitar o entendimento. Não se preocupe se no inicio se sentir desconfortável com a estrutura, também me senti, mas com o tempo fui aprendendo melhor e vendo que faz sentindo a forma que o angular trata o binding.

Criando o arquivo index.html

Vamos carregar as libs, então esse arquivo terá libs e a ng-view:

 

<html ng-app=“app”>

<head>

<meta charset=“UTF-8”>

<script src=“http://code.angularjs.org/1.0.6/angular.min.js”></script>

<script src=“app.js”></script>

<script src=“customerController.js”></script>

</head>

<body>

<a href=“#/create”>Create</a>

<a href=“#/list”>List</a>

<script src=“http://code.angularjs.org/1.0.6/angular-resource.min.js”></script>

<div ng-view></div>

</body>

</html>

Criando o form.html

<body ng-controller=“customerController”>

<h2>Register Customer</h2>

<form  name=“customerform”>

<div>

<label>Name</label>

<input name=“name” ng-model=“nameCustomer” require/> {{nameCustomer}}

</div>

<div>

<label>Phone</label>

<input name=“phone” ng-model=“phoneCustomer” /> {{phoneCustomer}}

</div>

<div>

<label>E-mail</label>

<input name=“email” ng-model=“emailCustomer” type=“email” required /> {{emailCustomer}}

</div>

<div>

<input type=“button” value=“Save” ng-click=“newOne()” ng-disabled=“customerform.$invalid”/>

</div>

</form>

</body>

 

 Criando customers.html

Aqui vamos listar os customers cadastrados

<div ng-init=“loadAll()”>

<table id=“tableData”>

<thead>

<tr>

<th>ID</th>

<td>Nome</td>

</tr>

</thead>

<tbody>

<tr ng-repeat=“row in rows”>

<td>{{row.id}}</td>

<td>{{row.name}}</td>

</tr>

</tbody>

</table>

</div>

 

Observe que temos ng-init. Essa diretiva invoca o método que carrega todos os customers.

Em seguida temos a diretiva ng-repeat que funciona como um forEach do Java rows; é a variável que criamos no customerController.js

Testando

Assumindo que seu BD está up, suba a aplicação (caso tenha criado um maven Project, apenas digite mvn tomcat:run via linha de comando):

angularjscustomerrunning

Clique no link Create

angularjscustomercreate

Observe a url e o botão save. A url tem alguma relação com as rotas que criamos? E o botão save, por que está desabilitado?

Ele está desabilitado porque fizemos isso no form.html:

<input type=“button” value=“Save” ng-click=“newOne()” ng-disabled=“customerform.$invalid”/>

Olhe para a diretiva ng-disabled. Ali estamos dizendo que se o formulário for invalid desabilite o botão. E o que é um formulário inválido? Nesse caso, se os campos que marcamos como required não estiverem preenchidos, é um form inválido. Observe que quando preencher os campos requeridos, automaticamente o botão fica habilitado:

angularjscustomerformvalid

Clique em save. Se clicar mais de uma vez acontece isso:

angularjscustomerlist

Click no link List

Poderiamos redirencionar usando $location.path(“nomeDaRota”);

Apesar de termos vários outros atributos no form, salvamos apenas o name. Mas sinta-se a vontade em praticar e salvar os demais.  Conferindo no banco:

angularjscustomerbd

Pronto. Salvando dados no BD com AngularJS, Spring, Jersey, Hibernate. Simples, não?

O projeto completo está no meu GitHub no repositório dedicado às minhas brincadeiras com angularJS: https://github.com/camilolopes/workspaceAngularJs

Sempre estarei subindo projetos novos, brincando com o framework… Se quiser acompanhar basta me seguir no github.

Enfim, espero que tenham gostado do post.

Abraços, see ya!! 

Série CI:Build Automatizado com Jenkins e GitHub

Olá Pessoal,

No último post vimos como conectar o Jenkins com o GitHub. Hoje veremos como automatizar o nosso build, ou seja, se alguma mudança ocorreu no repositório, um novo build é iniciado.

Lets go…

Starting…

Considerando que você tem o cenário do post anterior conforme a imagem a seguir:

 

cijenkinscenario

Clique no projeto MyBookStore e vá em configure.

Em build trigger deixe assim:

buildtriggerjenkins

O que fizemos?

Simples, estamos dizendo que a cada mudança no github vamos precisar rodar um novo build, porém, como estamos rodando localmente o jenkins, não tem como o Github informar ao Jenkins que algo mudou, então faremos o Jenkins verificar a cada 1min se algo mudou no Github. Essa é a forma que temos de fazer isso quando não temos o jenkins em um IP Público.

Feito isso, vá em manage jenkins >> configure system

E em GitHub Web Hook deixamos assim:

githubwebhook

Após inserir seus dados do github e a url do repositório, clique em test credential.

Agora vamos testar e ver se o build vai iniciar automaticamente. Mas antes veremos como estamos:

 

historybookstorebuild

No meu caso tenho o histórico de build acima. É esperado que se algo for alterado no repositório uma nova build seja iniciada, claro que não será de imediato, mas sim cada 1 min.

Vá no seu GitHub e acesse o projeto:

mybookstoregithubjenkins

Aperte a tecla T e você poderá realizar uma pesquisa no GitHub. Procure por store e escolha StoreMatrix.java 

storematrixgithub

É a classe que vamos realizar a alteração e aguardar o Jenkins build. Ao selecionar a classe, clique no botão Edit e adicione o atributo address.

addressaddedstorematrix

Clique no botão commit changes .

Vamos aguardar por 1 min e ver se o jenkins inicia o build. O resultado é como a seguir:

buildqueuejenkinsbookstore

Pronto! Temos agora nosso build automatizado conectado ao jenkins. Simples, não?

Vou ficando por aqui e espero que tenham gostado do post.

Abraços, see ya!!

Série CI: Conectando Jenkins com GitHub

Olá Pessoal,

No post de hoje vamos ver como buildar nossos projetos no jenkins e mantê-lo conectado a um repositório. No nosso caso escolhemos o github por usar o Git. Claro que poderia ser um outro repositório, até mesmo local, mas o Github é o mais popular repositório Git.

Lets go…

Starting

Antes de mais nada vou considerar que você já conhece um pouco de Git e GitHub, pois não entrarei em detalhes de como cada um funciona, para isso  você precisa ter:

– Um repositório criado no GiHub;

– Git na sua máquina local

Os nossos steps

Basicamente criaremos um projeto e em seguida faremos um push para o GitHub. Tendo o projeto no nosso repositório remoto, vamos configurar o Jenkins para conversar com o GitHub  e poder realizar  “pull” quando o build for inicializado.

Step 1

  1. Abra o seu eclipse e crie um Java Project chamado MyBookStore.

cimybookstore

  1. Feito isso, envie esse projeto para o GitHub.

 

cimybookstoregithub

Uma vez que o projeto já está no repositório, vamos ao Jenkins fazer as devidas configurações (estou considerando que você já tem o jenkins rodando na sua máquina, conforme o primeiro post da série).

Acesse o Jenkins e vá em Manage Jenkins  e escolha Manage Plugins. Alguns plugins o Jenkins já traz e outros precisamos instalar. Na aba de Installed verifique se o plugin do GitHub Plugin está instalado:

githubplugin

Se não estiver, vá na aba de available e procure pelo plugin. Instale também um plugin chamado Git Plugin. Esse é para que o Jenkins possa rodar os comandos do Git.

Note: use a opção install without restart.

Configurando o Jenkins

Agora vamos configurar o jenkins, portanto em manage jenkins escolha configure system e observe que você deve ter uma Git na lista:

jenkinsconfigsystem

Esses caras servem para configuramos e dizermos ao jenkins como ele deve se comportar se o projeto que fomos buildar usar um deles. Não é requerido preencher todos, exceto se você tem N projetos e cada projeto tem que usar uma estrutura diferente, por um usar ant e outro maven, daí você precisa configurar tanto maven quando o ant nessa parte do Jenkins.

Primeiro vamos configurar o JDK que é requerido para qualquer projeto Java onde precisamos compilar as classes .java.

Coloque o local onde instalou o Java, conforme a imagem a seguir:

jenkinsjdk

Assim dizemos ao jenkins onde está o nosso Java e qual ele deve usar para compilar as nossas classes durante o build

Agora vamos para o Git

jenkinsgitconfigure

Nada de diferente, apenas informamos onde está o Git na nossa máquina.

Deixamos as próximas opções da maneira default. Agora vamos configurar o Git Plugin que contém as informações do usuário que fez o commit.

jenkinsgituserconfigure

Observe que estamos configurando o Git e não GitHub.

Essa é uma das partes mais importantes e demorei horas para descobrir, aqui vamos colocar key-gen registrado lá no github:

publishsshkenkinsgithub

Em Github web Hook deixei a opção Manually manage hook URLs selecionada. Salve as modificações.

Pronto, jenkins configurado.

Criando Jobs no Jenkins

Agora vamos criar um job no Jenkins para o nosso projeto.

jenkinsnewjob

E darei o mesmo nome do projeto:

jobjenkinsbookstore

Ao criar o job, vamos para as configurações que nos interessa:

gitsourcecodejenkins

Precisamos informar onde está o nosso repositório, pode estar localmente ou remoto. No nosso caso está remoto no GitHub, que é o:

https://github.com/camilolopes/myworkspace.git

sourcecodegitjenkins

E deixamos assim. É esse cara que o jenkins fará o clone, por isso que ele precisa da URL.

Feito isso podemos salvar e buildar nosso projeto:

jenkinsbuildbookstore

Clique na barra de loading à esquerda para ver o log:

jenkinsgithubstoreclone

Observe que o jenkins conectou ao github e está trazendo o que temos no repositório, nesse caso MyBookStore.

Resultado

A seguir o resultado:

jenkinsresult

A nuvem, eu costumo dizer que o projeto passou por algumas turbulências, o solzão está tudo tranquilo, todo time pode ir para praia tranquilo que ninguém vai ligar para incomodar.

Pronto, temos nosso projeto  sendo construído pelo Jenkins.

Falha no Jenkins

Vamos simular uma falha e ver o que acontece, e para isso precisamos alterar a classe para que o código não compile:

mybookstorenocompile

Daí podemos mandar essa alteração para o GitHub. Uma vez com o código alterado no github:

githubcodechangestore

Precisamos configurar o maven, então vá em manage jenkins e na parte do maven deixe assim:

mavenconfigurejenkins

Esquecemos de configurar no Job como será o build, então vá no job que criamos e depois em configure e deixe assim o build:

buildmavenjenkins

Clique em advanced do build

buildmavencompile

No eclipse, clique com o botão direito no projeto e adicione Maven >> e habilite o maven.

Agora commit e manda as alterações para o github.

Agora vamos mandar o Jenkins buildar nosso projeto e ver o que acontece:

jenkinsfailurebuildstore

Vamos tentar arrumar isso corrigindo o código, altere o código e mande para o GitHub.

githubfixedstore

E agora vamos buildar pra ver o que acontece:

buildifxedbookstore

Pronto, assim concluímos essa parte. Um pouco cansativo na primeira vez devido a configurações, mas depois fica mais fácil. No próximo post veremos como automatizar, ou seja, com uma mudança no nosso repositório remoto, automaticamente o build começa. Fez push para o github, o build  começa a validar.

Abraços, see  ya!!

Conectando Jenkins com GitHub

Olá Pessoal,

No post de hoje vamos ver como buildar nossos projetos no jenkis e mantê-lo conectado a um repositório; no nosso caso escolhemos o github por usar o Git. Claro que poderia ser um outro repositório, até mesmo local, mas o Github é o mais popular repositório Git.

Lets go…

Starting

Antes de mais nada, vou considerar que você já conhece um pouco de Git e GitHub, pois não entrarei em detalhes de como cada um funciona, para isso  você precisa ter:

– Um repositório criado no GiHub;

– Git na sua máquina local

Os nossos steps

Basicamente criaremos um projeto e em seguida faremos um push para o GitHub. Tendo o projeto no nosso repositório remoto, vamos configurar o Jenkins para conversar com o GitHub  e poder realizar  “pull” quando o build for inicializado.

Step 1

1      Abra o seu eclipse e crie um Java Project chamado MyBookStore.

2      Feito, envie esse projeto para o GitHub.

Uma vez que o projeto já está no repositório, vamos ao Jenkins fazer as devidas configurações (estou considerando que você já tem o jenkins rodando na sua máquina, onforme o primeiro post da série).

Acesse o Jenkins e vá em Manage Jenkins  e escolha Manage Plugins. Alguns plugins o Jenkins já traz e outros precisamos instalar. Na aba de Installed verifique se o plugin do GitHub Plugin está instalado:

Se não tiver, vá na aba de available e procure pelo plugin. Instale também um plugin chamado Git Plugin. Esse é para que o Jenkins possa rodar os comandos do Git.

Note: use a opção install without restart.

Configurando o Jenkins

Agora vamos configurar o jenkins, portanto em manage jenkins escolha configure system e observe que você deve ter uma Git na lista:

Esses caras servem para configuramos e dizermos ao jenkins como ele deve ser comportar se o projeto que fomos buildar usar  um deles. Não é requerido preencher todos, exceto se você tem N projetos e cada projeto tem que usar uma estrutura diferente, por um usar ant e outro maven, daí vc precisa configurar tanto maven quando o ant nessa parte do Jenkins.

Primeiro vamos configurar o JDK que é requerido para qualquer projeto Java onde precisamos compilar as classes .java.

Coloque o local onde instalou o Java, conforme a imagem a seguir:

Assim dizemos ao jenkins onde está o nosso Java e qual ele deve usar para compilar as nossas classes durante o build

Agora vamos para o Git

Nada de diferente, apenas informamos onde está o Git na nossa máquina.

Deixamos as próximas opções da maneira default. Agora vamos configurar o Git Plugin que contém as informações do usuário que fez o commit.

Observe que estamos configurando o Git e não GitHub.

Essa é uma das partes mais importantes e demorei horas para descobrir, aqui vamos colocar key-gen registrado lá no github:

Em Github web Hook deixei a opção Manually manage hook URLs selecionada. Salve as modificações.

Pronto, jenkins configurado.

Criando Jobs no Jenkins

Agora vamos criar um job no Jenkins para o nosso projeto.

E darei o mesmo nome do projeto:

Ao criar o job, vamos para as configurações que nos interessa:

Precisamos informar onde está o nosso repositório, pode estar localmente ou remoto. No nosso caso está remoto no GitHub, que é o:

https://github.com/camilolopes/myworkspace.git

E deixamos assim. É esse cara que o jenkins fará o clone, por isso que ele precisa da URL.

Feito isso podemos salvar e buildar nosso projeto:

Clique na barra de loading à esquerda para ver o log:

Observe que o jenkins conectou ao github e está trazendo o que temos no repositório, nesse caso MyBookStore.

Resultado

A seguir o resultado:

A nuvem, eu costumo dizer que o projeto passou por algumas turbulências, o solzão está tudo tranquilo, todo time pode ir para praia tranquilo que ninguém vai ligar para incomodar.

Pronto temos, nosso projeto  sendo construído pelo Jenkins.

Falha no Jenkins

Vamos simular uma falha e ver o que acontece, e para isso precisamos alterar a classe para que o código não compile:

Daí podemos mandar essa alteração para o GitHub. Uma vez com o código alterado no github:

Precisamos configurar o maven, então vá em manage jenkins e na parte do maven deixe assim:

Esquecemos de configurar no Job como será o build, então vá no job que criamos e depois em configure e deixe assim o build:

Clique em advanced do build

No eclipse Clique com o botão direito no projeto e adicione Maven >> e habilite o maven.

Agora commit e manda as alterações para o github.

Agora vamos mandar o Jenkins buildar nosso projeto e ver o que acontece:

Vamos tentar arrumar isso corrigindo o código, altere o código e mande para o GitHub.

E agora vamos buildar pra ver. O que acontece:

Pronto! Assim concluímos essa parte. Pouco cansativo na primeira vez devido a configurações, mas depois fica mais fácil. No próximo post veremos como automatizar, ou seja, uma mudança no nosso repositório remoto e automaticamente o build começa. Ou seja, Fez push para o github, o build  começa a validar.

Abraços, see  ya!!

Série Git na Prática: Atualização específica de um arquivo na branch

Olá Pessoal,

No post de hoje vamos ver como atualizar um arquivo especifico na branch a partir da master. Como assim? Vou explicar no decorrer do post.

Lets go…

Starting….

Vamos dizer que a branch master foi atualizada e o arquivo que estou trabalhando sofreu atualização e preciso trazer para branch, então o comando seria  o seguinte:

git checkout master <nome do arquivo>

Assim estamos trazendo o arquivo do master para o branch.

Então vamos supor que na branch de development estou trabalhando com o arquivo Main.java

E na master alguém alterou o arquivo e fez o commit e ele está assim:

E agora preciso pegar essa atualização e trazer para branch. Nesse caso não haverá conflitos porque as alterações foram em pontos diferentes.

Observe que temos arquivos para commit, devido atualização que fizemos:   

Resultado após o commit:

Lembrando: as alterações feitas no arquivo na branch serão perdidas. 

Abraços, see ya!!