Übung: Erstellen von Azure-Ressourcen und einer Java-Spring-Anwendung

Abgeschlossen

In dieser Einheit erstellen Sie eine einfache Spring Boot-Anwendung. Sie verwenden die Azure CLI und eine integrierte Entwicklungsumgebung (Integrated Development Environment, IDE) Ihrer Wahl, um den Code zu bearbeiten. Zum Ausführen des Codes können Sie ein beliebiges Terminal verwenden.

Vorbereiten der Arbeitsumgebung

Richten Sie mehrere Umgebungsvariablen mithilfe der folgenden Befehle ein:

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>

Ersetzen Sie in Ihrem Code die Platzhalter durch die Werte in der folgenden Tabelle. Diese Werte werden in diesem Modul verwendet.

Variable Beschreibung
<YOUR_DATABASE_NAME> Ersetzen Sie diesen Platzhalter durch den Namen Ihres MySQL-Servers. Er muss innerhalb von Azure eindeutig sein.
<YOUR_AZURE_REGION> Ersetze Sie diesen Platzhalter durch die Azure-Region, die Sie verwenden. Standardmäßig können Sie eastus verwenden, aber es wird empfohlen, dass Sie eine Region in der Nähe ihrer Liveumgebung verwenden. Geben Sie az account list-locations ein, um eine Liste aller verfügbaren Regionen anzuzeigen.
<YOUR_MYSQL_PASSWORD> Ersetzen Sie diesen Platzhalter durch das Kennwort für Ihren MySQL-Datenbankserver. Das Kennwort muss mindestens acht Zeichen lang sein. Die Zeichen sollten aus drei der folgenden Kategorien bestehen: Englische Großbuchstaben, englische Kleinbuchstaben, Zahlen von 0 bis 9 und nicht alphanumerische Zeichen (!, $, #, % usw.).
<YOUR_LOCAL_IP_ADDRESS> Ersetzen Sie diesen Platzhalter durch die IP-Adresse des lokalen Computers, auf dem Sie die Spring Boot-Anwendung ausführen möchten. Verweisen Sie in Ihrem Browser auf whatismyip.Akamai.com, um die IP-Adresse zu ermitteln.

Erstellen Sie als Nächstes eine Ressourcengruppe:

az group create \
    --name $AZ_RESOURCE_GROUP \
    --location $AZ_LOCATION \
    | jq

Hinweis

Dieses Modul verwendet das jq-Tool, das standardmäßig in Azure Cloud Shell installiert wird, um JSON-Daten anzuzeigen und besser lesbar zu machen.

Wenn Sie das jq-Tool nicht verwenden möchten, können Sie den | jq-Teil aller Befehle in diesem Modul sicher entfernen.

Erstellen einer Azure Database for MySQL-Instanz

Nun erstellen Sie einen verwalteten MySQL-Server.

Hinweis

Weitere Informationen zu Azure Database for MySQL finden Sie am Ende dieses Moduls über den Link zur entsprechenden Dokumentation.

Führen Sie das folgende Skript aus, um eine kleine Azure Database for MySQL-Instanz zu erstellen. Die Datenbank verfügt über 1 CPU und 2 GB 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

Mit diesem Skript wird ein kleiner MySQL-Server erstellt, der die zuvor eingerichteten Variablen verwendet.

Konfigurieren einer Firewallregel für den MySQL-Server

Azure Database for MySQL wird standardmäßig geschützt. Die Firewall lässt keine eingehenden Verbindungen zu. Fügen Sie daher eine Firewallregel hinzu, damit die lokale IP-Adresse auf den Datenbankserver zugreifen kann.

Führen Sie den folgenden Befehl aus, um die Firewall des Servers zu öffnen:

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

Führen Sie den folgenden Befehl aus, um der Firewall Zugriff auf Azure-Ressourcen zu gewähren:

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

Konfigurieren einer MySQL-Datenbank

Der MySQL-Server, den Sie zuvor erstellt haben, ist leer. Er verfügt über keine Datenbank, die Sie mit der Spring Boot-Anwendung verwenden können. Erstellen Sie eine neue Datenbank mit dem Namen demo:

az mysql db create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name demo \
    --server-name $AZ_DATABASE_NAME \
    | jq

Erstellen der Anwendung mithilfe von Spring Initializr

Spring Initializr ist eine Webanwendung, die eine Spring Boot-Projektstruktur für Sie erstellt. Spring Initializr erzeugt keinen Anwendungscode, gibt Ihnen jedoch eine grundlegende Projektstruktur und eine Maven-Buildspezifikation.

Sie generieren Ihr Anwendungsgerüst mit drei Abhängigkeiten: web, mysql und data-jpa. Sie müssen keine Azure-Abhängigkeiten angeben, da Sie die Anwendung lokal ausführen.

Generieren Sie in der Eingabeaufforderung die Anwendung:

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 -

Konfigurieren von Spring Boot für die Verwendung von Azure Database for MySQL

Öffnen Sie die Datei src/main/resources/application.properties, und fügen Sie mehrere Eigenschaften hinzu. Stellen Sie sicher, dass Sie die beiden $AZ_DATABASE_NAME-Variablen und die $AZ_MYSQL_PASSWORD-Variable durch die Werte ersetzen, die Sie zuvor festgelegt haben.

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

Warnung

Die Konfigurationseigenschaft spring.jpa.hibernate.ddl-auto=create-drop gibt an, dass Spring Boot beim Starten der Anwendung automatisch ein Datenbankschema erstellt und versucht, das Datenbankschema zu löschen, wenn es heruntergefahren wird. Diese Eigenschaft eignet sich hervorragend für Tests, sollte aber nicht in der Produktion verwendet werden!

Hinweis

Sie fügen ?serverTimezone=UTC an die Konfigurationseigenschaft spring.datasource.url an. Dieses Setup weist den JDBC-Treiber (Java Database Connectivity, JDBC) an, das UTC-Datumsformat (Coordinated Universal Time, koordinierte Weltzeit) zu verwenden, wenn Sie eine Verbindung mit der Datenbank herstellen. Andernfalls verwendet Ihr Java-Server nicht das gleiche Datumsformat wie die Datenbank. Dies führt zu einem Fehler.

Starten Sie Ihre Anwendung nun, indem Sie den bereitgestellten Maven-Wrapper verwenden:

./mvnw spring-boot:run

Dieser Screenshot zeigt die Anwendung, die zum ersten Mal ausgeführt wird:

Screenshot, der die laufende Anwendung anzeigt.

Codieren der Anwendung

Fügen Sie als Nächstes den folgenden Java-Code hinzu. Er verwendet die Java Persistence-API (JPA) zum Speichern und Abrufen von Daten von Ihrem MySQL-Server.

Sie verwenden eine JPA-Entitätsklasse, um ein Java-Todo-Objekt direkt der MySQL-Todo-Tabelle zuzuordnen.

Erstellen Sie neben der DemoApplication-Klasse eine neue Todo-Entitätsklasse. Fügen Sie dann den folgenden Code hinzu:

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;
    }
}

