Exercício - Criar uma função do Azure para simular dados telemétricos
Para o nosso exemplo, usamos o fornecimento de eventos. Vamos criar uma função que simula dados telemétricos e enviá-los para um hub de eventos. Mais tarde, outra função pode ouvir esse evento e processá-lo e armazená-lo em um banco de dados criado com o Azure Cosmos DB.
Preparar o ambiente
Vamos definir algumas variáveis de ambiente para manter os comandos a seguir tão curtos e compreensíveis quanto possível. Defina os espaços reservados, cole e execute os <value>
seguintes comandos no seu terminal ou ferramenta de linha de comando:
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 definir a variável LOCATION, você pode verificar o comando e usar o az functionapp list-consumption-locations
local mais próximo.
Criar os componentes necessários
O provisionamento dos recursos no Azure leva algum tempo. Vamos começar com a criação do componente o mais cedo possível para evitar longas esperas mais tarde.
Criar um grupo de recursos
É sempre uma boa ideia vincular todos os recursos de um treinamento, prova de conceito ou um protótipo em um grupo de recursos. Dessa forma, você pode limpar convenientemente todos os serviços usados com um comando. Para criar um grupo de recursos no local especificado, execute o seguinte comando no terminal:
az group create \
--name $RESOURCE_GROUP \
--location $LOCATION
Criar e configurar um hub de eventos
Para o hub de eventos, é necessário especificar o namespace que ele deve ouvir. Além disso, você precisa configurar a regra de autorização para Listen
e 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
Criar, configurar e implantar a função do Azure
Para tornar este exemplo o mais realista possível, crie uma função do Azure e simule dados telemétricos. Você também pode vincular um dispositivo IoT à sua função do Azure, que levaria dados reais. Como essa função é a produtora de eventos, vamos adicionar um sinalizador p ou -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
As funções de uso da versão 4 como 2 e 3 foram preteridas em dezembro de 2022.
Quando o comando cria seu aplicativo de função, ele também cria um recurso do Application Insights com o az functionapp create
mesmo nome. Usamos esse recurso posteriormente para nosso monitoramento.
Para recuperar as cadeias de conexão da conta de armazenamento e do hub de eventos, use os comandos a seguir para salvá-las em variáveis de ambiente e exibi-las com o echo
comando.
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 armazenar as cadeias de conexão nas configurações do aplicativo da sua conta do Azure Function, execute o seguinte comando no 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
Agora, seu hub de eventos de recursos do Azure e a função do Azure são criados e configurados para funcionar corretamente juntos.
Em seguida, crie um projeto de funções locais com o 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 gera vários arquivos dentro de uma telemetry-functions-producer
pasta:
- O
pom.xml
arquivo de compilação com dependências predefinidas do Azure. - O
local.settings.json
arquivo para armazenar as configurações do aplicativo para implantação local e teste manual. - Um
host.json
arquivo que habilita o Pacote de Extensão do Azure Functions. - Um
Function.java
arquivo que inclui a função de gatilho HTTP padrão. - Alguns arquivos de teste que este módulo do Learn não usa.
Não tocamos nos arquivos de teste neste módulo do Learn, então sinta-se à vontade para excluí-los.
cd telemetry-functions-producer
rm -r src/test
Para execução local, as configurações do aplicativo precisam ser recuperadas local.settings.json
e armazenadas no arquivo. Você pode fazer isso automaticamente executando o fetch-app-settings
comando.
func azure functionapp fetch-app-settings $FUNCTION_APP"-p"
Em seguida, abra o arquivo e substitua o Function.java
conteúdo pelo seguinte código:
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);
}
}
A generateSensorData
função simula um sensor que envia leituras de temperatura e pressão para o hub de eventos. Um gatilho de temporizador executa a função a cada 10 segundos e uma ligação de saída do hub de eventos envia o valor de retorno para o hub de eventos.
Quando o hub de eventos recebe a mensagem, ele gera um evento.
Os dados usados por essa função são armazenados usando uma classe chamada TelemetryItem, que você precisa implementar. Crie um novo arquivo chamado TelemetryItem.java no mesmo local que Function.java e adicione o seguinte código:
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;
}
}
Executar localmente
Quando você executa funções do Azure localmente, elas já são transmitidas em todo o mundo! Além disso, você pode revisá-los em seu portal do Azure.
mvn clean package
mvn azure-functions:run
Após algumas mensagens de compilação e inicialização, você verá uma saída semelhante ao exemplo a seguir para cada vez que as funções forem executadas:
[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 implantar e executar sua função na nuvem do Azure, você pode enviar eventos de sua máquina local para todo o mundo! Isso é muito útil para desenvolver, depurar e testar localmente.
Implementar no Azure
Acione a implantação no Azure executando o mvn azure-functions:deploy
comando e continue.
mvn azure-functions:deploy