Exercício – Criar recursos do Azure e uma aplicação Java do Spring
Nesta unidade, irá criar uma aplicação básica do Spring Boot. Irá utilizar a CLI do Azure e um ambiente de desenvolvimento integrado (IDE) à sua escolha para editar o código. Utilize um terminal à sua escolha para executar o código.
Preparar o ambiente de trabalho
Configure algumas variáveis de ambiente ao utilizar os seguintes comandos:
AZ_RESOURCE_GROUP=azure-spring-workshop
AZ_DATABASE_NAME=<YOUR_DATABASE_NAME>
AZ_LOCATION=<YOUR_AZURE_REGION>
AZ_MYSQL_USERNAME=spring
AZ_MYSQL_PASSWORD=<YOUR_MYSQL_PASSWORD>
AZ_LOCAL_IP_ADDRESS=<YOUR_LOCAL_IP_ADDRESS>
No seu código, substitua os marcadores de posição pelos valores na tabela abaixo. Estes valores são utilizados ao longo deste módulo.
Variável | Description |
---|---|
<YOUR_DATABASE_NAME> | O nome do seu servidor MySQL. Deve ser um nome exclusivo no Azure. |
<YOUR_AZURE_REGION> | A região do Azure que irá utilizar. Pode utilizar a região eastus por predefinição, mas recomendamos que utilize uma região mais próxima do local onde vive. Para ver a lista completa de regiões disponíveis, introduza az account list-locations . |
<YOUR_MYSQL_PASSWORD> | A palavra-passe do seu servidor de bases de dados MySQL. A palavra-passe deve ter pelo menos oito carateres. Os caracteres devem ser de três das seguintes categorias: letras maiúsculas em inglês, letras minúsculas em inglês, números de 0 a 9 e caracteres não alfanuméricos (!, $, #, % e assim por diante). |
<YOUR_LOCAL_IP_ADDRESS> | O endereço IP do computador local a partir do qual irá executar a aplicação do Spring Boot. Para encontrar o endereço IP, aponte o browser para o endereço whatismyip.akamai.com. |
Depois, crie um grupo de recursos:
az group create \
--name $AZ_RESOURCE_GROUP \
--location $AZ_LOCATION \
| jq
Nota
Este módulo utiliza a ferramenta jq
, que está instalada por predefinição no Azure Cloud Shell, para apresentar dados JSON e torná-los mais legíveis.
Se não quiser utilizar a ferramenta jq
, pode remover com segurança a parte | jq
de todos os comandos neste módulo.
Criar uma instância da Base de Dados do Azure para MySQL
Agora, vai criar um servidor MySQL gerido.
Nota
Para saber mais sobre a Base de Dados do Azure para MySQL, siga a ligação para a documentação relevante no final deste módulo.
Execute o seguinte script para criar uma pequena instância da Base de Dados do Azure para MySQL. A base de dados tem 1 CPU e 2 GB de RAM.
az mysql server create \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_DATABASE_NAME \
--location $AZ_LOCATION \
--sku-name B_Gen5_1 \
--storage-size 5120 \
--admin-user $AZ_MYSQL_USERNAME \
--admin-password $AZ_MYSQL_PASSWORD \
| jq
Este script cria um pequeno servidor MySQL que utiliza as variáveis que configurou anteriormente.
Configurar uma regra de firewall para o servidor MySQL
A Base de Dados do Azure para MySQL está protegida por predefinição. A respetiva firewall não permite ligações de entrada. Por isso, adicione uma regra de firewall para permitir que o endereço IP local aceda ao servidor de bases de dados.
Execute o seguinte comando para abrir a firewall do servidor:
az mysql server firewall-rule create \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_DATABASE_NAME-database-allow-local-ip \
--server-name $AZ_DATABASE_NAME \
--start-ip-address $AZ_LOCAL_IP_ADDRESS \
--end-ip-address $AZ_LOCAL_IP_ADDRESS \
| jq
Execute o seguinte comando para permitir que os recursos do Azure acedam à firewall:
az mysql server firewall-rule create \
--resource-group $AZ_RESOURCE_GROUP \
--name allAzureIPs \
--server-name $AZ_DATABASE_NAME \
--start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0 \
| jq
Configurar uma base de dados MySQL
O servidor MySQL que criou anteriormente está vazio. Não tem nenhuma base de dados que possa utilizar com a aplicação do Spring Boot. Crie uma nova base de dados chamada demo
:
az mysql db create \
--resource-group $AZ_RESOURCE_GROUP \
--name demo \
--server-name $AZ_DATABASE_NAME \
| jq
Gerar a aplicação com o Spring Initializr
O Spring Initializr é uma aplicação Web que gera automaticamente uma estrutura de projeto do Spring Boot. O Spring Initializr não gera código de aplicação, mas dá-lhe uma estrutura de projeto básica e uma especificação de compilação do Maven.
Vai gerar a estrutura da sua aplicação com três dependências: web
, mysql
e data-jpa
.
Não precisa de especificar dependências do Azure porque vai executar a sua aplicação localmente.
Numa linha de comandos, vai gerar a aplicação:
curl https://start.spring.io/starter.tgz -d type=maven-project -d dependencies=web,data-jpa,mysql -d baseDir=azure-spring-workshop -d bootVersion=3.1.5.RELEASE -d javaVersion=17 | tar -xzvf -
Configurar o Spring Boot para utilizar a Base de Dados do Azure para MySQL
Abra o ficheiro src/main/resources/application.properties e adicione algumas propriedades. Certifique-se de que substitui as duas variáveis $AZ_DATABASE_NAME
e a variável $AZ_MYSQL_PASSWORD
pelos valores que configurou anteriormente.
logging.level.org.hibernate.SQL=DEBUG
spring.datasource.url=jdbc:mysql://$AZ_DATABASE_NAME.mysql.database.azure.com:3306/demo?serverTimezone=UTC
spring.datasource.username=spring@$AZ_DATABASE_NAME
spring.datasource.password=$AZ_MYSQL_PASSWORD
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop
Aviso
A propriedade de configuração spring.jpa.hibernate.ddl-auto=create-drop
significa que o Spring Boot criará automaticamente um esquema de base de dados no arranque da aplicação e tentará eliminar o esquema da base de dados no encerramento. Esta propriedade é útil para fins de teste, mas não deve ser utilizada na fase de produção!
Nota
Vai acrescentar ?serverTimezone=UTC
à propriedade de configuração spring.datasource.url
. Esta configuração indica ao controlador do Java Database Connectivity (JDBC) que utilize o formato de data UTC (Hora Universal Coordenada) quando ligar à base de dados. Caso contrário, o seu servidor Java não vai utilizar o mesmo formato de data que a base de dados, o que irá resultar num erro.
Agora, inicie a sua aplicação com o wrapper do Maven fornecido:
./mvnw spring-boot:run
Esta captura de ecrã mostra a aplicação em execução pela primeira vez:
Codificar a aplicação
Em seguida, adicione o código Java abaixo. Este código utiliza a JPA (API de Persistência em Java) para armazenar e obter dados do seu servidor MySQL.
Irá utilizar uma classe de entidade JPA para mapear um objeto Todo
Java diretamente à tabela Todo
MySQL.
Junto à classe DemoApplication
, crie uma nova classe de entidade Todo
. Em seguida, adicione o seguinte código:
package com.example.demo;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Todo {
public Todo() {
}
public Todo(String description, String details, boolean done) {
this.description = description;
this.details = details;
this.done = done;
}
@Id
@GeneratedValue
private Long id;
private String description;
private String details;
private boolean done;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}
public boolean isDone() {
return done;
}
public void setDone(boolean done) {
this.done = done;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Todo)) {
return false;
}
return id != null && id.equals(((Todo) o).id);
}
@Override
public int hashCode() {
return 31;
}
}
Esta classe é um modelo de domínio mapeado na tabela Todo
. Será automaticamente criada pela JPA.
Para gerir essa classe, precisa de um repositório. Defina uma nova interface TodoRepository
no mesmo pacote:
package com.example.demo;
import org.springframework.data.jpa.repository.JpaRepository;
public interface TodoRepository extends JpaRepository<Todo, Long> {
}
Este é um repositório JPA gerido pelo Spring Data JPA. Ao expandir o JpaRepository
, obtém vários métodos genéricos de criação, leitura, atualização e eliminação (CRUD) para o seu tipo. Assim, pode realizar ações como guardar e eliminar objetos Todo
.
Conclua a aplicação ao criar um RestController
que consiga publicar interfaces REST para armazenar e obter dados através de HTTP. Implemente uma classe TodoController
no mesmo pacote. Em seguida, adicione o seguinte código:
package com.example.demo;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/")
public class TodoController {
private final TodoRepository todoRepository;
public TodoController(TodoRepository todoRepository) {
this.todoRepository = todoRepository;
}
@PostMapping("/")
@ResponseStatus(HttpStatus.CREATED)
public Todo createTodo(@RequestBody Todo todo) {
return todoRepository.save(todo);
}
@GetMapping("/")
public Iterable<Todo> getTodos() {
return todoRepository.findAll();
}
}
Por último, pare a aplicação e inicie-a novamente com o seguinte comando:
./mvnw spring-boot:run
A aplicação do Spring Boot deverá ser iniciada e ligada à base de dados.
Esta captura de ecrã mostra a aplicação a ligar-se à base de dados:
Testar a aplicação
Para testar a aplicação, pode utilizar o cURL
.
Comece por criar um novo item de lista de tarefas na base de dados:
curl --header "Content-Type: application/json" \
--request POST \
--data '{"description":"configuration","details":"congratulations, you have set up your Spring Boot application correctly!","done": "true"}' \
http://127.0.0.1:8080
Este comando deverá devolver o item criado:
{"id":1,"description":"configuration","details":"congratulations, you have set up your Spring Boot application correctly!","done":true}
Depois, obtenha os dados ao utilizar um novo pedido de cURL
:
curl http://127.0.0.1:8080
Este comando devolve a lista de itens de tarefas, incluindo o item que criou:
[{"id":1,"description":"configuration","details":"congratulations, you have set up your Spring Boot application correctly!","done":true}]