Tuesday, February 26, 2019

SpringBoot + MySQL + Docker-Compose (parte 2)

Na parte 1 deste artigo criamos o front-end. Nesta, criamos o back-end e o serviço de banco de dados.

Back-end com Spring Boot

Acesse a página start.spring.io e preencha os campos de dependências conforme a imagem abaixo e clique em Generate project. Unzipe o arquivo baixado e importe o projeto para o eclipse.



O projeto back-end tem como base o pacote com.app.backend, a partir do qual criamos o pacote entidade, que contém a entidade Pessoa.java idêntica ao do projeto front-end. Temos também o pacote repository, que declara uma interface para persistência de dados utilizando o Spring data. E o pacote controller, que expõe um web service REST que recebe as requisições do front-end. A estrutura do projeto back-end é como da imagem abaixo:


Interface PessoaRepository.java cuja implementação fica a cargo do container do Spring:

package com.app.backend.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.app.backend.entidade.Pessoa;

@Repository
public interface PessoaRepository extends JpaRepository{

}

Web Service REST PessoaController.java:
package com.app.backend.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.app.backend.entidade.Pessoa;
import com.app.backend.repository.PessoaRepository;

@RestController
@RequestMapping("/pessoa")
public class PessoaController {
 
 @Autowired
 PessoaRepository pessoaDao;
 
 @PostMapping(value = "/salvar")
 public ResponseEntity salvarPessoa(@RequestBody Pessoa pessoa) {
    
  try {
   pessoa = pessoaDao.save(pessoa);
   ResponseEntity response = new ResponseEntity<>(pessoa, HttpStatus.OK);   
   return response;
  }
  catch(Exception e) {
   e.printStackTrace();
   ResponseEntity response = new ResponseEntity<>(e.getMessage(), 
               HttpStatus.INTERNAL_SERVER_ERROR);   
   return response;
  }  
 }
 
 @GetMapping(value = "/todas")
 public ResponseEntity getTodas() {  
 
  List result = pessoaDao.findAll();  
  ResponseEntity> response = new ResponseEntity<>(result, HttpStatus.OK);
  return response;
 }   
}

A entidade Pessoa.java é idêntica àquela descrita na parte 1 deste artigo. O arquivo Dockerfile é auto explicativo e descreve passo a passo como construir a aplicação e executá-la dentro do Docker:
    FROM openjdk:8
    MAINTAINER "http://finalexception.blogspot.com"
    ADD target/back-end.jar .
    ENTRYPOINT ["java", "-jar", "back-end.jar"]


Na pasta main/resources temos o arquivo application.properties do Spring vazio. Deixe-o conforme abaixo:
# JPA PROPS
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy

# APPLICATION CONTEXT PATH
server.servlet.context-path=/app-backend

# DATABASE
spring.datasource.url=jdbc:mysql://mysql-standalone:3306/bd_pessoa?useSSL=true&serverTimezone=UTC
spring.datasource.username=rafael
spring.datasource.password=12345

spring.database.driverClassName =com.mysql.cj.jdbc.Driver

Isso é tudo! Com o botão direito do mouse no projeto, selecione Run As e Run as Maven Install. Esse comando gera o arquivo back-end.jar na pasta target, conforme descrito no Dockerfile.

Subindo a aplicação com Docker-compose

Nossa aplicação tem 3 serviços, poderia ter dezenas. Subir e gerenciar uma grande quantidade de serviços pode ser trabalhos, é aí que entra o docker-compose.

O Compose é um arquivo binário escrito em Python que você deve instalar no host que roda o docker.

A pasta dos projetos back-end e front-end devem estar dentro do mesmo diretório, que também devre conter o arquivo docker-compose.yml:



Com o Docker-compose, definimos os serviços da aplicação em arquivo YML e o Compose se encarrega de publicar a aplicação na engine do Docker.

docker-compose.yml
:
version: '3.5'
services:
  mysql-standalone:
    image: mysql:5.6
    environment:
      - MYSQL_ROOT_PASSWORD=rootpass
      - MYSQL_DATABASE=bd_pessoa
      - MYSQL_USER=rafael
      - MYSQL_PASSWORD=12345
    expose:
      - 3306
  backend:
    build: back-end
    depends_on:
      - mysql-standalone
    ports:
      - 8989:8080
    environment:
      - DATABASE_HOST=mysql-standalone
      - DATABASE_USER=rafael
      - DATABASE_NAME=bd_pessoa
      - DATABASE_PASSWORD=12345
      - DATABASE_PORT=3306
  frontend:
    build: front-end
    depends_on:
      - backend
    ports:
      - 8180:8080


O arquivo docker-compose.yml acima também serve como uma valiosa documentação do projeto. Nele vemos que nossa aplicação possui 3 serviços, cada qual em um host virtual separado: mysql-standalone, backend e frontend. Execute o comando $ docker-compose up para subir aplicação:



Agora você pode acessar o front-end na porta 8180 e testar a aplicação:


O código fonte do projeto completo está no git-hub.

"Fiquem unidos a mim, e eu ficarei unidos a vocês. O ramo que não fica unido à videira não pode dar frutos. Vocês também não poderão dar frutos, se não ficarem unidos a mim. Eu sou a videira, e vocês são os ramos. Quem fica unido a mim, e eu a ele, dará muito fruto, porque sem mim vocês não podem fazer nada"


João 15:4-5

       

1 comment: