A maioria das aplicações modernas são constituidas de múltiplos pequenos serviços independentes que interagem e assim dão forma à própria aplicação. Chamamos isso de microserviços. Um simples exemplo pode ser uma aplicação com 3 serviços:
- web front-end
- web back-end
- banco de dados
Coloque os três serviços juntos e temos uma aplicação com alguma utilidade.
Subir e gerenciar vários serviços pode se tornar uma tarefa difícil. É aí que entra o Docker-Compose.
Ao invés de juntar tudo com scripts e comandos extreamente longos, o Docker-Compose permite você descrever toda aplicação em único arquivo de configuração declarativo. Depois então você sobe todos os serviços com um único comando:
$ docker-compose up
Vamos ilustrar o uso do docker-compose criando uma aplicação formada por 3 serviços: uma interface REST no backend (com Spring Boot), um front-end HTML (Java Server Faces) e um banco de dados MySQL. Cada serviço totalmente separado um do outro
Front-End com Java Server Faces
Nosso front-end é um formulário HTML com JSF para cadastrar uma entidade Pessoa, a qual possui dois campos: nome e profissão. O front também lista todas as pessoas registradas na base de dados em um elemento table. O container é o WildFly. Há uma camada de serviço para fazer a requisições ao backend, representada pela classe Service.java e retorná-las ao managed bean. A classe que recebe os eventos da página HTML é ManagedBean.java:
classe ManagedBean.java
O arquivo Dockerfile é auto explicativo e descreve passo a passo como construir a aplicação e executá-la dentro do Docker: A aplicação roda dentro do Wildfly (FROM) e o arquivo front-end.war é adicionado na pasta /opt/jboss/wildfly/standalone/deployments/ do servidor:
Neste ponto a aplicação pode rodar, porém ela ainda não estará funcional, já que depende de dois outros serviços: o backend propriamente dito, este por sua vez depende do banco de dados.
Na parte 2 deste artigo criamos e subimos esses dois serviços que faltam.
Tiago 4:13-15
Nosso front-end é um formulário HTML com JSF para cadastrar uma entidade Pessoa, a qual possui dois campos: nome e profissão. O front também lista todas as pessoas registradas na base de dados em um elemento table. O container é o WildFly. Há uma camada de serviço para fazer a requisições ao backend, representada pela classe Service.java e retorná-las ao managed bean. A classe que recebe os eventos da página HTML é ManagedBean.java:
classe ManagedBean.java
package com.app;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Model;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import com.app.entidade.Pessoa;
@Model
public class ManagedBean {
@Inject
private Service service;
private Pessoa pessoa = new Pessoa();
private List pessoas;
public String salvar() {
try {
pessoa = service.salvarPessoa(pessoa);
pessoa = new Pessoa();
FacesContext.getCurrentInstance()
.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,
"salvo com sucesso", "salvo com sucesso"));
}
catch(Exception e) {
FacesContext.getCurrentInstance()
.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL,
e.getMessage(), e.getMessage()));
}
return null;
}
public Pessoa getPessoa() {
return pessoa;
}
public void setPessoa(Pessoa pessoa) {
this.pessoa = pessoa;
}
public List getPessoas() {
try {
pessoas = service.getPessoas();
return pessoas;
}
catch(RuntimeException e) {
FacesContext.getCurrentInstance()
.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL,
e.getMessage(), e.getMessage()));
}
return null;
}
public void setPessoas(List pessoas) {
this.pessoas = pessoas;
}
}
classe Service.java
package com.app;
import java.net.URI;
import java.util.List;
import javax.enterprise.inject.Model;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import com.app.entidade.Pessoa;
@Model
public class Service {
private final String URL_BACKEND = "http://backend:8080/app-backend/";
public Pessoa salvarPessoa(Pessoa pessoa) {
final String operacao = "salvar";
URI uri = UriBuilder.fromUri(URL_BACKEND).path(operacao).build();
//usando JAX-RS Client API para enviar o objeto pessoa ao server back-end
Entity data = Entity.entity(pessoa, MediaType.APPLICATION_XML_TYPE);
Response response = ClientBuilder.newClient()
.target(uri)
.request(MediaType.APPLICATION_XML)
.post(data, Response.class);
if(response.getStatusInfo() == Response.Status.OK)
return pessoa;
else
throw new RuntimeException("Ocorreu um erro ao salvar a Pessoa");
}
public List getPessoas() {
final String operacao = "all";
URI uri = UriBuilder.fromUri(URL_BACKEND).path(operacao).build();
Response response = ClientBuilder.newClient()
.target(uri)
.request(MediaType.APPLICATION_JSON_TYPE)
.get(Response.class);
if(response.getStatusInfo() == Response.Status.OK)
return response.readEntity(List.class);
else
throw new RuntimeException("Não foi possível obter a Lista de Pessoas");
}
}
Entidade Pessoa.javapackage com.app.entidade;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Pessoa implements Serializable{
private Long id;
private String nome;
private String profissao;
//getters & setters omitidos
}
Página index.xhtml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Cadastro Pessoa</title>
</h:head>
<h:body>
<h:form>
<h:messages />
<h:panelGrid columns="2">
<h:outputText value="Nome" />
<h:inputText value="#{managedBean.pessoa.nome}" />
<h:outputText value="Idade" />
<h:inputText value="#{managedBean.pessoa.profissao}" />
</h:panelGrid>
<h:commandButton action="#{managedBean.salvar}" value="Salvar" />
<p />
Lista
<h:dataTable value="#{managedBean.pessoas}" var="pessoa" border="1">
<h:column>
<h:outputText value="#{pessoa.nome}" />
</h:column>
<h:column>
<h:outputText value="#{pessoa.profissao}" />
</h:column>
</h:dataTable>
</h:form>
</h:body>
</html>
O arquivo Dockerfile é auto explicativo e descreve passo a passo como construir a aplicação e executá-la dentro do Docker: A aplicação roda dentro do Wildfly (FROM) e o arquivo front-end.war é adicionado na pasta /opt/jboss/wildfly/standalone/deployments/ do servidor:
FROM jboss/wildfly
MAINTAINER "http://finalexception.blogspot.com"
ADD target/front-end.war /opt/jboss/wildfly/standalone/deployments/
Com o botão direito do mouse na pasta raiz do projeto, selecione Run As e Run as Maven Install. Esse comando gera o arquivo front-end.war na pasta target, conforme descrito no Dockerfile.Na parte 2 deste artigo criamos e subimos esses dois serviços que faltam.
"Ouçam agora, vocês que dizem: 'Hoje ou amanhã iremos para esta ou aquela cidade, passaremos um ano ali, faremos negócios e ganharemos dinheiro'. Vocês nem sabem o que acontecerá amanhã! Que é a sua vida? Vocês são como a neblina que aparece por um pouco de tempo e depois se dissipa. Em vez disso, deveriam dizer: 'Se o Senhor quiser, viveremos e faremos isto ou aquilo'."
No comments:
Post a Comment