演習 - 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>
Note
LOCATION 変数を設定するために、az functionapp list-consumption-locations
コマンドを確認して最も近い場所を使用できます。
必要なコンポーネントを作成する
Azure でのリソースのプロビジョニングには時間がかかります。 後で長い待機時間が発生しないように、できるだけ早くコンポーネントの作成を開始しましょう。
リソース グループを作成する
トレーニング、概念実証、またはプロトタイプの全リソースを常に 1 つのリソース グループにバインドすることをお勧めします。 これにより、1 つのコマンドで、使用されているすべてのサービスを簡単にクリーンアップできます。 指定した場所にリソース グループを作成するには、ターミナルで次のコマンドを実行します。
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 関数を作成し、テレメトリ データをシミュレートします。 また、IoT デバイスを 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
Note
functions-version では、2 と 3 が 2022 年 12 月に非推奨になったため、4 を使います。
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
フォルダー内にいくつかのファイルが生成されます。
- 定義済みの Azure 依存関係を含む
pom.xml
ビルド ファイル。 - ローカル配置と手動テストのためのアプリケーション設定を保持する
local.settings.json
ファイル。 - Azure Functions 拡張機能バンドルを有効にする
host.json
ファイル。 - 既定の HTTP トリガー関数を含む
Function.java
ファイル。 - この 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 portal で確認することもできます。
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)
Note
Azure クラウドに関数をデプロイして実行する前に、ローカル コンピューターから世界中にイベントを送信できます。 これは、開発、デバッグ、およびローカル テストに非常に便利です。
Azure にデプロイ
Azure でデプロイをトリガーするには、mvn azure-functions:deploy
コマンドを実行して続行します。
mvn azure-functions:deploy