Connecter Azure Functions à Stockage Azure à l’aide des outils en ligne de commande

Dans cet article, vous intégrez une file d’attente Stockage Azure à la fonction et au compte de stockage que vous avez créés dans le guide de démarrage rapide précédent. Vous effectuez cette intégration à l’aide d’une liaison de sortie qui écrit les données d’une requête HTTP dans un message en file d’attente. Le fait de suivre les instructions de cet article n’entraîne aucun coût supplémentaire au-delà des quelques cents USD du guide de démarrage rapide précédent. Pour en savoir plus sur les liaisons, consultez Concepts des déclencheurs et liaisons Azure Functions.

Remarque

Cet article prend uniquement en charge Node.js v3 pour Functions.

Configurer votre environnement local

Avant de commencer, vous devez terminer l’article Démarrage rapide : Créer un projet Azure Functions à partir de la ligne de commande. Si vous avez déjà nettoyé les ressources à la fin de cet article, suivez à nouveau les étapes pour recréer l’application Functions et les ressources associées dans Azure.

Avant de commencer, vous devez terminer l’article Démarrage rapide : Créer un projet Azure Functions à partir de la ligne de commande. Si vous avez déjà nettoyé les ressources à la fin de cet article, suivez à nouveau les étapes pour recréer l’application Functions et les ressources associées dans Azure.

Avant de commencer, vous devez terminer l’article Démarrage rapide : Créer un projet Azure Functions à partir de la ligne de commande. Si vous avez déjà nettoyé les ressources à la fin de cet article, suivez à nouveau les étapes pour recréer l’application Functions et les ressources associées dans Azure.

Avant de commencer, vous devez terminer l’article Démarrage rapide : Créer un projet Azure Functions à partir de la ligne de commande. Si vous avez déjà nettoyé les ressources à la fin de cet article, suivez à nouveau les étapes pour recréer l’application Functions et les ressources associées dans Azure.

Avant de commencer, vous devez terminer l’article Démarrage rapide : Créer un projet Azure Functions à partir de la ligne de commande. Si vous avez déjà nettoyé les ressources à la fin de cet article, suivez à nouveau les étapes pour recréer l’application Functions et les ressources associées dans Azure.

Avant de commencer, vous devez terminer l’article Démarrage rapide : Créer un projet Azure Functions à partir de la ligne de commande. Si vous avez déjà nettoyé les ressources à la fin de cet article, suivez à nouveau les étapes pour recréer l’application Functions et les ressources associées dans Azure.

Récupérer la chaîne de connexion de Stockage Azure

Vous avez créé auparavant un compte de stockage Azure que l’application de fonction va utiliser. La chaîne de connexion pour ce compte est stockée de manière sécurisée dans les paramètres d’application au sein d’Azure. En téléchargeant le paramètre dans le fichier local.settings.json, vous pouvez utiliser cette connexion pour écrire dans une file d’attente de stockage du même compte au moment de l’exécution locale de la fonction.

  1. À partir de la racine du projet, exécutez la commande suivante, en remplaçant <APP_NAME> par le nom de votre application de fonction créée à l’étape précédente. Cette commande remplace toutes les valeurs existantes dans le fichier.

    func azure functionapp fetch-app-settings <APP_NAME>
    
  2. Ouvrez le fichier local.settings.json et recherchez la valeur nommée AzureWebJobsStorage, qui est la chaîne de connexion du compte de stockage. Vous utilisez le nom AzureWebJobsStorage et la chaîne de connexion dans d’autres sections de cet article.

Important

Dans la mesure où le fichier local.settings.json contient des secrets téléchargés à partir d’Azure, excluez toujours ce fichier du contrôle de code source. Le fichier .gitignore créé avec un projet Functions local exclut le fichier par défaut.

Inscrire des extensions de liaison

À l’exception des déclencheurs HTTP et de minuteur, les liaisons sont implémentées en tant que packages d’extension. Exécutez la commande dotnet add package suivante dans la fenêtre de terminal pour ajouter le package d’extension de Stockage à votre projet.

dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Storage.Queues --prerelease

Vous pouvez maintenant ajouter la liaison de sortie de stockage à votre projet.

