Exercice - Créer une fonction Azure pour simuler des données de télémétrie

Effectué

Pour notre exemple, nous utilisons l’approvisionnement en événements. Créons une fonction qui simule des données de télémétrie et envoyons-la à un hub d’événements. Ensuite, une autre fonction peut écouter cet événement, le traiter et le stocker dans une base de données créée avec Azure Cosmos DB.

Visualization of event sourcing for buying coffee at a coffee shop.

Préparation de votre environnement

Nous allons définir des variables d’environnement pour que les commandes suivantes restent aussi courtes et compréhensibles que possible. Définissez les espaces réservés <value>, puis collez et exécutez les commandes suivantes dans votre terminal ou outil en ligne de commande :

RESOURCE_GROUP=<value>
EVENT_HUB_NAMESPACE=<value>
EVENT_HUB_NAME=<value>
EVENT_HUB_AUTHORIZATION_RULE=<value>
COSMOS_DB_ACCOUNT=<value>
STORAGE_ACCOUNT=<value>
FUNCTION_APP=<value>
LOCATION=<value>

Notes

Pour définir la variable LOCATION, vous pouvez vérifier la commande az functionapp list-consumption-locations et utiliser l’emplacement le plus proche.

Créer les composants requis

L’approvisionnement des ressources sur Azure prend un certain temps. Commençons à créer le composant le plus tôt possible afin d’éviter de longues attentes plus tard.

Créer un groupe de ressources

Il est toujours judicieux de lier toutes les ressources d’un entraînement, d’une preuve de concept ou d’un prototype dans un seul groupe de ressources. Cela vous permet de nettoyer facilement tous les services utilisés à l’aide d’une seule commande. Pour créer un groupe de ressources à l’emplacement spécifié, exécutez la commande suivante dans votre terminal :

az group create \
    --name $RESOURCE_GROUP \
    --location $LOCATION

Créer et configurer un hub d’événements

Pour le hub d’événements, il est nécessaire de spécifier l’espace de noms qu’il doit écouter. En outre, vous devez configurer la règle d’autorisation pour Listen et Send.

az eventhubs namespace create \
    --resource-group $RESOURCE_GROUP \
    --name $EVENT_HUB_NAMESPACE
az eventhubs eventhub create \
    --resource-group $RESOURCE_GROUP \
    --name $EVENT_HUB_NAME \
    --namespace-name $EVENT_HUB_NAMESPACE \
az eventhubs eventhub authorization-rule create \
    --resource-group $RESOURCE_GROUP \
    --name $EVENT_HUB_AUTHORIZATION_RULE \
    --eventhub-name $EVENT_HUB_NAME \
    --namespace-name $EVENT_HUB_NAMESPACE \
    --rights Listen Send

Créer, configurer et déployer la fonction Azure

Pour que cet exemple soit le plus réaliste possible, créez une fonction Azure et simulez des données de télémétrie. Vous pouvez également lier un appareil IoT à votre fonction Azure, ce qui nécessite des données réelles. Étant donné que cette fonction est celle qui va créer l’événement, ajoutons un indicateur p ou -p.

az storage account create \
    --resource-group $RESOURCE_GROUP \
    --name $STORAGE_ACCOUNT"p" \
    --sku Standard_LRS
az functionapp create \
    --resource-group $RESOURCE_GROUP \
    --name $FUNCTION_APP"-p"\
    --storage-account $STORAGE_ACCOUNT"p" \
    --consumption-plan-location $LOCATION \
    --runtime java \
    --functions-version 4

Remarque

Utilisez les fonctions de la version 4, car les versions 2 et 3 ont été déconseillées en décembre 2022.

Lorsque la commande az functionapp create crée votre application de fonction, elle crée également une ressource Application Insights portant le même nom. Nous utilisons cette ressource ultérieurement pour notre supervision.

Afin de récupérer les chaînes de connexion pour le compte de stockage et le Event Hub, utilisez les commandes suivantes pour les enregistrer dans des variables d’environnement, puis affichez-les avec la commande echo.

AZURE_WEB_JOBS_STORAGE=$( \
    az storage account show-connection-string \
        --resource-group $RESOURCE_GROUP \
        --name $STORAGE_ACCOUNT"p" \
        --query connectionString \
        --output tsv)
echo $AZURE_WEB_JOBS_STORAGE
EVENT_HUB_CONNECTION_STRING=$( \
    az eventhubs eventhub authorization-rule keys list \
        --resource-group $RESOURCE_GROUP \
        --name $EVENT_HUB_AUTHORIZATION_RULE \
        --eventhub-name $EVENT_HUB_NAME \
        --namespace-name $EVENT_HUB_NAMESPACE \
        --query primaryConnectionString \
        --output tsv)
echo $EVENT_HUB_CONNECTION_STRING

Pour stocker les chaînes de connexion dans les paramètres d’application de votre compte Azure Functions, exécutez la commande suivante dans votre terminal :

az functionapp config appsettings set \
    --resource-group $RESOURCE_GROUP \
    --name $FUNCTION_APP"-p" \
    --settings \
        AzureWebJobsStorage=$AZURE_WEB_JOBS_STORAGE \
        EventHubConnectionString=$EVENT_HUB_CONNECTION_STRING

Vos ressources Azure, le Event Hub et la fonction Azure, sont à présent créées et configurées pour fonctionner en synergie.

Ensuite, créez un projet de fonctions local avec Maven.

