Spring Cloud Function dans Azure

Cet article explique comment générer, tester, déboguer et déployer une fonction Spring Cloud Java dans Azure Functions. Lorsque vous avez terminé, votre fonction s’exécute sur le plan de consommation et répond aux requêtes HTTP.

Conditions préalables

  • Un abonnement Azure. Si vous n’avez pas d’abonnement Azure , créez un compte gratuit avant de commencer.

Pour développer des fonctions à l’aide de Java, installez les outils suivants :

Importante

Définissez la JAVA_HOME variable d’environnement sur l’emplacement d’installation du JDK pour suivre ce guide de démarrage rapide.

Vérifiez que la version de vos outils de base est au moins 4.0.5455.

Ce que vous allez créer

Vous allez créer une fonction classique « Hello, World » qui s'exécute sur Azure Functions et qui est configurée avec Spring Cloud Function.

La fonction reçoit un User objet JSON, qui contient un nom d’utilisateur et renvoie un Greeting objet, qui contient le message d’accueil de cet utilisateur.

Le projet est disponible dans l'exemple de Spring Cloud Function dans Azure du azure-function-java-worker dépôt sur GitHub. Vous pouvez utiliser cet exemple directement si vous souhaitez voir le travail final décrit dans ce guide de démarrage rapide.

Créer un projet Maven

Créez un projet Maven vide et configurez-le avec Spring Cloud Function et Azure Functions.

Dans un dossier vide, créez un fichier pom.xml . Ensuite, copiez le contenu du fichier pom.xml de l'exemple de projet.

Remarque

Ce fichier utilise des dépendances Maven à partir de Spring Boot et de Spring Cloud Function. Il configure également les plug-ins Spring Boot et Azure Functions Maven.

Personnalisez quelques propriétés pour votre application :

  • <functionAppName>est le nom de votre fonction Azure.
  • <functionAppRegion>est le nom de la région Azure où vous déployez votre fonction.
  • <functionResourceGroup>est le nom du groupe de ressources Azure que vous utilisez.

Modifiez ces propriétés directement en haut du fichier pom.xml, comme indiqué dans l’exemple suivant :

    <properties>
        <java.version>11</java.version>

        <!-- Spring Boot start class. WARNING: correct class must be set -->
        <start-class>com.example.DemoApplication</start-class>

        <!-- customize those properties. WARNING: the functionAppName should be unique across Azure -->
        <azure.functions.maven.plugin.version>1.36.0</azure.functions.maven.plugin.version>
        <functionResourceGroup>my-spring-function-resource-group</functionResourceGroup>
        <functionAppServicePlanName>my-spring-function-service-plan</functionAppServicePlanName>
        <functionAppName>my-spring-function</functionAppName>
        <functionPricingTier>Y1</functionPricingTier>
        <functionAppRegion>eastus</functionAppRegion>
    </properties>

Créer des fichiers de configuration Azure

Créez un dossier src/main/resources et ajoutez-y les fichiers de configuration Azure Functions suivants.

host.json:

{
  "version": "2.0",
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[4.*, 5.2.0)"
  },
  "functionTimeout": "00:10:00"
}

local.settings.json:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "FUNCTIONS_WORKER_RUNTIME": "java",
    "FUNCTIONS_EXTENSION_VERSION": "~4",
    "AzureWebJobsDashboard": ""
  }
}

Créer des objets de domaine

Azure Functions peut recevoir et envoyer des objets au format JSON. Créez des objets Greeting et User qui représentent votre modèle de domaine. Vous pouvez créer des objets plus complexes avec plus de propriétés si vous souhaitez personnaliser ce guide de démarrage rapide.

Créez un dossier src/main/java/com/example/model et ajoutez les deux fichiers suivants :

User.java :

package com.example.model;

public class User {

    private String name;

    public User() {
    }

    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Greeting.java :

package com.example.model;

public class Greeting {

    private String message;

    public Greeting() {
    }