Ajouter une définition de liaison de sortie à la fonction

Bien qu’une fonction ne puisse avoir qu’un seul déclencheur, elle peut avoir plusieurs liaisons d’entrée et de sortie. Ainsi, vous pouvez vous connecter à d’autres services et ressources Azure sans avoir à écrire du code d’intégration personnalisé.

Vous déclarez ces liaisons dans le fichier function.json situé dans le dossier de la fonction. Compte tenu du guide de démarrage rapide précédent, votre fichier function.json situé dans le dossier HttpExample contient deux liaisons dans la collection bindings :

Lors de l’utilisation du modèle de programmation Python v2, les attributs de liaison sont définis directement dans le fichier function_app.py comme éléments décoratifs. Dans le guide de démarrage rapide précédent, votre fichier function_app.py contient déjà une liaison basée sur un élément décoratif :

import azure.functions as func
import logging

app = func.FunctionApp()

@app.function_name(name="HttpTrigger1")
@app.route(route="hello", auth_level=func.AuthLevel.ANONYMOUS)

L’élément décoratif route ajoute la liaison HttpTrigger et HttpOutput à la fonction, ce qui permet à votre fonction d’être déclenchée lorsque les requêtes HTTP atteignent l’itinéraire spécifié.

Pour écrire dans une file d’attente stockage Azure à partir de cette fonction, ajoutez l’élément décoratif queue_output à votre code de fonction :

@app.queue_output(arg_name="msg", queue_name="outqueue", connection="AzureWebJobsStorage")

Dans l’élément décoratif, arg_name identifie le paramètre de liaison référencé dans votre code. queue_name est le nom de la file d’attente sur laquelle la liaison écrit et connection est le nom d’un paramètre d’application qui contient la chaîne de connexion pour le compte de stockage. Dans les démarrages rapides, vous utilisez le même compte de stockage que l’application de fonction, qui se trouve dans le paramètre AzureWebJobsStorage (du fichier local.settings.json). Si la propriété queue_name n’existe pas, la liaison la crée lors de la première utilisation.

"bindings": [
    {
        "authLevel": "function",
        "type": "httpTrigger",
        "direction": "in",
        "name": "req",
        "methods": [
            "get",
            "post"
        ]
    },
    {
        "type": "http",
        "direction": "out",
        "name": "res"
    }
]
"bindings": [
  {
    "authLevel": "function",
    "type": "httpTrigger",
    "direction": "in",
    "name": "Request",
    "methods": [
      "get",
      "post"
    ]
  },
  {
    "type": "http",
    "direction": "out",
    "name": "Response"
  }
]

La deuxième liaison dans la collection est nommée res. Cette liaison http est une liaison de sortie (out) qui est utilisée pour écrire la réponse HTTP.