Bei dieser Klasse handelt es sich um ein Domänenmodell, das in der Todo-Tabelle zugeordnet ist. Sie wird automatisch von der JPA erstellt.

Sie benötigen ein Repository, um diese Klasse zu verwalten. Definieren Sie eine neue TodoRepository-Schnittstelle im gleichen Paket:

package com.example.demo;

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

public interface TodoRepository extends JpaRepository<Todo, Long> {
}

Bei diesem Repository handelt es sich um ein JPA-Repository, das von Spring Data JPA verwaltet wird. Wenn Sie JpaRepository erweitern, erhalten Sie eine Reihe generischer create-, read-, update- und delete-Methoden (CRUD) für Ihren Typ. So können Sie z. B. Todo-Objekte speichern und löschen.

Vervollständigen Sie die Anwendung, indem Sie eine RestController-Klasse erstellen, die REST-Schnittstellen veröffentlichen kann, um Daten mit HTTP zu speichern und abzurufen. Implementieren Sie eine TodoController-Klasse im gleichen Paket. Fügen Sie dann den folgenden Code hinzu:

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();
    }
}

Beenden Sie dann die Anwendung, und starten Sie sie nochmal mit dem folgenden Befehl:

./mvnw spring-boot:run

Die Spring Boot-Anwendung sollte starten und eine Verbindung zu Ihrer Datenbank herstellen.

Hier sehen Sie einen Screenshot der Anwendung, die eine Verbindung zur Datenbank herstellt:

Screenshot der laufenden Anwendung, die eine Verbindung zur Datenbank herstellt

Testen der Anwendung

Zum Testen der Anwendung können Sie cURL verwenden.

Erstellen Sie zunächst ein neues To-do-Element in der Datenbank:

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

Mit diesem Befehl sollte das erstellte Element zurückgegeben werden:

{"id":1,"description":"configuration","details":"congratulations, you have set up your Spring Boot application correctly!","done":true}

Rufen Sie dann die Daten mithilfe einer neuen cURL-Anforderung ab:

curl http://127.0.0.1:8080

Mit diesem Befehl wird die Liste der To-do-Elemente zurückgegeben, einschließlich des von Ihnen erstellten Elements:

[{"id":1,"description":"configuration","details":"congratulations, you have set up your Spring Boot application correctly!","done":true}]