Ejercicio: Creación de una función de Azure para simular datos de telemetría
Para nuestro ejemplo, usaremos el modelo de aprovisionamiento de eventos. Vamos a crear una función que simule datos de telemetría y los envíe a un centro de eventos. Más adelante, otra función podrá escuchar este evento, procesarlo y almacenarlo en una base de datos creada con Azure Cosmos DB.
Preparación del entorno
Vamos a definir algunas variables de entorno para que los siguientes comandos sean lo más comprensibles y breves posible. Defina los marcadores de posición <value>
, y pegue y ejecute los siguientes comandos en el terminal o en la herramienta de línea de comandos:
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>
Nota:
Para establecer la variable LOCATION, puede ejecutar el comando az functionapp list-consumption-locations
y usar la ubicación más cercana.
Creación de los componentes necesarios
El aprovisionamiento de los recursos en Azure tarda un poco de tiempo. Empecemos por crear los componentes cuanto antes para evitar largas esperas más adelante.
Crear un grupo de recursos
Siempre es una buena idea enlazar todos los recursos de un entrenamiento, una prueba de concepto o un prototipo en un grupo de recursos. De este modo, puede limpiar con facilidad todos los servicios usados con un comando. Para crear un grupo de recursos en la ubicación especificada, ejecute el siguiente comando en el terminal:
az group create \
--name $RESOURCE_GROUP \
--location $LOCATION
Creación y configuración de un centro de eventos
Para el centro de eventos, es necesario especificar el espacio de nombres en el que debe realizar la escucha. Además, hay que configurar la regla de autorización para Listen
y 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
Compilación, configuración e implementación de la función de Azure
Para que este ejemplo sea lo más realista posible, deberá crear una función de Azure y simular datos de telemetría. También podría enlazar un dispositivo IoT a su función de Azure, que tomaría datos reales. Dado que esta función es la que produce eventos, vamos a agregar una marca p o -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
Nota:
El uso de functions-version 4 como 2 y 3 quedó en desuso en diciembre de 2022.
Cuando el comando az functionapp create
crea la aplicación de función, también crea un recurso de Application Insights con el mismo nombre. Usaremos ese recurso más adelante para nuestras necesidades de supervisión.
Para recuperar las cadenas de conexión de la cuenta de almacenamiento y el centro de eventos, use los siguientes comandos para guardarlas en variables de entorno y, a continuación, mostrarlas con el comando 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
Para almacenar las cadenas de conexión en la configuración de la aplicación de la cuenta de Azure Functions, ejecute el siguiente comando en el 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
Ahora, el centro de eventos de recursos de Azure y la función de Azure se crean y configuran para que funcionen bien juntos.
A continuación, cree un proyecto de Functions local con 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
Este comando genera varios archivos dentro de una carpeta de telemetry-functions-producer
:
- El archivo de compilación
pom.xml
con las dependencias de Azure predefinidas - El archivo
local.settings.json
para almacenar la configuración de la aplicación para la implementación local y las pruebas manuales - Un archivo
host.json
que habilita el conjunto de extensión de Azure Functions - Un archivo
Function.java
que incluye la función de desencadenador HTTP predeterminada - Algunos archivos de prueba que no se usan en este módulo de Learn
No emplearemos los archivos de prueba en este módulo de Learn, de modo que puede eliminarlos.
cd telemetry-functions-producer
rm -r src/test
Para llevar a cabo la ejecución local, la configuración de la aplicación debe recuperarse y almacenarse en el archivo local.settings.json
. Puede hacerlo automáticamente ejecutando el comando fetch-app-settings
.
func azure functionapp fetch-app-settings $FUNCTION_APP"-p"
Después, abra el archivo Function.java
y reemplace el contenido por el código siguiente:
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 función generateSensorData
simula un sensor que envía lecturas de temperatura y presión al centro de eventos. Un desencadenador de temporizador ejecuta la función cada diez segundos y un enlace de salida del centro de eventos envía el valor devuelto al centro de eventos.
Cuando el centro de eventos recibe el mensaje, genera un evento.
Los datos que utiliza esta función se almacenan mediante una clase denominada "TelemetryItem", que deberá implementar. Cree un archivo denominado "TelemetryItem.java" en la misma ubicación que Function.java y agregue el código siguiente:
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;
}
}
Ejecución en modo local
Al ejecutar funciones de Azure localmente, los eventos ya se transmiten por todo el mundo. Además, puede revisarlos en Azure Portal.
mvn clean package
mvn azure-functions:run
Después de algunos mensajes de compilación e inicio, verá una salida similar al ejemplo siguiente cada vez que se ejecuten las funciones:
[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)
Nota:
Antes de implementar y ejecutar la función en la nube de Azure, puede enviar eventos de su máquina local por todo el mundo. Esto es muy útil para las tareas de desarrollo, depuración y pruebas locales.
Implementar en Azure
Desencadene la implementación en Azure mediante la ejecución del comando mvn azure-functions:deploy
y continúe.
mvn azure-functions:deploy