mvn archetype:generate --batch-mode \
    -DarchetypeGroupId=com.microsoft.azure \
    -DarchetypeArtifactId=azure-functions-archetype \
    -DappName=$FUNCTION_APP"-p" \
    -DresourceGroup=$RESOURCE_GROUP \
    -DappRegion=$LOCATION \
    -DappServicePlanName=$LOCATION"plan" \
    -DgroupId=com.learn \
    -DartifactId=telemetry-functions-producer

Cette commande génère plusieurs fichiers dans un dossier telemetry-functions-producer :

  • Fichier de build pom.xml avec des dépendances Azure prédéfinies.
  • Fichier local.settings.json destiné à contenir les paramètres d’application pour le déploiement local et les tests manuels.
  • Fichier host.json qui active l’ensemble d’extensions Azure Functions.
  • Fichier Function.java qui comprend la fonction de déclencheur HTTP par défaut.
  • Quelques fichiers de test que ce module Learn n’utilise pas.

Comme nous ne touchons pas aux fichiers de test dans ce module Learn, n’hésitez pas à les supprimer.

cd telemetry-functions-producer
rm -r src/test

Pour une exécution locale, les paramètres d’application doivent être récupérés et stockés dans le fichier local.settings.json. Vous pouvez effectuer cette opération automatiquement en exécutant la commande fetch-app-settings.

func azure functionapp fetch-app-settings $FUNCTION_APP"-p"

Ensuite, ouvrez le fichier Function.java et remplacez son contenu par le code suivant :

package com.learn;

import com.microsoft.azure.functions.annotation.EventHubOutput;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.TimerTrigger;
import com.microsoft.azure.functions.ExecutionContext;
public class Function {

    @FunctionName("generateSensorData")
    @EventHubOutput(
        name = "event",
        eventHubName = "", // blank because the value is included in the connection string
        connection = "EventHubConnectionString")
    public TelemetryItem generateSensorData(
        @TimerTrigger(
            name = "timerInfo",
            schedule = "*/10 * * * * *") // every 10 seconds
            String timerInfo,
        final ExecutionContext context) {
            context.getLogger().info("Java Timer trigger function executed at: " + java.time.LocalDateTime.now());
            double temperature = Math.random() * 100;
            double pressure = Math.random() * 50;
        return new TelemetryItem(temperature, pressure);
    }
}

La fonction generateSensorData simule un capteur qui envoie des relevés de température et de pression au hub d'événements. Un déclencheur exécute la fonction toutes les 10 secondes et une liaison de sortie du hub d'événements transmet la valeur renvoyée au hub d'événements.

Lorsque le hub d'événements reçoit le message, il génère un événement.

Les données utilisées par cette fonction sont stockées à l’aide d’une classe appelée TelemetryItem, que vous devez implémenter. Créez un fichier appelé TelemetryItem.java dans le même emplacement que le fichier Function.java et ajoutez le code suivant :

package com.learn;

public class TelemetryItem {

    private String id;
    private double temperature;
    private double pressure;
    private boolean isNormalPressure;
    private status temperatureStatus;
    static enum status {
        COOL,
        WARM,
        HOT
    }

    public TelemetryItem(double temperature, double pressure) {
        this.temperature = temperature;
        this.pressure = pressure;
    }

    public String getId() {
        return id;
    }

    public double getTemperature() {
        return temperature;
    }

    public double getPressure() {
        return pressure;
    }

    @Override
    public String toString() {
        return "TelemetryItem={id=" + id + ",temperature="
            + temperature + ",pressure=" + pressure + "}";
    }

    public boolean isNormalPressure() {
        return isNormalPressure;
    }

    public void setNormalPressure(boolean isNormal) {
        this.isNormalPressure = isNormal;
    }

    public status getTemperatureStatus() {
        return temperatureStatus;
    }

    public void setTemperatureStatus(status temperatureStatus) {
        this.temperatureStatus = temperatureStatus;
    }
}

Exécution locale

Lorsque vous exécutez les fonctions Azure localement, elles sont déjà envoyées en streaming dans le monde entier. Vous pouvez également les examiner dans votre portail Azure.

mvn clean package
mvn azure-functions:run

Après quelques messages relatifs à la génération et au démarrage, une sortie semblable à l'exemple suivant s'affiche à chaque exécution des fonctions :

[2021-01-19T16:25:40.005Z] Executing 'Functions.generateSensorData' (Reason='Timer fired at 2021-01-19T17:25:40.0044630+01:00', Id=fcf567a3-03ec-4159-9714-aa4449861b30)
[2021-01-19T16:25:40.011Z] Java Timer trigger function executed at: 2021-01-19T17:25:40.009405
[2021-01-19T16:25:40.013Z] Function "generateSensorData" (Id: fcf567a3-03ec-4159-9714-aa4449861b30) invoked by Java Worker
[2021-01-19T16:25:40.048Z] Executed 'Functions.generateSensorData' (Succeeded, Id=fcf567a3-03ec-4159-9714-aa4449861b30, Duration=43ms)

Notes

Avant de déployer et d’exécuter votre fonction sur le cloud Azure, vous pouvez envoyer des événements dans le monde entier à partir de votre ordinateur local. Cela est très utile pour le développement, le débogage et le test local.

Déployer sur Azure

Déclenchez le déploiement sur Azure en exécutant la commande mvn azure-functions:deploy et continuez.

mvn azure-functions:deploy