Démarrage rapide : Créer une fonction Java dans Azure à partir de la ligne de commande

Dans cet article, vous allez utiliser des outils en ligne de commande pour créer une fonction Java qui répond aux requêtes HTTP. Après avoir testé le code localement, vous le déployez dans l’environnement serverless d’Azure Functions.

Si Maven n’est pas votre outil de développement préféré, consultez nos tutoriels similaires destinés aux développeurs Java :

Le fait de suivre ce guide de démarrage rapide entraîne une faible dépense de quelques cents USD tout au plus dans votre compte Azure.

Configurer votre environnement local

Avant de commencer la lecture cet article, vous devez disposer des éléments suivants :

Vérification du prérequis

  • Dans une fenêtre de terminal ou de commande, exécutez func --version pour vérifier que vous disposez d’Azure Functions Core Tools version 4.x.

  • Exécutez az --version pour vérifier que vous disposez d’Azure CLI version 2.4 ou ultérieure.

  • Exécutez az login pour vous connecter à Azure et vérifier que l’abonnement est actif.

Créer un projet de fonction local

Dans Azure Functions, un projet de fonction est un conteneur pour une ou plusieurs fonctions qui répondent chacune à un déclencheur spécifique. Toutes les fonctions d’un projet partagent les mêmes configurations locale et d’hébergement. Dans cette section, vous créez un projet de fonction qui contient une seule fonction.

  1. Dans un dossier vide, exécutez la commande suivante pour générer le projet Functions à partir d’un archétype Maven.

    mvn archetype:generate -DarchetypeGroupId=com.microsoft.azure -DarchetypeArtifactId=azure-functions-archetype -DjavaVersion=8
    

    Important

    • Utilisez -DjavaVersion=11 si vous voulez que vos fonctions s’exécutent sur Java 11. Pour plus d’informations, consultez les versions Java.
    • La variable d’environnement JAVA_HOME doit être définie sur l’emplacement d’installation de la version appropriée du JDK pour que vous puissiez suivre cet article.
  2. Maven vous invite à entrer les valeurs nécessaires pour terminer la génération du projet lors du déploiement.
    Fournissez les valeurs suivantes à l’invite :

    Prompt Valeur Description
    groupId com.fabrikam Valeur qui identifie de façon unique votre projet parmi tous les projets, avec respect des règles de nommage de package pour Java.
    artifactId fabrikam-functions Valeur qui correspond au nom du fichier jar, sans numéro de version.
    version 1.0-SNAPSHOT Choisissez la valeur par défaut.
    package com.fabrikam Valeur qui correspond au package Java pour le code de fonction généré. Utilisez la valeur par défaut.
  3. Tapez Y ou appuyez sur Entrée pour confirmer.

    Maven crée les fichiers projet dans un nouveau dossier avec le nom d’artifactId, qui est fabrikam-functions dans cet exemple.

  4. Accédez au dossier du projet :

    cd fabrikam-functions
    

    Ce dossier contient divers fichiers pour le projet, notamment des fichiers config nommés local.settings.json et host.json. Dans la mesure où local.settings.json peut contenir des secrets téléchargés à partir d’Azure, le fichier est exclu du contrôle de code source par défaut dans le fichier .gitignore.

(Facultatif) Examiner le contenu du fichier

Si vous le souhaitez, vous pouvez passer à Exécuter la fonction localement et examiner le contenu du fichier plus tard.

Function.java

Function.java contient une méthode run qui reçoit des données de requête dans la variable request d’un objet HttpRequestMessage, doté de l’annotationHttpTrigger qui définit le comportement du déclencheur.

/**
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License. See License.txt in the project root for
 * license information.
 */

package com.functions;

import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.HttpMethod;
import com.microsoft.azure.functions.HttpRequestMessage;
import com.microsoft.azure.functions.HttpResponseMessage;
import com.microsoft.azure.functions.HttpStatus;
import com.microsoft.azure.functions.annotation.AuthorizationLevel;
import com.microsoft.azure.functions.annotation.FixedDelayRetry;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.HttpTrigger;

import java.util.Optional;

/**
 * Azure Functions with HTTP Trigger.
 */
public class Function {
    /**
     * This function listens at endpoint "/api/HttpExample". Two ways to invoke it using "curl" command in bash:
     * 1. curl -d "HTTP Body" {your host}/api/HttpExample
     * 2. curl "{your host}/api/HttpExample?name=HTTP%20Query"
     */
    @FunctionName("HttpExample")
    public HttpResponseMessage run(
            @HttpTrigger(
                name = "req",
                methods = {HttpMethod.GET, HttpMethod.POST},
                authLevel = AuthorizationLevel.ANONYMOUS)
                HttpRequestMessage<Optional<String>> request,
            final ExecutionContext context) {
        context.getLogger().info("Java HTTP trigger processed a request.");

        // Parse query parameter
        final String query = request.getQueryParameters().get("name");
        final String name = request.getBody().orElse(query);

        if (name == null) {
            return request.createResponseBuilder(HttpStatus.BAD_REQUEST).body("Please pass a name on the query string or in the request body").build();
        } else {
            return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build();
        }
    }

