Cvičení – vytvoření funkce Azure pro simulaci telemetrických dat

Dokončeno

V našem příkladu používáme model Event Sourcing. Pojďme vytvořit funkci, která simuluje telemetrická data a odesílá je do centra událostí. Později může další funkce naslouchat této události a zpracovávat ji a ukládat ji do databáze vytvořené pomocí služby Azure Cosmos DB.

Vizualizace event sourcingu pro nákup kávy v kavárně.

Příprava prostředí

Pojďme definovat některé proměnné prostředí, aby byly následující příkazy co nejkratší a co nejsrozumitelné. Definujte zástupné symboly <value> a vložte a spusťte následující příkazy v terminálu nebo nástroji příkazového řádku:

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>

Poznámka

Pokud chcete nastavit proměnnou LOCATION, můžete zkontrolovat příkaz az functionapp list-consumption-locations a použít nejbližší umístění.

Vytvoření požadovaných komponent

Zřizování prostředků v Azure nějakou dobu trvá. Začněme vytvořením komponenty co nejdříve, abyste se vyhnuli dlouhým čekáním později.

Vytvoření skupiny prostředků

Vždy je vhodné svázat všechny prostředky trénování, testování konceptu nebo prototypu v jedné skupině prostředků. Tímto způsobem můžete pohodlně vyčistit všechny použité služby jedním příkazem. Pokud chcete vytvořit skupinu prostředků v zadaném umístění, spusťte v terminálu následující příkaz:

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

Vytvoření a konfigurace centra událostí

Pro centrum událostí je nutné zadat obor názvů, kterému má naslouchat. Musíte také nakonfigurovat autorizační pravidlo pro Listen a 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

Sestavení, konfigurace a nasazení funkce Azure Functions

Pokud chcete, aby byl tento příklad co nejrealističtější, vytvořte funkci Azure a simulujte telemetrická data. Můžete také vytvořit vazbu zařízení IoT na funkci Azure, která pak převezme skutečná data. Jelikož tato funkce generuje události, přidejme příznak p nebo -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

Poznámka

Použijte funkce ve verzi 4, protože verze 2 a 3 byly v prosinci 2022 zastaralé.

Když příkaz az functionapp create vytvoří vaši aplikaci funkcí, vytvoří také prostředek Application Insights se stejným názvem. Tento prostředek použijeme později pro monitorování.

Pokud chcete načíst připojovací řetězce pro účet úložiště a centrum událostí, pomocí následujících příkazů je uložte do proměnných prostředí a pak je zobrazte pomocí příkazu 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

Pokud chcete připojovací řetězce uložit v nastavení aplikace účtu funkce Azure Functions, spusťte v terminálu následující příkaz:

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

Teď se centrum událostí prostředků Azure a funkce Azure vytvoří a nakonfigurují tak, aby správně spolupracovaly.

Dále vytvořte projekt místních funkcí pomocí Mavenu.

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

Tento příkaz vygeneruje několik souborů ve složce telemetry-functions-producer:

  • Soubor sestavení pom.xml s předdefinovanými závislostmi Azure.
  • Soubor local.settings.json pro uložení nastavení aplikace pro místní nasazení a ruční testování.
  • Soubor host.json, který aktivuje sadu rozšíření Azure Functions.
  • Soubor Function.java, který obsahuje výchozí funkci triggeru HTTP.
  • Několik testovacích souborů, které tento modul Learn nepoužívá.

V tomto modulu Learn se nedotkneme testovacích souborů, takže je můžete odstranit.

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

Pro místní spuštění je potřeba načíst a uložit nastavení aplikace v souboru local.settings.json. Můžete to udělat automaticky spuštěním příkazu fetch-app-settings.

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

Dále otevřete soubor Function.java a nahraďte obsah následujícím kódem:

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

Funkce generateSensorData simuluje senzor, který odesílá hodnoty teploty a tlaku do centra událostí. Trigger časovače spustí funkci každých 10 sekund a výstupní vazba centra událostí odešle návratovou hodnotu do centra událostí.

Když centrum událostí obdrží zprávu, vygeneruje událost.

Data používaná touto funkcí se ukládají pomocí třídy s názvem TelemetryItem, kterou potřebujete implementovat. Vytvořte nový soubor s názvem TelemetryItem.java ve stejném umístění jako Function.java a přidejte následující kód:

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

Spustit lokálně

Když spouštíte funkce Azure Functions místně, jsou už streamované po celém světě. Můžete je také zkontrolovat na webu Azure Portal.

mvn clean package
mvn azure-functions:run

Po některých sestavách a spouštěcích zprávách se zobrazí výstup podobný následujícímu příkladu při každém spuštění funkcí:

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

Poznámka

Před nasazením a spuštěním funkce v cloudu Azure můžete odesílat události z místního počítače po celém světě. To je velmi užitečné pro vývoj, ladění a místní testování.

Nasazení do Azure

Aktivujte nasazení v Azure spuštěním příkazu mvn azure-functions:deploy a pokračujte.

mvn azure-functions:deploy