Exercise : Ajouter une logique à l’application de fonction

Effectué

Reprenons notre exemple d’engrenage et ajoutons la logique au service de température. Plus précisément, nous allons recevoir les données d’une requête HTTP.

Conditions de la fonction

Tout d’abord, nous devons définir certaines conditions pour notre logique :

  • Les températures comprises entre 0 et 25 degrés doivent être marquées avec OK.
  • Les températures comprises entre 25 et 50 degrés doivent être marquées avec ATTENTION.
  • Les températures supérieures à 50 degrés doivent indiquer DANGER.

Ajouter une fonction à votre application de fonction

Comme nous l’avons vu dans l’unité précédente, Azure fournit des modèles qui facilitent la génération de fonctions. Dans cette unité, vous utilisez le modèle HttpTrigger pour implémenter le service de température.

  1. Dans l’exercice précédent, vous avez déployé votre application de fonction et l’avez ouverte. Si elle n’est pas déjà ouverte, vous pouvez l’ouvrir à partir de la page d’accueil en sélectionnant Toutes les ressources, puis sélectionnez votre application de fonction dont le nom ressemble à escalator-functions-xxx.

  2. Dans l’écran Application de fonction, sous l’onglet Fonctions, sélectionnez Créer dans le portail Azure. Le volet Créer une fonction s’affiche.

  3. Sous Sélectionner un modèle, sélectionnez Déclencheur HTTP.

  1. Sélectionnez Create (Créer). HttpTrigger1 est créé et s’affiche dans le volet Fonction HttpTrigger1.

  2. Dans le menu Développeur à gauche, sélectionnez Code + test. L’éditeur de code s’ouvre et affiche le contenu du fichier de code index.js de votre fonction. Le code par défaut que le modèle HTTP a généré est montré dans l’extrait de code suivant.

    module.exports = async function (context, req) {
        context.log('JavaScript HTTP trigger function processed a request.');
    
        const name = (req.query.name || (req.body && req.body.name));
        const responseMessage = name
            ? "Hello, " + name + ". This HTTP triggered function executed successfully."
            : "This HTTP triggered function executed successfully. Pass a name on the query string or in the request body for a personalized response.";
    
        context.res = {
            // status: 200, /* Defaults to 200 */
            body: responseMessage
        };
    }
    

    Votre fonction s’attend à ce qu’un nom soit passé via la chaîne de requête HTTP ou dans le cadre du corps de la requête. La fonction répond en retournant le message Hello, <name>. Cette fonction déclenchée par HTTP s’est correctement exécutée., répétant ainsi le nom qui a été envoyé dans la demande.

    Dans la liste déroulante de fichiers sources, sélectionnez function.json pour voir la configuration de la fonction, qui doit ressembler au code suivant.

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

    Ce fichier de configuration déclare que la fonction s’exécute quand elle reçoit une requête HTTP. La liaison de sortie déclare que la réponse est envoyée comme réponse HTTP.

  1. Dans la section Détails du modèle, dans le champ Nouvelle fonction, entrez DriveGearTemperatureService. Conservez le Niveau d’autorisation défini sur Fonction, puis sélectionnez Créer pour créer la fonction. Le volet Vue d’ensemble de votre fonction DriveGearTemperatureService s’affiche.

  2. Dans le menu Fonction, sélectionnez Code + Test. L’éditeur de code s’ouvre avec le contenu du fichier de code run.ps1. Le code par défaut que le modèle a généré automatiquement est repris dans l’extrait de code suivant.

    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
    }
    
    $body = "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
    
    if ($name) {
        $body = "Hello, $name. This HTTP triggered function executed successfully."
    }
    
    # Associate values to output bindings by calling 'Push-OutputBinding'.
    Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
        StatusCode = [HttpStatusCode]::OK
        Body = $body
    })
    

    Notre fonction s’attend à ce qu’un nom soit transmis par le biais de la chaîne de requête HTTP ou en tant que partie intégrante du corps de la demande. Les fonctions HTTP doivent générer une réponse en écrivant dans leur liaison de sortie, qui est établie dans PowerShell Functions avec l’applet de commande Push-OutputBinding. Cette fonction retourne le message Hello $name, répétant ainsi le nom qui a été envoyé dans la demande.

  3. Dans la liste déroulante source, sélectionnez function.json pour afficher la configuration de la fonction, qui doit se présenter de la façon suivante.

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

    Cette configuration déclare que la fonction s’exécute quand elle reçoit une requête HTTP. La liaison de sortie déclare que la réponse est envoyée comme réponse HTTP.