Pour écrire dans une file d’attente Stockage Azure à partir de cette fonction, ajoutez une liaison out de type queue nommée msg, comme indiqué dans le code ci-dessous :

    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },
    {
      "type": "queue",
      "direction": "out",
      "name": "msg",
      "queueName": "outqueue",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

La deuxième liaison dans la collection est nommée res. Cette liaison http est une liaison de sortie (out) qui est utilisée pour écrire la réponse HTTP.

Pour écrire dans une file d’attente Stockage Azure à partir de cette fonction, ajoutez une liaison out de type queue nommée msg, comme indiqué dans le code ci-dessous :

    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "Request",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "Response"
    },
    {
      "type": "queue",
      "direction": "out",
      "name": "msg",
      "queueName": "outqueue",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

Dans ce cas, msg est fourni à la fonction en tant qu’argument de sortie. Pour un type queue, vous devez également spécifier le nom de la file d’attente dans queueName et fournir le nom de la connexion Stockage Azure (à partir du fichier local.settings.json) dans connection.

Dans un projet C#, les liaisons sont définies comme des attributs de liaison sur la méthode de fonction. Les définitions spécifiques varient selon que votre application s’exécute in-process (bibliothèque de classes C#) ou dans un processus Worker isolé.

Ouvrez le fichier projet HttpExample.cs et ajoutez la classe MultiResponse suivante :

public class MultiResponse
{
    [QueueOutput("outqueue",Connection = "AzureWebJobsStorage")]
    public string[] Messages { get; set; }
    public HttpResponseData HttpResponse { get; set; }
}

La classe MultiResponse vous permet d’écrire dans une file d’attente de stockage nommée outqueue et dans un message de réussite HTTP. Plusieurs messages peuvent être envoyés à la file d’attente comme l’attribut QueueOutput est appliqué à un tableau de chaînes.

La propriété Connection définit la chaîne de connexion pour le compte de stockage. Dans ce cas, vous pourriez omettre Connection, car vous utilisez déjà le compte de stockage par défaut.

Dans un projet Java, les liaisons sont définies comme annotations de liaison sur la méthode de fonction. Le fichier function.json est ensuite généré automatiquement en fonction de ces annotations.

Accédez à l’emplacement de votre code de fonction sous src/main/java, ouvrez le fichier projet Function.java, puis ajoutez le paramètre suivant à la définition de la méthode run :

@QueueOutput(name = "msg", queueName = "outqueue", connection = "AzureWebJobsStorage") OutputBinding<String> msg

Le paramètre msg est un type OutputBinding<T>, qui représente une collection de chaînes. Ces chaînes sont écrites sous forme de messages dans une liaison de sortie lorsque la fonction se termine. Dans ce cas, la sortie est une file d’attente de stockage nommée outqueue. La chaîne de connexion pour le compte de stockage est définie par la méthode connection. Au lieu de passer la chaîne de connexion proprement dite, vous passez le paramètre d’application qui contient la chaîne de connexion du compte de stockage.

La définition de la méthode run doit maintenant être semblable à celle de l’exemple suivant :

@FunctionName("HttpTrigger-Java")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.FUNCTION)  
        HttpRequestMessage<Optional<String>> request, 
        @QueueOutput(name = "msg", queueName = "outqueue", connection = "AzureWebJobsStorage") 
        OutputBinding<String> msg, final ExecutionContext context) {
    ...
}

Pour plus d’informations sur les détails des liaisons, consultez Concepts des déclencheurs et liaisons Azure Functions et Configuration de la sortie de la file d’attente.

Ajouter du code pour utiliser la liaison de sortie

Avec la liaison de file d’attente définie, vous pouvez à présent mettre à jour votre fonction pour qu’elle reçoive le paramètre de sortie msg et écrive des messages dans la file d’attente.

Mettez à jour le fichier HttpExample\function_app.py de manière à ce qu’il corresponde au code suivant, en ajoutant le paramètre msg à la définition de fonction et msg.set(name) sous l’instruction if name: :

import azure.functions as func
import logging

app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)

@app.route(route="HttpExample")
@app.queue_output(arg_name="msg", queue_name="outqueue", connection="AzureWebJobsStorage")
def HttpExample(req: func.HttpRequest, msg: func.Out [func.QueueMessage]) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    name = req.params.get('name')
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    if name:
        msg.set(name)
        return func.HttpResponse(f"Hello, {name}. This HTTP triggered function executed successfully.")
    else:
        return func.HttpResponse(
             "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.",
             status_code=200
        )

Le paramètre msg est une instance de la azure.functions.Out class. La méthode set écrit un message de type chaîne dans la file d’attente. Dans ce cas, il s’agit du paramètre name transmis à la fonction dans la chaîne de requête de l’URL.

Ajoutez le code qui utilise l’objet de liaison de sortie msg sur context.bindings pour créer un message de file d’attente. Ajoutez ce code avant l’instruction context.res.

// Add a message to the Storage queue,
// which is the name passed to the function.
context.bindings.msg = (req.query.name || req.body.name);

À ce stade, votre fonction doit ressembler à ce qui suit :

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');

    if (req.query.name || (req.body && req.body.name)) {
        // Add a message to the Storage queue,
        // which is the name passed to the function.
        context.bindings.msg = (req.query.name || req.body.name);
        context.res = {
            // status: 200, /* Defaults to 200 */
            body: "Hello " + (req.query.name || req.body.name)
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }
};

Ajoutez le code qui utilise l’objet de liaison de sortie msg sur context.bindings pour créer un message de file d’attente. Ajoutez ce code avant l’instruction context.res.

