Упражнение. Создание функции Azure для имитации данных телеметрии
В нашем примере используется поиск событий. Давайте создадим функцию, которая имитирует данные телеметрии и отправляет их в концентратор событий. Позже другая функция может прослушивать это событие и обрабатывать и хранить его в базе данных, созданной с помощью Azure Cosmos DB.
Подготовьте среду
Давайте определим некоторые переменные среды, чтобы обеспечить максимально короткие и понятные команды. Определите заполнители <value>
и вставьте и выполните следующие команды в терминале или средстве командной строки:
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>
Заметка
Чтобы задать переменную LOCATION, можно проверить команду az functionapp list-consumption-locations
и использовать ближайшее местоположение.
Создание необходимых компонентов
Подготовка ресурсов в Azure занимает некоторое время. Начнем с создания компонента как можно раньше, чтобы избежать длительных ожиданий позже.
Создание группы ресурсов
Всегда рекомендуется привязать все ресурсы обучения, доказательства концепции или прототипа в одной группе ресурсов. Таким образом можно удобно очистить все используемые службы с помощью одной команды. Чтобы создать группу ресурсов в указанном расположении, выполните следующую команду в терминале:
az group create \
--name $RESOURCE_GROUP \
--location $LOCATION
Создание и настройка концентратора событий
Для концентратора событий необходимо указать пространство имен, к которому он должен подключаться. Кроме того, необходимо настроить правило авторизации для Listen
и 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
Создание, настройка и развертывание функции Azure
Чтобы сделать этот пример максимально реалистичным, создайте функцию Azure и имитируйте данные телеметрики. Вы также можете привязать устройство Интернета вещей к функции Azure, которая будет принимать реальные данные. Поскольку эта функция воспроизводит события, давайте добавим флаг p или -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
Заметка
Используйте функции-версии 4, так как версии 2 и 3 были устаревшими в декабре 2022 года.
Когда команда az functionapp create
создает приложение-функцию, он также создает ресурс Application Insights с тем же именем. Мы используем этот ресурс позже для мониторинга.
Чтобы получить строки подключения для учетной записи хранения и концентратора событий, используйте следующие команды, чтобы сохранить их в переменных среды, а затем отобразить их с помощью команды 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
Чтобы сохранить строки подключения в параметрах приложения учетной записи функции Azure, выполните следующую команду в терминале:
az functionapp config appsettings set \
--resource-group $RESOURCE_GROUP \
--name $FUNCTION_APP"-p" \
--settings \
AzureWebJobsStorage=$AZURE_WEB_JOBS_STORAGE \
EventHubConnectionString=$EVENT_HUB_CONNECTION_STRING
Теперь центр событий ваших ресурсов Azure и функция Azure созданы и настроены для правильной совместной работы.
Затем создайте проект локальных функций с помощью 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
Эта команда создает несколько файлов в папке telemetry-functions-producer
:
- Файл сборки
pom.xml
с предопределенными зависимостями Azure. - Файл
local.settings.json
для хранения параметров приложения для локального развертывания и ручного тестирования. - Файл
host.json
, который включает пакет расширений функций Azure. - Файл
Function.java
, включающий функцию триггера HTTP по умолчанию. - Несколько тестовых файлов, которые этот модуль Learn не использует.
Мы не касаемся тестовых файлов в этом модуле Learn, поэтому вы можете удалить их.
cd telemetry-functions-producer
rm -r src/test
Для локального выполнения параметры приложения должны быть извлечены и сохранены в файле local.settings.json
. Это можно сделать автоматически, выполнив команду fetch-app-settings
.
func azure functionapp fetch-app-settings $FUNCTION_APP"-p"
Затем откройте файл Function.java
и замените содержимое следующим кодом:
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);
}
}
Функция generateSensorData
имитирует датчик, который отправляет значения температуры и давления в концентратор событий. Триггер таймера запускает функцию каждые 10 секунд, а выходная привязка концентратора событий отправляет возвращаемое значение в концентратор событий.
Когда концентратор событий получает сообщение, он создает событие.
Данные, используемые этой функцией, хранятся с помощью класса TelemetryItem, который необходимо реализовать. Создайте новый файл с именем TelemetryItem.java в том же расположении, что и Function.java, и добавьте следующий код:
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;
}
}
Запуск локально
При локальном запуске функций Azure они уже передаются по всему миру! Кроме того, их можно просмотреть на портале Azure.
mvn clean package
mvn azure-functions:run
После некоторых сообщений сборки и запуска вы увидите выходные данные, аналогичные следующему примеру при каждом запуске функций:
[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)
Заметка
Перед развертыванием и запуском функции в облаке Azure можно отправлять события с локального компьютера по всему миру! Это очень полезно для разработки, отладки и локального тестирования.
Развертывание в Azure
Активируйте развертывание в Azure, выполнив команду mvn azure-functions:deploy
и продолжайте работу.
mvn azure-functions:deploy