Övning – Skapa en Azure-funktion för att simulera telemetriska data

Slutförd

I vårt exempel använder vi händelsekällor. Nu ska vi skapa en funktion som simulerar telemetriska data och skickar dem till en händelsehubb. Senare kan en annan funktion lyssna på den här händelsen och bearbeta och lagra den i en databas som skapats med Azure Cosmos DB.

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

Förbered din miljö

Nu ska vi definiera vissa miljövariabler för att hålla följande kommandon så korta och begripliga som möjligt. <value> Definiera platshållarna och klistra in och kör följande kommandon i terminalen eller kommandoradsverktyget:

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>

Kommentar

Om du vill ange LOCATION-variabeln kan du kontrollera az functionapp list-consumption-locations kommandot och använda närmaste plats.

Skapa nödvändiga komponenter

Det tar lite tid att etablera resurserna i Azure. Vi börjar med att skapa komponenten så tidigt som möjligt för att undvika långa väntetider senare.

Skapa en resursgrupp

Det är alltid en bra idé att binda alla resurser i en utbildning, konceptbevis eller en prototyp i en resursgrupp. På så sätt kan du enkelt rensa alla tjänster som används med ett kommando. Om du vill skapa en resursgrupp på den angivna platsen kör du följande kommando i terminalen:

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

Skapa och konfigurera en händelsehubb

För händelsehubben är det nödvändigt att ange det namnområde som den ska lyssna på. Du måste också konfigurera auktoriseringsregeln till Listen och 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

Skapa, konfigurera och distribuera Azure-funktionen

Om du vill göra det här exemplet så realistiskt som möjligt skapar du en Azure-funktion och simulerar telemetriska data. Du kan också binda en IoT-enhet till din Azure-funktion, som sedan tar verkliga data. Eftersom den här funktionen är den händelseproducerande ska vi lägga till en p- eller -p-flagga.

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

Kommentar

Använd functions-version 4 som 2 och 3 blev inaktuella i december 2022.

az functionapp create När kommandot skapar funktionsprogrammet skapas även en Application Insights-resurs med samma namn. Vi använder den resursen senare för vår övervakning.

Om du vill hämta anslutningssträng för lagringskontot och händelsehubben använder du följande kommandon för att spara dem i miljövariabler och visar dem sedan med echo kommandot .

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

Om du vill lagra anslutningssträng i programinställningarna för ditt Azure-funktionskonto kör du följande kommando i terminalen:

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

Nu skapas och konfigureras händelsehubben och Azure-funktionen för Azure-resurser så att de fungerar korrekt tillsammans.

Skapa sedan ett lokalt funktionsprojekt med 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

Det här kommandot genererar flera filer i en telemetry-functions-producer mapp:

  • Byggfilen pom.xml med fördefinierade Azure-beroenden.
  • Filen local.settings.json som innehåller programinställningarna för lokal distribution och manuell testning.
  • En host.json fil som aktiverar Azure Functions-tilläggspaketet.
  • En Function.java fil som innehåller http-utlösarfunktionens standardfunktion.
  • Några testfiler som den här Learn-modulen inte använder.

Vi rör inte testfilerna i den här Learn-modulen, så ta bort dem.

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

För lokal körning måste programinställningarna hämtas och lagras i local.settings.json filen. Du kan göra det automatiskt genom att köra fetch-app-settings kommandot .

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

Function.java Öppna sedan filen och ersätt innehållet med följande kod:

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);
    }
}

Funktionen generateSensorData simulerar en sensor som skickar temperatur- och tryckavläsningar till händelsehubben. En timerutlösare kör funktionen var 10:e sekund och en utdatabindning för händelsehubben skickar returvärdet till händelsehubben.

När händelsehubben tar emot meddelandet genereras en händelse.

De data som används av den här funktionen lagras med hjälp av en klass som heter TelemetryItem, som du behöver implementera. Skapa en ny fil med namnet TelemetryItem.java på samma plats som Function.java och lägg till följande kod:

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;
    }
}

Kör lokalt

När du kör Azure-funktioner lokalt strömmas de redan över hela världen! Du kan också granska dem i Azure-portalen.

mvn clean package
mvn azure-functions:run

Efter några kompilerings- och startmeddelanden visas utdata som liknar följande exempel för varje gång funktionerna körs:

[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)

Kommentar

Innan du distribuerar och kör din funktion i Azure-molnet kan du skicka händelser från din lokala dator över hela världen! Det är mycket användbart för att utveckla, felsöka och lokala tester.

Distribuera till Azure

Utlös distributionen i Azure genom att mvn azure-functions:deploy köra kommandot och fortsätta.

mvn azure-functions:deploy