context.bindings.msg = name;

À ce stade, votre fonction doit se présenter comme suit :

import { AzureFunction, Context, HttpRequest } from "@azure/functions"

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
    context.log('HTTP trigger function processed a request.');
    const name = (req.query.name || (req.body && req.body.name));

    if (name) {
        // Add a message to the storage queue, 
        // which is the name passed to the function.
        context.bindings.msg = name; 
        // Send a "hello" response.
        context.res = {
            // status: 200, /* Defaults to 200 */
            body: "Hello " + (req.query.name || req.body.name)
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }
};

export default httpTrigger;

Ajoutez du code qui utilise l’applet de commande Push-OutputBinding pour écrire du texte dans la file d’attente à l’aide de la liaison de sortie msg. Ajoutez ce code avant de définir l’état OK dans l’instruction if.

$outputMsg = $name
Push-OutputBinding -name msg -Value $outputMsg

À ce stade, votre fonction doit se présenter comme suit :

using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

# Interact with query parameters or the body of the request.
$name = $Request.Query.Name
if (-not $name) {
    $name = $Request.Body.Name
}

if ($name) {
    # Write the $name value to the queue, 
    # which is the name passed to the function.
    $outputMsg = $name
    Push-OutputBinding -name msg -Value $outputMsg

    $status = [HttpStatusCode]::OK
    $body = "Hello $name"
}
else {
    $status = [HttpStatusCode]::BadRequest
    $body = "Please pass a name on the query string or in the request body."
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = $status
    Body = $body
})

Remplacez la classe existante HttpExample par le code suivant :

    [Function("HttpExample")]
    public static MultiResponse Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
        FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger("HttpExample");
        logger.LogInformation("C# HTTP trigger function processed a request.");

        var message = "Welcome to Azure Functions!";

        var response = req.CreateResponse(HttpStatusCode.OK);
        response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
        response.WriteString(message);

        // Return a response to both HTTP trigger and storage output binding.
        return new MultiResponse()
        {
            // Write a single message.
            Messages = new string[] { message },
            HttpResponse = response
        };
    }
}

À présent, vous pouvez utiliser le nouveau paramètre msg pour écrire dans la liaison de sortie à partir de votre code de fonction. Ajoutez la ligne de code suivante avant la réponse de réussite pour ajouter la valeur de name à la liaison de sortie msg.

msg.setValue(name);

Lorsque vous utilisez une liaison de sortie, vous n’avez pas besoin de recourir au code du Kit de développement logiciel (SDK) Stockage Azure pour l’authentification, l’obtention d’une référence de file d’attente ou l’écriture de données. La liaison de sortie de file d’attente et le runtime Functions effectuent ces tâches.

Votre méthode run doit maintenant être semblable à celle de l’exemple suivant :

public HttpResponseMessage run(
        @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) 
        HttpRequestMessage<Optional<String>> request, 
        @QueueOutput(name = "msg", queueName = "outqueue", 
        connection = "AzureWebJobsStorage") OutputBinding<String> msg, 
        final ExecutionContext context) {
    context.getLogger().info("Java HTTP trigger processed a request.");

    // Parse query parameter
    String query = request.getQueryParameters().get("name");
    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 {
        // Write the name to the message queue. 
        msg.setValue(name);

        return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build();
    }
}

Mettre à jour les tests

Étant donné que l’archétype crée également un ensemble de tests, vous devez mettre à jour ces tests pour gérer le nouveau paramètre msg dans la signature de méthode run.

Accédez à l’emplacement de votre code de test sous src/test/Java, ouvrez le fichier projet Function.java et remplacez la ligne de code située sous //Invoke par le code suivant :

@SuppressWarnings("unchecked")
final OutputBinding<String> msg = (OutputBinding<String>)mock(OutputBinding.class);
final HttpResponseMessage ret = new Function().run(req, msg, context);

Notez que vous n’avez pas besoin d’écrire du code pour l’authentification, l’obtention d’une référence de file d’attente ou l’écriture de données. Toutes ces tâches d’intégration sont prises en charge de manière pratique dans le runtime d’Azure Functions et la liaison de sortie de file d’attente.

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 :

    func start
    

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

    Screenshot of terminal window output when running function locally.

    Remarque

    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 l’URL de votre fonction HTTP à partir de cette sortie dans un navigateur et 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 de réponse 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é, appuyez sur Ctrl + C, puis tapez y pour arrêter l’hôte Functions.