Tester la fonction

Conseil

cURL est un outil de ligne de commande qui permet d’envoyer ou de recevoir des fichiers. Il est intégré à Linux, macOS et Windows 10 et peut être téléchargé pour la plupart des autres systèmes d’exploitation. cURL prend en charge de nombreux protocoles comme HTTP, HTTPS, FTP, FTPS, SFTP, LDAP, TELNET, SMTP, POP3, etc. Pour plus d'informations, consultez les liens suivants :

Pour tester la fonction, vous pouvez envoyer une requête HTTP à l’URL de la fonction en utilisant cURL sur la ligne de commande.

  1. Développez le cadre Journaux en bas du volet de la fonction de déclencheur. Sélectionnez Journaux du système de fichiers dans la liste déroulante en haut du cadre Journaux. Le cadre des journaux doit commencer à accumuler des notifications de trace toutes les minutes.

  2. Pour rechercher l’URL de point de terminaison de la fonction, à partir de la barre de commandes, sélectionnez Obtenir l’URL de la fonction, comme illustré dans l’image suivante. Enregistrez ce lien en sélectionnant l’icône Copier dans le Presse-papiers à la fin de l’URL. Stockez ce lien dans le Bloc-notes ou dans une application similaire pour une utilisation ultérieure.

    Screenshot of the Azure portal showing the function editor, with the Get function URL button highlighted.

  3. Ouvrez une invite de commandes et exécutez cURL pour envoyer une requête HTTP à l’URL de la fonction. N’oubliez pas d’utiliser l’URL que vous avez copiée à l’étape précédente.

    curl "<your-https-url>"
    

    Conseil

    Vous devez placer l’URL entre guillemets pour éviter les problèmes liés aux caractères spéciaux dans l’URL.
    Si vous êtes sur Windows, exécutez cURL à partir de l’invite de commandes. PowerShell a une commande curl, mais il s’agit d’un alias pour Invoke-WebRequest, qui n’est pas identique à cURL.

    La réponse doit ressembler à celle-ci :

    This HTTP triggered function executed successfully. Pass a name on the query string or in the request body for a personalized response.
    

    Passez maintenant un nom dans la requête. Pour ce faire, vous devez ajouter un paramètre de chaîne de requête nommé name à l’URL. L’exemple suivant ajoute le paramètre de chaîne de requête name=Azure.

    curl "<your-https-url>&name=Azure"
    

    La réponse doit ressembler à celle-ci :

    Hello, Azure. This HTTP triggered function executed successfully.
    

    La fonction s’est exécutée correctement et a retourné le nom que vous avez transmis dans la requête.

Sécuriser les déclencheurs HTTP

Les déclencheurs HTTP vous permettent d’utiliser des clés API pour bloquer les appelants inconnus en imposant la fourniture d’une clé dans le cadre de la requête. Quand vous créez une fonction, vous sélectionnez le niveau d’autorisation. Par défaut, il est défini sur Fonction, ce qui nécessite une clé API propre à la fonction. Il peut également être défini sur Admin afin d’utiliser une clé « maîtresse » globale, ou Anonyme pour indiquer qu’aucune clé n’est requise. Vous pouvez aussi modifier le niveau d’autorisation via les propriétés de la fonction après que celle-ci a été créée.

