Ejercicio: creación de recursos de Azure y una aplicación de Java Spring
En esta unidad, creará una aplicación básica de Spring Boot. Usará la CLI de Azure y un entorno de desarrollo integrado (IDE) de su elección para editar el código. Utilice el terminal de su elección para ejecutar el código.
Preparación del entorno de trabajo
Configure algunas variables de entorno mediante los siguientes 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>
En el código, reemplace los marcadores de posición por los valores de la tabla siguiente. Estos valores se utilizan durante todo el módulo.
Variable | Descripción |
---|---|
<NOMBRE_DE_LA_BASE_DE_DATOS> | El nombre del servidor MySQL. Debe ser único en Azure. |
<REGIÓN_DE_AZURE> | La región de Azure que usará. Puede usar eastus de manera predeterminada, pero le recomendamos que use una región cercana a su lugar de residencia. Para ver la lista completa de las regiones disponibles, escriba az account list-locations . |
<CONTRASEÑA_DE_MYSQL> | La contraseña del servidor de bases de datos MySQL. La contraseña debe tener ocho caracteres como mínimo. Los caracteres deben ser de tres de las categorías siguientes: letras en mayúsculas del alfabeto inglés, letras en minúscula del alfabeto inglés, números del 0 al 9 y caracteres no alfanuméricos (!, $, #, %, etc.). |
<DIRECCIÓN_IP_LOCAL> | Dirección IP del equipo local desde el que se ejecutará la aplicación de Spring Boot. Para encontrar la dirección IP, apunte el explorador a whatismyip.akamai.com. |
A continuación, cree un grupo de recursos:
az group create \
--name $AZ_RESOURCE_GROUP \
--location $AZ_LOCATION \
| jq
Nota
En este módulo se usa la herramienta jq
, que se instala de forma predeterminada en Azure Cloud Shell para mostrar datos JSON y hacer que sean más legibles.
Si no quiere usar la herramienta jq
, puede quitar de forma segura la parte | jq
de todos los comandos de este módulo.
Creación de una instancia de Azure Database for MySQL
Ahora creará un servidor MySQL administrado.
Nota:
Para obtener más información sobre Azure Database for MySQL, consulte el vínculo a la documentación correspondiente que encontrará al final de este módulo.
Ejecute el siguiente script para crear una instancia pequeña de Azure Database for MySQL. La base de datos tiene 1 CPU y 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 crea un servidor MySQL pequeño que usa las variables que configuró anteriormente.
Configuración de una regla de firewall para el servidor de MySQL
Azure Database for MySQL está protegido de forma predeterminada. Su firewall no permite ninguna conexión entrante. Por tanto, deberá agregar una regla de firewall que permita que la dirección IP local tenga acceso al servidor de bases de datos.
Ejecute el siguiente comando para abrir el firewall del 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
Ejecute el siguiente comando para permitir el acceso del firewall desde los recursos de Azure:
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
Configuración de una base de datos MySQL
El servidor de MySQL que creó anteriormente está vacío. No tiene ninguna base de datos que pueda usar con la aplicación de Spring Boot. Cree una nueva base de datos llamada demo
:
az mysql db create \
--resource-group $AZ_RESOURCE_GROUP \
--name demo \
--server-name $AZ_DATABASE_NAME \
| jq
Generación de la aplicación con Spring Initializr
Spring Initializr es una aplicación web que genera automáticamente una estructura de proyecto de Spring Boot. Spring Initializr no genera ningún código de aplicación, pero le proporciona una estructura de proyecto básica y una especificación de compilación de Maven.
Generará el elemento de scaffolding de la aplicación con tres dependencias: web
, mysql
y data-jpa
.
No es necesario especificar las dependencias de Azure, ya que ejecutará la aplicación de forma local.
En un símbolo del sistema, genere la aplicación:
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 -
Configuración de Spring Boot para el uso de Azure Database for MySQL
Abra el archivo src/main/resources/application.properties y agregue algunas propiedades. Asegúrese de reemplazar las dos variables $AZ_DATABASE_NAME
y la variable $AZ_MYSQL_PASSWORD
por los valores que configuró 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
Advertencia
La propiedad de configuración spring.jpa.hibernate.ddl-auto=create-drop
hará que Spring Boot cree automáticamente un esquema de la base de datos al iniciar la aplicación e intente eliminar el esquema de la base de datos cuando se cierre. Esta propiedad es excelente para las pruebas, pero no se debe usar durante la producción.
Nota:
Anexe ?serverTimezone=UTC
a la propiedad de configuración spring.datasource.url
. Esta configuración indica al controlador de Java Database Connectivity (JDBC) que use el formato de fecha y hora universal coordinada (UTC) cuando se conecte a la base de datos. De lo contrario, el servidor Java no usará el mismo formato de fecha que la base de datos, lo que producirá un error.
Ahora inicie la aplicación mediante el contenedor de Maven proporcionado:
./mvnw spring-boot:run
Esta captura de pantalla muestra la aplicación cuando se ejecuta por primera vez:
Incorporación del código de la aplicación
A continuación, agregue el siguiente código Java. Usa Java Persistence API (JPA) para almacenar y recuperar datos del servidor MySQL.
Usará una clase de entidad JPA para asignar un objeto Todo
de Java directamente a la tabla Todo
de MySQL.
Junto a la clase DemoApplication
, cree una nueva clase de entidad Todo
. Después, agregue el siguiente 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 clase es un modelo de dominio que se asigna a la tabla Todo
. JPA la creará automáticamente.
Para administrar esa clase, necesitará un repositorio. Defina una nueva interfaz TodoRepository
en el mismo paquete:
package com.example.demo;
import org.springframework.data.jpa.repository.JpaRepository;
public interface TodoRepository extends JpaRepository<Todo, Long> {
}
Este repositorio es un repositorio de JPA que administra la JPA de Spring Data. Al extender JpaRepository
, obtendrá una serie de métodos genéricos de creación, lectura, actualización y eliminación (CRUD) para su tipo. Así pues, podrá, por ejemplo, guardar y eliminar objetos Todo
.
Finalice la aplicación mediante la creación de un elemento RestController
que pueda publicar interfaces REST para almacenar y recuperar datos a través de HTTP. Implemente una clase TodoController
en el mismo paquete. Después, agregue el siguiente 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, detenga la aplicación y, a continuación, iníciela de nuevo con el siguiente comando:
./mvnw spring-boot:run
La aplicación de Spring Boot debe iniciarse y conectarse a la base de datos.
Esta captura de pantalla muestra la aplicación conectándose a la base de datos:
Prueba de la aplicación
Para probar la aplicación, puede usar cURL
.
En primer lugar, cree un nuevo elemento de tareas pendientes en la base de datos:
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 debe devolver el elemento creado:
{"id":1,"description":"configuration","details":"congratulations, you have set up your Spring Boot application correctly!","done":true}
A continuación, recupere los datos mediante una nueva solicitud cURL
:
curl http://127.0.0.1:8080
Este comando devuelve la lista de tareas pendientes, incluido el elemento que ha creado:
[{"id":1,"description":"configuration","details":"congratulations, you have set up your Spring Boot application correctly!","done":true}]