Conseil

Au démarrage, l’hôte télécharge et installe l’extension de liaison de stockage et d’autres extensions de liaison Microsoft. Cette installation a lieu, car les extensions de liaison sont activées par défaut dans le fichier host.json avec les propriétés suivantes :

{
    "version": "2.0",
    "extensionBundle": {
        "id": "Microsoft.Azure.Functions.ExtensionBundle",
        "version": "[1.*, 2.0.0)"
    }
}

Si vous rencontrez des erreurs liées aux extensions de liaison, vérifiez que les propriétés ci-dessus sont présentes dans host.json.

Afficher le message dans la file d’attente Stockage Azure

Vous pouvez voir la file d’attente dans le portail Azure ou dans l’Explorateur Stockage Microsoft Azure. Vous pouvez également voir la file d’attente dans Azure CLI, en effectuant les étapes suivantes :

  1. Ouvrez le fichier local.setting.json du projet de fonction, et copiez la valeur de la chaîne de connexion. Dans une fenêtre de terminal ou une fenêtre Commande, exécutez la commande suivante pour créer une variable d’environnement nommée AZURE_STORAGE_CONNECTION_STRING, en collant votre chaîne de connexion spécifique à la place de <MY_CONNECTION_STRING>. (Cette variable d’environnement signifie que vous n’avez pas besoin de fournir la chaîne de connexion pour les prochaines commandes à l’aide de l’argument --connection-string.)

    export AZURE_STORAGE_CONNECTION_STRING="<MY_CONNECTION_STRING>"
    
  2. (Facultatif) Utilisez la commande az storage queue list pour voir les files d’attente de stockage dans votre compte. La sortie de cette commande doit inclure une file d’attente nommée outqueue, qui a été créée au moment où la fonction a écrit son premier message dans cette file d’attente.

    az storage queue list --output tsv
    
  3. Utilisez la commande az storage message get pour lire le message de cette file d'attente, qui devrait être la valeur que vous avez fournie lors du test de la fonction plus tôt. La commande lit et supprime le premier message dans la file d’attente.

    echo `echo $(az storage message get --queue-name outqueue -o tsv --query '[].{Message:content}') | base64 --decode`
    

    Étant donné que le corps du message stocké est encodé en base64, le message doit être décodé préalablement à son affichage. Une fois que vous avez exécuté az storage message get, le message est supprimé de la file d’attente. S’il n’y avait qu’un seul message dans outqueue, vous ne récupérez pas de message à la deuxième exécution de cette commande et vous obtenez une erreur à la place.

Redéployer le projet sur Azure

Une fois que vous avez vérifié localement que la fonction a écrit un message dans la file d’attente Stockage Azure, vous pouvez redéployer votre projet pour mettre à jour le point de terminaison exécuté sur Azure.

Dans le dossier LocalFunctionsProj, utilisez la commande func azure functionapp publish pour redéployer le projet, en remplaçant <APP_NAME> par le nom de votre application.

func azure functionapp publish <APP_NAME>

Dans le dossier de projet local, utilisez la commande Maven suivante pour republier votre projet :

mvn azure-functions:deploy

Vérifier dans Azure

  1. Comme dans le guide de démarrage rapide précédent, utilisez un navigateur ou CURL pour tester la fonction redéployée.

    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 identique à celle générée au moment de l’exécution locale de la fonction.

  2. Examinez à nouveau la file d’attente de stockage, comme indiqué dans la section précédente, pour vérifier qu’elle contient le nouveau message écrit.

Nettoyer les ressources

Quand vous avez terminé, 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 AzureFunctionsQuickstart-rg

Étapes suivantes

Vous avez mis à jour votre fonction déclenchée via HTTP pour écrire des données dans une file d’attente de stockage. Pour en savoir plus sur le développement de fonctions à partir de la ligne de commande avec Core Tools et Azure CLI, consultez maintenant ces articles :