    public Greeting(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

Créer l’application Spring Boot

Cette application gère toute la logique métier et a accès à l’écosystème Spring Boot complet. Cette fonctionnalité offre deux avantages principaux sur une fonction Azure standard :

  • Il ne s’appuie pas sur les API Azure Functions. Vous pouvez donc facilement le porter vers d’autres systèmes. Par exemple, vous pouvez la réutiliser dans une application Spring Boot normale.
  • Vous pouvez utiliser toutes les annotations @Enable de Spring Boot pour ajouter de nouvelles fonctionnalités.

Dans le dossier src/main/java/com/example, créez le fichier suivant, qui est une application Spring Boot normale :

DemoApplication.java :

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(DemoApplication.class, args);
    }
}

Créez maintenant le fichier suivant dans le dossier src/main/java/com/example/hello. Ce code contient un composant Spring Boot qui représente la fonction que vous souhaitez exécuter :

Hello.java :

package com.example.hello;

import com.example.model.*;
import org.springframework.stereotype.Component;
import java.util.function.Function;

@Component
public class Hello implements Function<User, Greeting> {

    @Override
    public Greeting apply(User user) {
        return new Greeting("Hello, " + user.getName() + "!\n");
    }
}

Remarque

La fonction Hello est assez spécifique :

  • C’est un java.util.function.Function. Il contient la logique métier et utilise une API Java standard pour transformer un objet en un autre.
  • Comme il a l’annotation @Component , il s’agit d’un Spring Bean. Par défaut, son nom est identique à la classe, mais commence par un caractère minuscule : hello. Suivre cette convention de nommage est important si vous souhaitez créer d'autres fonctions dans votre application. Le nom doit correspondre au nom Azure Functions que vous créez dans la section suivante.

Créer la fonction Azure

Pour utiliser l’API Azure Functions complète, créez une fonction Azure qui délègue son exécution à la fonction Spring Cloud que vous avez créée à l’étape précédente.

Dans le dossier src/main/java/com/example/hello, créez le fichier de classe de fonction Azure suivant :

HelloHandler.java :

package com.example.hello;

import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.annotation.AuthorizationLevel;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.HttpTrigger;
import com.example.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Optional;

@Component
public class HelloHandler {

    @Autowired
    private Hello hello;

    @FunctionName("hello")
    public HttpResponseMessage execute(
        @HttpTrigger(name = "request", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<User>> request, ExecutionContext context) {
        User user = request.getBody()
                           .filter(u -> u.getName() != null)
                           .orElseGet(() -> new User(request.getQueryParameters().getOrDefault("name", "world")));
        context.getLogger().info("Greeting user name: " + user.getName());
        return request.createResponseBuilder(HttpStatus.OK)
                      .body(hello.apply(user))
                      .header("Content-Type", "application/json")
                      .build();
    }
}

Cette classe Java est une fonction Azure avec les fonctionnalités suivantes :