    public static int count = 1;

    /**
     * This function listens at endpoint "/api/HttpExampleRetry". The function is re-executed in case of errors until the maximum number of retries occur.
     * Retry policies: https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-error-pages?tabs=java
     */
    @FunctionName("HttpExampleRetry")
    @FixedDelayRetry(maxRetryCount = 3, delayInterval = "00:00:05")
    public HttpResponseMessage HttpExampleRetry(
        @HttpTrigger(
            name = "req",
            methods = {HttpMethod.GET, HttpMethod.POST},
            authLevel = AuthorizationLevel.ANONYMOUS)
            HttpRequestMessage<Optional<String>> request,
        final ExecutionContext context) throws Exception {
        context.getLogger().info("Java HTTP trigger processed a request.");

        if(count<3) {
            count ++;
            throw new Exception("error");
        }

        // Parse query parameter
        final String query = request.getQueryParameters().get("name");
        final String name = request.getBody().orElse(query);

        if (name == null) {
            return request.createResponseBuilder(HttpStatus.BAD_REQUEST).body("Please pass a name on the query string or in the request body").build();
        } else {
            return request.createResponseBuilder(HttpStatus.OK).body(name).build();
        }
    }

    /**
     * This function listens at endpoint "/api/HttpTriggerJavaVersion".
     * It can be used to verify the Java home and java version currently in use in your Azure function
     */
    @FunctionName("HttpTriggerJavaVersion")
    public static HttpResponseMessage HttpTriggerJavaVersion(
        @HttpTrigger(
            name = "req",
            methods = {HttpMethod.GET, HttpMethod.POST},
            authLevel = AuthorizationLevel.ANONYMOUS)
            HttpRequestMessage<Optional<String>> request,
        final ExecutionContext context
    ) {
        context.getLogger().info("Java HTTP trigger processed a request.");
        final String javaVersion = getJavaVersion();
        context.getLogger().info("Function - HttpTriggerJavaVersion" + javaVersion);
        return request.createResponseBuilder(HttpStatus.OK).body("HttpTriggerJavaVersion").build();
    }

    public static String getJavaVersion() {
        return String.join(" - ", System.getProperty("java.home"), System.getProperty("java.version"));
    }
}

Le message de réponse est généré par l’API HttpResponseMessage. Builder.

pom.xml

Les paramètres des ressources Azure créées pour héberger votre application sont définis dans l’élément de configuration du plug-in avec un groupId de com.microsoft.azure dans le fichier pom.xml généré. Par exemple, l’élément de configuration ci-dessous indique à un déploiement basé sur Maven de créer une application de fonction dans le groupe de ressources java-functions-group de la région westus. L’application de fonction elle-même s’exécute sur Windows hébergé dans le plan java-functions-app-service-plan qui, par défaut, est un plan de consommation serverless.

    </configuration>
</plugin>
<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.2</version>
</plugin>
<plugin>
    <groupId>com.microsoft.azure</groupId>
    <artifactId>azure-functions-maven-plugin</artifactId>
    <version>${azure.functions.maven.plugin.version}</version>
    <configuration>
        <!-- function app name -->
        <appName>${functionAppName}</appName>
        <!-- function app resource group -->
        <resourceGroup>${functionResourceGroup}</resourceGroup>
        <!-- function app service plan name -->
        <appServicePlanName>java-functions-app-service-plan</appServicePlanName>
        <!-- function app region-->
        <!-- refers https://github.com/microsoft/azure-maven-plugins/wiki/Azure-Functions:-Configuration-Details#supported-regions for all valid values -->
        <region>${functionAppRegion}</region>
        <!-- function pricingTier, default to be consumption if not specified -->
        <!-- refers https://github.com/microsoft/azure-maven-plugins/wiki/Azure-Functions:-Configuration-Details#supported-pricing-tiers for all valid values -->
        <!-- <pricingTier></pricingTier> -->

        <!-- Whether to disable application insights, default is false -->
        <!-- refers https://github.com/microsoft/azure-maven-plugins/wiki/Azure-Functions:-Configuration-Details for all valid configurations for application insights-->
        <!-- <disableAppInsights></disableAppInsights> -->
        <runtime>
            <!-- runtime os, could be windows, linux or docker-->
            <os>windows</os>
            <javaVersion>8</javaVersion>
            <!-- for docker function, please set the following parameters -->
            <!-- <image>[hub-user/]repo-name[:tag]</image> -->
            <!-- <serverId></serverId> -->
            <!-- <registryUrl></registryUrl>  -->
        </runtime>
        <appSettings>
            <property>
                <name>FUNCTIONS_EXTENSION_VERSION</name>
                <value>~3</value>
            </property>
        </appSettings>
    </configuration>
    <executions>
        <execution>
            <id>package-functions</id>

Vous pouvez modifier ces paramètres pour contrôler la façon dont les ressources sont créées dans Azure, par exemple en modifiant runtime.os pour passer de windows à linux avant le déploiement initial. Pour obtenir la liste complète des paramètres pris en charge par le plug-in Maven, consultez les détails de la configuration.