Dans la mesure où vous avez spécifié Function quand vous avez créé cette fonction, vous devez fournir la clé quand vous envoyez la requête HTTP. Vous pouvez l’envoyer en tant que paramètre de chaîne de requête nommé code. Vous pouvez également utiliser la méthode préférée et la transmettre en tant qu’en-tête HTTP nommé x-functions-key.

  1. Pour rechercher la fonction et les clés principales, dans le menu Application de fonction, sous Développeur, sélectionnez Clés de fonction. Le volet Clés de fonction pour votre fonction s’ouvre.

  2. Par défaut, la valeur de la clé de fonction est masquée. Affichez la valeur de clé de fonction par défaut en sélectionnant Afficher la valeur. Copiez le contenu du champ Valeur dans le Presse-papiers, puis stockez cette clé dans le Bloc-notes ou une application similaire pour l’utiliser ultérieurement.

    Screenshot showing the Function Keys pane with the revealed function key highlighted.

  3. Pour tester la fonction avec la clé de fonction, ouvrez une invite de commandes et exécutez cURL pour envoyer une requête HTTP à l’URL de la fonction. Remplacez <your-function-key> par la valeur de clé de fonction que vous avez enregistrée, et remplacez <your-https-url> par l’URL de votre fonction.

    curl --header "Content-Type: application/json" --header "x-functions-key: <your-function-key>" --request POST --data "{\"name\": \"Azure Function\"}" <your-https-url>
    
  4. Passez en revue la commande cURL et vérifiez que ses valeurs sont les suivantes :

    • Elle a ajouté une valeur d’en-tête Content-Type de type application/json.
    • Elle a passé la clé de fonction comme valeur d’en-tête x-functions-key.
    • Elle a utilisé une demande POST.
    • Elle a passé la fonction Azure avec l’URL de votre fonction.
  5. Consultez les journaux.

    Le volet Code + Test doit ouvrir une session affichant la sortie du fichier journal (vérifiez que Journaux du système de fichiers est sélectionné dans la liste déroulante en haut du volet Journaux). Le fichier journal est mis à jour avec l’état de votre demande, qui doit ressembler à ceci :

```output
2022-02-16T22:34:10.473 [Information] Executing 'Functions.HttpTrigger1' (Reason='This function was programmatically called via the host APIs.', Id=4f503b35-b944-455e-ba02-5205f9e8b47a)
2022-02-16T22:34:10.539 [Information] JavaScript HTTP trigger function processed a request.
2022-02-16T22:34:10.562 [Information] Executed 'Functions.HttpTrigger1' (Succeeded, Id=4f503b35-b944-455e-ba02-5205f9e8b47a, Duration=114ms)
```
```output
2022-02-16T21:07:11.340 [Information] INFORMATION: PowerShell HTTP trigger function processed a request.
2022-02-16T21:07:11.449 [Information] Executed 'Functions.DriveGearTemperatureService' (Succeeded, Id=25e2edc3-542f-4629-a152-cf9ed99680d8, Duration=1164ms)
```

Ajouter la logique métier à la fonction

Ajoutons la logique à la fonction pour vérifier les relevés de température qu’elle reçoit et leur définir un état.

Notre fonction attend un tableau de relevés de température. L’extrait de code JSON suivant est un exemple de corps de demande qui nous enverrons à notre fonction. Chaque entrée reading possède un ID, un horodatage et une température.

{
    "readings": [
        {
            "driveGearId": 1,
            "timestamp": 1534263995,
            "temperature": 23
        },
        {
            "driveGearId": 3,
            "timestamp": 1534264048,
            "temperature": 45
        },
        {
            "driveGearId": 18,
            "timestamp": 1534264050,
            "temperature": 55
        }
    ]
}

Nous remplaçons le code par défaut de notre fonction par le code suivant qui implémente notre logique métier.

Dans le volet de la fonction HttpTrigger1, ouvrez le fichier index.js et remplacez son contenu par le code suivant. Après avoir apporté ce changement, dans la barre de commandes, sélectionnez Enregistrer pour enregistrer les mises à jour dans le fichier.