  • La classe a l’annotation @Component, donc c’est un Bean Spring.
  • Le nom de la fonction, tel que défini par l’annotation @FunctionName("hello"), est hello.
  • La classe implémente une vraie fonction Azure. Vous pouvez donc utiliser l’API Azure Functions complète ici.

Ajouter des tests unitaires

Cette étape est facultative, mais recommandée pour vérifier que l’application fonctionne correctement.

Créez un dossier src/test/java/com/example et ajoutez les tests JUnit suivants :

HelloTest.java :

package com.example;

import com.example.hello.Hello;
import com.example.model.Greeting;
import com.example.model.User;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class HelloTest {

    @Test
    public void test() {
        Greeting result = new Hello().apply(new User("foo"));
        assertThat(result.getMessage()).isEqualTo("Hello, foo!\n");
    }
}

Vous pouvez maintenant tester votre fonction Azure à l’aide de Maven :

mvn clean test

Exécuter la fonction localement

Avant de déployer votre application sur Azure Function, testez-la localement.

Tout d’abord, empaqueter votre application dans un fichier JAR :

mvn package

Maintenant que l’application est empaquetée, exécutez-la à l’aide du azure-functions plug-in Maven :

mvn azure-functions:run

La fonction Azure est désormais disponible sur votre hôte local, à l’aide du port 7071. Testez la fonction en l’envoyant une requête POST, avec un User objet au format JSON. Par exemple, utilisez cURL :

curl -X POST http://localhost:7071/api/hello -d "{\"name\":\"Azure\"}"

La fonction répond avec un Greeting objet, au format JSON :

{
  "message": "Hello, Azure!\n"
}

Voici une capture d’écran de la requête cURL en haut de l’écran et de la fonction Azure locale en bas :

fonction Azure s’exécutant localement

Déboguer la fonction localement

Les sections suivantes décrivent comment déboguer la fonction.

Déboguer à l’aide d’Intellij IDEA

Ouvrez le projet dans IntelliJ IDEA, puis créez une configuration d’exécution Remote JVM Debug pour vous y attacher. Pour plus d’informations, consultez le tutoriel sur le débogage distant.

Créer une configuration d’exécution Remote JVM Debug

Exécutez l’application avec la commande suivante :

mvn azure-functions:run -DenableDebug

Au démarrage de l’application, la sortie suivante s’affiche :

Worker process started and initialized.
Listening for transport dt_socket at address: 5005

Démarrez le débogage de projet dans IntelliJ IDEA. Vous voyez la sortie suivante :

Connected to the target VM, address: 'localhost:5005', transport: 'socket'

Marquez les points d’arrêt que vous souhaitez déboguer. IntelliJ IDEA entre en mode débogage après l’envoi d’une demande.

Déboguer à l’aide de Visual Studio Code

Ouvrez le projet dans Visual Studio Code, puis configurez le contenu de fichierlaunch.json suivant :

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "java",
            "name": "Attach to Remote Program",
            "request": "attach",
            "hostName": "127.0.0.1",
            "port": 5005
        }
    ]
}

Exécutez l’application avec la commande suivante :

mvn azure-functions:run -DenableDebug

Au démarrage de l’application, la sortie suivante s’affiche :

Worker process started and initialized.
Listening for transport dt_socket at address: 5005

Démarrez le débogage du projet dans Visual Studio Code, puis définissez les points d’arrêt que vous souhaitez utiliser pour le débogage. Visual Studio Code entre en mode débogage après l’envoi d’une demande. Pour plus d’informations, consultez Exécution et débogage de Java.

Déployer la fonction sur Azure Functions

À présent, vous allez publier la fonction Azure en production. N’oubliez pas que les propriétés <functionAppName>, <functionAppRegion>et <functionResourceGroup> que vous avez définies dans votre fichier pom.xml sont utilisées pour configurer votre fonction.

Remarque

Le plug-in Maven doit s’authentifier auprès d’Azure. Si Azure CLI est installé, utilisez az login avant de continuer.

Pour plus d’options d’authentification, consultez Authentification dans le azure-maven-plugins référentiel.

Exécutez Maven pour déployer automatiquement votre fonction :

mvn azure-functions:deploy

Accédez maintenant au portail Azure pour rechercher l’Function App qui a été créée.

Sélectionnez la fonction :

  • Dans la vue d’ensemble de la fonction, notez l’URL de la fonction.
  • Pour vérifier votre fonction en cours d’exécution, sélectionnez Diffusion des journaux dans le menu de navigation.

À présent, comme vous l’avez fait dans la section précédente, utilisez cURL pour accéder à la fonction en cours d’exécution, comme illustré dans l’exemple suivant. Veillez à remplacer your-function-name par votre nom de fonction réel.

curl https://your-function-name.azurewebsites.net/api/hello -d "{\"name\":\"Azure\"}"

Comme dans la section précédente, la fonction doit vous répondre avec un objet Greeting, toujours au format JSON :

{
  "message": "Hello, Azure!\n"
}

Félicitations, vous avez une fonction Spring Cloud en cours d’exécution sur Azure Functions ! Pour plus d’informations et des exemples de fonctions Spring Cloud, consultez les ressources suivantes :

Étapes suivantes

Pour en savoir plus sur Spring et Azure, passez au centre de documentation Spring sur Azure.