FunctionTest.java

L’archétype génère également un test unitaire pour votre fonction. Lorsque vous modifiez votre fonction pour ajouter des liaisons ou de nouvelles fonctions au projet, vous devez également modifier les tests dans le fichier FunctionTest.java.

Exécuter la fonction localement

  1. Exécutez votre fonction en démarrant l’hôte du runtime d’Azure Functions local à partir du dossier LocalFunctionProj :

    mvn clean package
    mvn azure-functions:run
    

    Vers la fin de la sortie, les lignes suivantes doivent s’afficher :

     ...
    
     Now listening on: http://0.0.0.0:7071
     Application started. Press Ctrl+C to shut down.
    
     Http Functions:
    
             HttpExample: [GET,POST] http://localhost:7071/api/HttpExample
     ...
    
     

    Notes

    Si HttpExample n’apparaît pas comme indiqué ci-dessus, cela signifie probablement que vous avez démarré l’hôte à partir d’un emplacement autre que le dossier racine du projet. Dans ce cas, utilisez Ctrl+C pour arrêter l’hôte, accédez au dossier racine du projet, puis réexécutez la commande précédente.

  2. Copiez dans un navigateur l’URL de votre fonction HttpExample à partir de cette sortie, puis ajoutez la chaîne de requête ?name=<YOUR_NAME> pour obtenir une URL complète semblable à http://localhost:7071/api/HttpExample?name=Functions. Le navigateur doit afficher un message qui renvoie la valeur de votre chaîne de requête. Le terminal dans lequel vous avez démarré votre projet affiche également une sortie de journal quand vous effectuez des requêtes.

  3. Quand vous avez terminé, utilisez Ctrl+C, puis choisissez y pour arrêter l’hôte Functions.

Déployer le projet de fonction sur Azure

Une application de fonction et les ressources associées sont créées dans Azure lors du déploiement initial de votre projet Functions. Les paramètres des ressources Azure créées pour héberger votre application sont définis dans le fichier pom.xml. Dans cet article, vous allez accepter les valeurs par défaut.

Conseil

Pour créer une application de fonction s’exécutant sur Linux au lieu de Windows, changez l’élément runtime.os dans le fichier pom.xml en remplaçant windows par linux. L’exécution de Linux dans un plan de consommation est prise en charge dans ces régions. Des applications s’exécutant sur Linux et des applications s’exécutant sur Windows ne peuvent pas se côtoyer dans le même groupe de ressources.

  1. Avant d’effectuer le déploiement, connectez-vous à votre abonnement Azure en utilisant Azure CLI ou Azure PowerShell.

    az login
    

    La commande az login vous connecte à votre compte Azure.

  2. Utilisez la commande suivante pour déployer votre projet vers une nouvelle application de fonction.

    mvn azure-functions:deploy
    

    Cette commande crée les ressources suivantes dans Azure :

    • Groupe de ressources. Nommé en tant que java-functions-group.
    • Compte de stockage. Requis par les fonctions. Le nom est généré de façon aléatoire en fonction des exigences du nom de compte de stockage.
    • Plan d’hébergement. Hébergement serverless pour votre application de fonction dans la région westus. Le nom est java-functions-app-service-plan.
    • Application de fonction. Une application de fonction est l’unité de déploiement et d’exécution de vos fonctions. Le nom est généré de façon aléatoire, en fonction de votre artifactId auquel est ajouté un numéro généré de façon aléatoire.

    Le déploiement empaquette les fichiers du projet et les déploie dans la nouvelle application de fonction à l’aide du déploiement zip. Le code s’exécute à partir du package de déploiement dans Azure.

Appeler la fonction sur Azure

Dans la mesure où votre fonction utilise un déclencheur HTTP, vous l’appelez en adressant une requête HTTP à son URL dans le navigateur ou à l’aide d’un outil semblable à curl.

Copiez l’URL d’appel complète affichée au sein de la sortie de la commande de publication dans la barre d’adresse d’un navigateur, en ajoutant le paramètre de requête ?name=Functions. Le navigateur doit afficher une sortie similaire à celle générée au moment de l’exécution locale de la fonction.

Sortie de la fonction exécutée sur Azure dans un navigateur

Exécutez la commande suivante pour afficher les journaux de streaming en temps quasi-réel :

func azure functionapp logstream <APP_NAME> 

Dans une fenêtre de terminal distincte ou dans le navigateur, appelez à nouveau la fonction distante. Un journal détaillé de l’exécution de la fonction dans Azure est affiché dans le terminal.

Nettoyer les ressources

Si vous passez à l’étape suivante, qui consiste à ajouter une liaison de sortie de file d’attente Stockage Azure, gardez toutes vos ressources en place, car vous allez tirer parti de ce que vous avez déjà fait.

Sinon, utilisez la commande suivante pour supprimer le groupe de ressources et toutes les ressources qu’il contient afin d’éviter les coûts supplémentaires.

az group delete --name java-functions-group

Étapes suivantes