module.exports = function (context, req) {
    context.log('Drive Gear Temperature Service triggered');
    if (req.body && req.body.readings) {
        req.body.readings.forEach(function(reading) {

            if(reading.temperature<=25) {
                reading.status = 'OK';
            } else if (reading.temperature<=50) {
                reading.status = 'CAUTION';
            } else {
                reading.status = 'DANGER'
            }
            context.log('Reading is ' + reading.status);
        });

        context.res = {
            // status: 200, /* Defaults to 200 */
            body: {
                "readings": req.body.readings
            }
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please send an array of readings in the request body"
        };
    }
    context.done();
};

La logique que nous avons ajoutée est simple. Nous effectuons une itération au sein du tableau et définissons l’état sur OK, Attention ou Danger, en fonction de la valeur du champ de température. Nous renvoyons ensuite le tableau de relevés avec un champ d’état ajouté à chaque entrée.

Remarquez les instructions Log lorsque vous développez Journaux au bas du volet. Quand la fonction s’exécute, ces instructions ajoutent des messages dans la fenêtre Journaux.

Ouvrez le fichier run.ps1 et remplacez son contenu par le code suivant. Après avoir apporté ce changement, dans la barre de commandes, sélectionnez Enregistrer pour enregistrer les mises à jour dans le fichier.

using namespace System.Net

param($Request, $TriggerMetadata)

Write-Host "Drive Gear Temperature Service triggered"

$readings = $Request.Body.Readings
if ($readings) {
    foreach ($reading in $readings) {
        if ($reading.temperature -le 25) {
            $reading.Status = "OK"
        }
        elseif ($reading.temperature -le 50) {
            $reading.Status = "CAUTION"
        }
        else {
            $reading.Status = "DANGER"
        }

        Write-Host "Reading is $($reading.Status)"
    }

    $status = [HttpStatusCode]::OK
    $body = $readings
}
else {
    $status = [HttpStatusCode]::BadRequest
    $body = "Please send an array of readings in the request body"
}

Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = $status
    Body = $body
})

La logique que nous avons ajoutée est simple. Nous effectuons une itération au sein du tableau et définissons l’état sur OK, Attention ou Danger, en fonction de la valeur du champ de température. Nous renvoyons ensuite le tableau de relevés avec un champ d’état ajouté à chaque entrée.

Notez les appels à l’applet de commande Write-Host. Quand la fonction s’exécute, ces instructions ajoutent des messages dans la fenêtre Journaux.

Tester notre logique métier

Nous allons utiliser la fonctionnalité Tester/exécuter dans Développeur>Code + test pour tester notre fonction.

  1. Sous l’onglet Entrée, remplacez le contenu de la zone de texte Corps par le code suivant pour créer notre exemple de demande.

    {
        "readings": [
            {
                "driveGearId": 1,
                "timestamp": 1534263995,
                "temperature": 23
            },
            {
                "driveGearId": 3,
                "timestamp": 1534264048,
                "temperature": 45
            },
            {
                "driveGearId": 18,
                "timestamp": 1534264050,
                "temperature": 55
            }
        ]
    }
    
  2. Sélectionnez Exécuter. L’onglet Sortie affiche le code de réponse HTTP et le contenu. Pour voir les messages des journaux, ouvrez l’onglet Journaux dans le contrôle suspendu en bas du volet (s’il n’est pas déjà ouvert). L’image suivante montre un exemple de réponse dans le volet de sortie ainsi que des messages dans le volet Journaux.

    Screenshot of the Azure function editor, with the Test and Logs tabs showing.

    L’onglet Sortie montre qu’un champ d’état a été ajouté à chaque relevé.

  3. Dans le menu Développeur à gauche, sélectionnez Monitorer pour voir si la demande a été journalisée dans Application Insights. Le volet Surveiller apparaît pour votre fonction.

    L’onglet Appels du volet affiche les Traces d’appel pour chacun de vos appels de fonction. Sélectionnez la valeur Date(UTC) pour l’un des appels et affichez les détails sur l’exécution de votre fonction.