Os grafos de fluxo de dados proporcionam duas formas de controlar quais mensagens fluem através do seu pipeline: as transformações de filtro eliminam mensagens indesejadas, e as transformações de ramificação encaminham cada mensagem por um de dois caminhos com base em uma condição. Após a ramificação, uma transformação de concatenação junta novamente os caminhos.
Estas transformam as mensagens de encaminhamento dentro do grafo. Para em vez disso, encaminhar mensagens para diferentes tópicos MQTT com base no seu conteúdo, veja Encaminhar mensagens para diferentes tópicos MQTT.
Para uma visão geral dos gráficos de fluxo de dados e de como as transformações se compõem num pipeline, consulte Visão Geral dos Gráficos de Fluxo de Dados.
As transformações utilizam uma linguagem de expressões para calcular valores, condições de teste e campos de referência. Expressões referem-se a entradas por posição, não pelo nome: a primeira entrada na inputs lista é $1, a segunda é $2, e assim sucessivamente. Funções incorporadas como cToF convertem e manipulam esses valores.
Para a lista completa de operadores, funções, tipos de dados e campos de metadados, consulte a referência Expressões.
Pré-requisitos
- Um endpoint de registo predefinido chamado
default que aponta mcr.microsoft.com é criado automaticamente durante a implementação. As transformações incorporadas usam este endpoint.
Os CLI do Azure exemplos deste artigo usam variáveis de ambiente para que possas definir cada valor uma vez e depois copiar e colar os comandos as-is. Se estiver a usar o ambiente Operações IoT do Azure Codespaces do quickstart, estas variáveis já estão definidas para si e pode saltar este passo. Caso contrário, defina as seguintes variáveis de ambiente no seu shell antes de executar os comandos.
Os seguintes scripts definem as variáveis de ambiente mais usadas:
| Variável de ambiente |
Descrição |
SUBSCRIPTION_ID |
O ID da subscrição que contém a sua instância Operações IoT do Azure. |
RESOURCE_GROUP |
O nome do grupo de recursos que contém a sua instância do Operações IoT do Azure. |
AIO_INSTANCE_NAME |
O nome da sua instância do Operações IoT do Azure. Para listar as suas instâncias, execute az iot ops list -o table. |
CLUSTER_NAME |
O nome do cluster Kubernetes com Azure Arc que hospeda a sua instância. |
LOCATION |
A região do Azure deve ser usada para novos recursos, por exemplo eastus. |
SUBSCRIPTION_ID=<subscription-id>
RESOURCE_GROUP=<resource-group-name>
AIO_INSTANCE_NAME=<instance-name>
CLUSTER_NAME=<cluster-name>
LOCATION=<region>
$SUBSCRIPTION_ID = "<subscription-id>"
$RESOURCE_GROUP = "<resource-group-name>"
$AIO_INSTANCE_NAME = "<instance-name>"
$CLUSTER_NAME = "<cluster-name>"
$LOCATION = "<region>"
Só precisa de definir as variáveis que este artigo utiliza. Este artigo pode usar variáveis adicionais de ambiente para nomes de recursos que escolher. O artigo explica como posicioná-los onde são apresentados.
Uma transformação de filtro avalia cada mensagem recebida de acordo com uma ou mais regras e decide se a mensagem continua pelo pipeline ou se é eliminada.
Importante
Uma expressão de filtro seleciona as mensagens a remover, não as a manter. Quando a expressão é verdadeira, a mensagem é omitida. Este comportamento é o oposto de uma expressão de mapa, que calcula um valor que é mantido.
Para manter as mensagens que correspondem a uma condição, inverta a expressão. Por exemplo, para manter apenas leituras acima de 90, filtre em $1 <= 90.
Como funcionam as regras de filtro
Cada regra de filtro tem estas propriedades:
| Propriedade |
Obrigatório |
Descrição |
inputs |
Sim |
Lista de caminhos de campo a ler da mensagem recebida. |
expression |
Sim |
Fórmula aplicada aos valores de entrada. Tem de devolver um booleano. Quando isso retorna verdadeiro, a mensagem é descartada. |
description |
No |
Etiqueta legível por humanos usada em mensagens de erro. |
Cada entrada corresponde a uma variável posicional com base na sua ordem: a primeira entrada é $1, a segunda é $2, e assim sucessivamente.
Quando defines múltiplas regras, elas usam lógica OR: se alguma regra for avaliada como verdadeira, a mensagem é descartada. O motor entra em curto-circuito assim que uma regra corresponde.
Restrições principais:
- A expressão é necessária. Cada regra de filtro deve incluir um
expression.
-
filter Aceita uma matriz. Fornece regras como um array JSON, "filter": [ { ... } ], mesmo para uma única regra. Passar um objeto simples não consegue carregar a transformação, e o erro resultante aponta para o artefacto e o repositório, em vez do payload de regras. Esta restrição difere de branch, que toma um único objeto.
- Sem entradas imprevisíveis. Cada entrada deve referenciar um caminho de campo específico.
- Campos em falta causam erros. Se um campo referenciado em
inputs não existir, o filtro devolve um erro em vez de passar a mensagem silenciosamente.
- Resultados não booleanos causam erros. Se uma expressão devolver um valor não booleano (como uma cadeia ou número), o filtro devolve um erro.
Descartar mensagens por condição
Para descartar mensagens se a temperatura ultrapassar 100:
Na configuração de transformação de filtro, adicione uma regra:
| Configuração |
Value |
|
Input |
temperature |
|
Expressão |
$1 > 100 |
A CLI aplica todo o grafo a partir de um ficheiro de configuração. Adicione este excerto no local correspondente em seu graph.json e aplique-o usando az iot ops dataflowgraph apply.
"filter": [
{
"inputs": [
"temperature"
],
"expression": "$1 > 100"
}
]
filter: [
{
inputs: [ 'temperature' ]
expression: '$1 > 100'
}
]
Importante
A utilização dos manifestos de implementação do Kubernetes não é suportada em ambientes de produção e deve ser usada apenas para depuração e testes.
- inputs:
- temperature # $1
expression: "$1 > 100"
Mensagens em que a temperatura é 100 graus ou menos passam. Mensagens acima de 100 são eliminadas.
Manter mensagens por condição
Muitas vezes, queres o resultado oposto: manter apenas as mensagens que correspondem a uma condição. Como uma expressão de filtro seleciona o que remover, inverta a comparação.
Para manter apenas leituras acima de 90, reduza tudo a 90 ou abaixo:
Na configuração de transformação de filtro, adicione uma regra:
| Configuração |
Value |
|
Input |
temperature |
|
Expressão |
$1 <= 90 |
|
Description |
Drop readings at or below 90 |
A CLI aplica todo o grafo a partir de um ficheiro de configuração. Adicione este excerto no local correspondente em seu graph.json e aplique-o usando az iot ops dataflowgraph apply.
"filter": [
{
"inputs": [
"temperature"
],
"expression": "$1 <= 90",
"description": "Drop readings at or below 90"
}
]
filter: [
{
inputs: [ 'temperature' ]
expression: '$1 <= 90'
description: 'Drop readings at or below 90'
}
]
Importante
A utilização dos manifestos de implementação do Kubernetes não é suportada em ambientes de produção e deve ser usada apenas para depuração e testes.
- inputs:
- temperature # $1
expression: "$1 <= 90"
description: "Drop readings at or below 90"
Apenas mensagens com valores superiores a 90 continuam através do pipeline. Escrever $1 > 90 aqui faria o oposto do que queres: descartaria todas as leituras acima de 90 e manteria as mais baixas.
Sugestão
Use o campo description para registar a intenção da regra relativamente ao que esta descarta. Uma descrição como Drop readings at or below 90 mantém-se precisa, enquanto Keep hot readings convida ao erro de expressão invertida e aparece em mensagens de erro que depois se lêem ao contrário.
Usar múltiplas condições
Quando definires mais do que uma regra, o filtro elimina a mensagem se qualquer regra for correspondida.
Adicione duas regras:
| Entrada |
Expression |
Descrição |
temperature |
$1 > 100 |
Queda de temperatura elevada |
humidity |
$1 > 95 |
Redução da humidade elevada |
A CLI aplica todo o grafo a partir de um ficheiro de configuração. Adicione este excerto no local correspondente em seu graph.json e aplique-o usando az iot ops dataflowgraph apply.
"filter": [
{
"inputs": [
"temperature"
],
"expression": "$1 > 100",
"description": "Drop high temperature"
},
{
"inputs": [
"humidity"
],
"expression": "$1 > 95",
"description": "Drop high humidity"
}
]
filter: [
{
inputs: [ 'temperature' ]
expression: '$1 > 100'
description: 'Drop high temperature'
}
{
inputs: [ 'humidity' ]
expression: '$1 > 95'
description: 'Drop high humidity'
}
]
Importante
A utilização dos manifestos de implementação do Kubernetes não é suportada em ambientes de produção e deve ser usada apenas para depuração e testes.
- inputs:
- temperature # $1
expression: "$1 > 100"
description: "Drop high temperature"
- inputs:
- humidity # $1
expression: "$1 > 95"
description: "Drop high humidity"
| Mensagem |
Regra da temperatura |
Regra da humidade |
Result |
{"temperature": 150, "humidity": 60} |
verdadeiro |
falso |
Caiu |
{"temperature": 80, "humidity": 98} |
falso |
verdadeiro |
Caiu |
{"temperature": 80, "humidity": 60} |
falso |
falso |
Passes |
Sugestão
Usa múltiplas entradas numa regra quando precisares de lógica AND entre campos. Use múltiplas regras quando precisar de lógica OU em condições independentes.
Usar expressões complexas
Referenciar múltiplos campos numa única regra e combiná-los com operadores lógicos:
Adicione uma regra com entradas temperature e humidity, e expressão $1 > 30 && $2 < 60.
A CLI aplica todo o grafo a partir de um ficheiro de configuração. Adicione este excerto no local correspondente em seu graph.json e aplique-o usando az iot ops dataflowgraph apply.
"filter": [
{
"inputs": [
"temperature",
"humidity"
],
"expression": "$1 > 30 && $2 < 60",
"description": "Drop hot and dry readings"
}
]
filter: [
{
inputs: [ 'temperature', 'humidity' ]
expression: '$1 > 30 && $2 < 60'
description: 'Drop hot and dry readings'
}
]
Importante
A utilização dos manifestos de implementação do Kubernetes não é suportada em ambientes de produção e deve ser usada apenas para depuração e testes.
- inputs:
- temperature # $1
- humidity # $2
expression: "$1 > 30 && $2 < 60"
description: "Drop hot and dry readings"
Para a lista completa de operadores e funções, veja Referência de expressões.
Validar mensagens de filtro contra um esquema
Configure uma transformação de filtro para validar mensagens recebidas contra um esquema JSON antes da execução das regras de filtro. O processo deixa de enviar mensagens que não seguem o esquema.
Para permitir a validação do esquema, defina validateSchema como true na configuração do filtro. Quando ativado, o filtro recupera o esquema da schemaRef ligação ao nó de entrada (o from lado da nodeConnections entrada que alimenta o nó do filtro).
A configuração da transformação do filtro inclui uma caixa de verificação Validar esquema. No entanto, a experiência operacional atualmente não suporta configurar ou visualizar as schemaRef ligações on-node. Para usar a validação de esquema, configure o schemaRef da ligação ao nó através de manifestos Bicep ou Kubernetes.
A CLI aplica o grafo completo a partir de um ficheiro de configuração, por isso adiciona isto ao local correspondente no teu graph.json e aplica-o com az iot ops dataflowgraph apply. No graph.json ficheiro, as regras de cada transformação são armazenadas no value campo como uma string JSON escapada. Para a forma legível das regras de cada transformação, veja o tutorial para esse tipo de transformação.
"nodes": [
{
"nodeType": "Graph",
"name": "schema-filter",
"graphSettings": {
"registryEndpointRef": "default",
"artifact": "azureiotoperations/graph-dataflow-filter:1.0.0",
"configuration": [
{
"key": "rules",
"value": "{\"validateSchema\":true,\"filter\":[]}"
}
]
}
}
],
"nodeConnections": [
{
"from": {
"name": "sensors",
"schema": {
"schemaRef": "aio-sr://my-namespace/sensor-schema:1",
"serializationFormat": "Json"
}
},
"to": {
"name": "schema-filter"
}
}
]
Sugestão
Para gerar a string escapada, guarde as regras num ficheiro como rules.json, execute jq -c . rules.json, e cole a saída de linha única no value campo.
Inclua validateSchema nas regras de filtro JSON e configure schemaRef na ligação do nó de entrada:
nodes: [
{
nodeType: 'Graph'
name: 'schema-filter'
graphSettings: {
registryEndpointRef: 'default'
artifact: 'azureiotoperations/graph-dataflow-filter:1.0.0'
configuration: [
{
key: 'rules'
value: '{"validateSchema":true,"filter":[]}'
}
]
}
}
]
nodeConnections: [
{
from: {
name: 'sensors'
schema: {
schemaRef: 'aio-sr://my-namespace/sensor-schema:1'
serializationFormat: 'Json'
}
}
to: { name: 'schema-filter' }
}
]
Importante
A utilização dos manifestos de implementação do Kubernetes não é suportada em ambientes de produção e deve ser usada apenas para depuração e testes.
nodes:
- nodeType: Graph
name: schema-filter
graphSettings:
registryEndpointRef: default
artifact: azureiotoperations/graph-dataflow-filter:1.0.0
configuration:
- key: rules
value: |
{
"validateSchema": true,
"filter": []
}
nodeConnections:
- from:
name: sensors
schema:
schemaRef: "aio-sr://my-namespace/sensor-schema:1"
serializationFormat: Json
to:
name: schema-filter
Orientações:
- Use apenas um filtro de validação por pipeline.
- Coloque primeiro o filtro de validação para que mensagens inválidas sejam descartadas antes de outros processamentos.
- As regras de filtro continuam a aplicar-se após a validação do esquema ser aprovada. Se só precisares de validação do esquema, deixa as regras de filtro vazias.
- O
schemaRef deve apontar para um esquema no registo de esquemas. O serializationFormat especifica o formato do esquema (por exemplo, Json).
Para aprender sobre a configuração de esquemas, veja Compreender esquemas de mensagens.
Enriquecer regras de filtro com dados externos
As regras de filtro suportam conjuntos de dados, que permitem comparar valores com dados de um armazenamento de estados externo. Para detalhes sobre a configuração de conjuntos de dados, consulte Enriquecer com dados externos.
Configuração completa do filtro
Na configuração de transformação de filtro, adiciona-se uma ou mais regras com entradas e expressões booleanas. Opcionalmente, ative a validação de esquemas e configure conjuntos de dados para consultas de enriquecimento.
A CLI aplica o grafo completo a partir de um ficheiro de configuração, por isso adiciona isto ao configuration do nó de transformação no teu graph.json e aplica-o com az iot ops dataflowgraph apply.
As regras são um objeto JSON:
{
"datasets": [
{
"key": "device_limits as limits",
"inputs": ["$source.deviceId", "$context.deviceId"],
"expression": "$1 == $2"
}
],
"filter": [
{
"inputs": ["temperature"],
"expression": "$1 > 100",
"description": "Drop high temperature readings"
},
{
"inputs": ["rawValue", "$context(limits).maxValue"],
"expression": "$1 > $2",
"description": "Drop readings above device-specific limit"
}
]
}
Estas regras entram no value campo como uma sequência escapada:
"configuration": [
{
"key": "rules",
"value": "{\"datasets\":[{\"key\":\"device_limits as limits\",\"inputs\":[\"$source.deviceId\",\"$context.deviceId\"],\"expression\":\"$1 == $2\"}],\"filter\":[{\"inputs\":[\"temperature\"],\"expression\":\"$1 > 100\",\"description\":\"Drop high temperature readings\"},{\"inputs\":[\"rawValue\",\"$context(limits).maxValue\"],\"expression\":\"$1 > $2\",\"description\":\"Drop readings above device-specific limit\"}]}"
}
]
As regras de filtro JSON são passadas como argumento para a chave valuerules.
configuration: [
{
key: 'rules'
value: '{"datasets":[{"key":"device_limits as limits","inputs":["$source.deviceId","$context.deviceId"],"expression":"$1 == $2"}],"filter":[{"inputs":["temperature"],"expression":"$1 > 100","description":"Drop high temperature readings"},{"inputs":["rawValue","$context(limits).maxValue"],"expression":"$1 > $2","description":"Drop readings above device-specific limit"}]}'
}
]
Importante
A utilização dos manifestos de implementação do Kubernetes não é suportada em ambientes de produção e deve ser usada apenas para depuração e testes.
{
"datasets": [
{
"key": "device_limits as limits",
"inputs": ["$source.deviceId", "$context.deviceId"],
"expression": "$1 == $2"
}
],
"filter": [
{
"inputs": ["temperature"],
"expression": "$1 > 100",
"description": "Drop high temperature readings"
},
{
"inputs": ["rawValue", "$context(limits).maxValue"],
"expression": "$1 > $2",
"description": "Drop readings above device-specific limit"
}
]
}
| Key |
Obrigatório |
Descrição |
filter |
Sim |
Conjunto de regras de filtro. |
datasets |
No |
Array de definições de conjuntos de dados para consultas de enriquecimento. |
validateSchema |
No |
Quando true, valida mensagens contra um esquema JSON antes da execução das regras de filtro. O padrão é false. |
Uma transformada de desvio avalia uma condição em cada mensagem de entrada e encaminha-a para um de dois caminhos de saída: true ou false. Ao contrário de um filtro (que elimina mensagens), um ramo preserva todas as mensagens e encaminha-as pelo caminho apropriado.
Como funciona a ramificação
Cada mensagem vai exatamente para um dos dois caminhos. Nada é deixado cair.
Restrições principais:
- A expressão do ramo deve devolver um booleano. Resultados não booleanos causam um erro.
-
Sem entradas imprevisíveis.
- Exatamente uma regra de ramo. A
branch chave leva um único objeto, não um array.
Importante
A ramificação divide as mensagens em caminhos de processamento separados, mas todos os caminhos devem fundir-se novamente através de uma transformação de concatenação antes de chegarem ao destino. Pensa na ramificação como uma forma de aplicar diferentes transformações a diferentes mensagens, não como uma forma de encaminhar para múltiplos endpoints.
Defina uma regra de ramo
Para ramificar mensagens com base num limiar de gravidade:
Na configuração da transformada de ramo, defina:
| Configuração |
Value |
|
Input |
severity |
|
Expressão |
$1 > 5 |
A CLI aplica o grafo completo a partir de um ficheiro de configuração, por isso adiciona isto ao configuration do nó de transformação no teu graph.json e aplica-o com az iot ops dataflowgraph apply.
As regras são um objeto JSON:
{
"branch": {
"inputs": ["severity"],
"expression": "$1 > 5",
"description": "Route high-severity messages"
}
}
Estas regras entram no value campo como uma sequência escapada:
"configuration": [
{
"key": "rules",
"value": "{\"branch\":{\"inputs\":[\"severity\"],\"expression\":\"$1 > 5\",\"description\":\"Route high-severity messages\"}}"
}
]
configuration: [
{
key: 'rules'
value: '{"branch":{"inputs":["severity"],"expression":"$1 > 5","description":"Route high-severity messages"}}'
}
]
Importante
A utilização dos manifestos de implementação do Kubernetes não é suportada em ambientes de produção e deve ser usada apenas para depuração e testes.
{
"branch": {
"inputs": ["severity"],
"expression": "$1 > 5",
"description": "Route high-severity messages"
}
}
Mensagens onde severity é maior que 5 vão para o true caminho. Todos os outros seguem o false caminho.
Validar mensagens de desvio contra um esquema
A partir da versão 1.1.0, pode configurar uma transformação de ramificação para validar as mensagens recebidas em relação a um esquema JSON antes de avaliar a expressão de ramificação.
Para permitir a validação do esquema, defina validateSchema para true na configuração do ramo. O validateSchema campo é opcional e por defeito é false. Quando ativado, o ramo recupera o esquema da schemaRef ligação do nó de entrada (o from lado da nodeConnections entrada que alimenta o nó do ramo).
- As mensagens que passam a validação do esquema prosseguem para a avaliação do ramo.
- As mensagens que falham na validação do esquema vão para o
false caminho.
A configuração da transformação de ramificação inclui uma caixa de verificação Validar esquema. No entanto, a experiência operacional atualmente não suporta configurar ou visualizar as schemaRef ligações on-node. Para usar a validação de esquema, configure o schemaRef da ligação ao nó através de manifestos Bicep ou Kubernetes.
A CLI aplica o grafo completo a partir de um ficheiro de configuração, por isso adiciona isto ao local correspondente no teu graph.json e aplica-o com az iot ops dataflowgraph apply. No graph.json ficheiro, as regras de cada transformação são armazenadas no value campo como uma string JSON escapada. Para a forma legível das regras de cada transformação, veja o tutorial para esse tipo de transformação.
"nodes": [
{
"nodeType": "Graph",
"name": "schema-branch",
"graphSettings": {
"registryEndpointRef": "default",
"artifact": "azureiotoperations/graph-dataflow-branch:1.1.0",
"configuration": [
{
"key": "rules",
"value": "{\"validateSchema\":true,\"branch\":{\"inputs\":[\"severity\"],\"expression\":\"$1 > 5\"}}"
}
]
}
}
],
"nodeConnections": [
{
"from": {
"name": "sensors",
"schema": {
"schemaRef": "aio-sr://my-namespace/sensor-schema:1",
"serializationFormat": "Json"
}
},
"to": {
"name": "schema-branch"
}
}
]
Sugestão
Para gerar a string escapada, guarde as regras num ficheiro como rules.json, execute jq -c . rules.json, e cole a saída de linha única no value campo.
Inclua validateSchema nas regras de desvio JSON e configure schemaRef na ligação do nó de entrada:
nodes: [
{
nodeType: 'Graph'
name: 'schema-branch'
graphSettings: {
registryEndpointRef: 'default'
artifact: 'azureiotoperations/graph-dataflow-branch:1.1.0'
configuration: [
{
key: 'rules'
value: '{"validateSchema":true,"branch":{"inputs":["severity"],"expression":"$1 > 5"}}'
}
]
}
}
]
nodeConnections: [
{
from: {
name: 'sensors'
schema: {
schemaRef: 'aio-sr://my-namespace/sensor-schema:1'
serializationFormat: 'Json'
}
}
to: { name: 'schema-branch' }
}
]
Importante
A utilização dos manifestos de implementação do Kubernetes não é suportada em ambientes de produção e deve ser usada apenas para depuração e testes.
nodes:
- nodeType: Graph
name: schema-branch
graphSettings:
registryEndpointRef: default
artifact: azureiotoperations/graph-dataflow-branch:1.1.0
configuration:
- key: rules
value: |
{
"validateSchema": true,
"branch": {
"inputs": ["severity"],
"expression": "$1 > 5"
}
}
nodeConnections:
- from:
name: sensors
schema:
schemaRef: "aio-sr://my-namespace/sensor-schema:1"
serializationFormat: Json
to:
name: schema-branch
Ligar saídas de ramificações
Na configuração do pipeline, use o nome do nó seguido de .output.true ou .output.false para ligar cada caminho a uma transformação a jusante.
No editor de grafos de fluxo de dados, arraste as ligações das saídas verdadeira e falsa da transformada de desvio para as transformadas a jusante apropriadas.
A interface de linha de comandos (CLI) aplica o grafo completo a partir de um único ficheiro de configuração, por isso adiciona isto no local correspondente do teu graph.json e aplica-o com az iot ops dataflowgraph apply:
"nodeConnections": [
{
"from": {
"name": "sensors"
},
"to": {
"name": "severity-check"
}
},
{
"from": {
"name": "severity-check.output.true"
},
"to": {
"name": "alert-transform"
}
},
{
"from": {
"name": "severity-check.output.false"
},
"to": {
"name": "normal-transform"
}
}
]
nodeConnections: [
{ from: { name: 'sensors' }, to: { name: 'severity-check' } }
{ from: { name: 'severity-check.output.true' }, to: { name: 'alert-transform' } }
{ from: { name: 'severity-check.output.false' }, to: { name: 'normal-transform' } }
]
Importante
A utilização dos manifestos de implementação do Kubernetes não é suportada em ambientes de produção e deve ser usada apenas para depuração e testes.
nodeConnections:
- from: { name: sensors }
to: { name: severity-check }
- from: { name: severity-check.output.true }
to: { name: alert-transform }
- from: { name: severity-check.output.false }
to: { name: normal-transform }
Fundir caminhos com concatenação
Todos os caminhos de ramificação devem convergir antes de chegar a um destino. Uma transformação de concatenação funde-os. Não tem configuração nem regras. As mensagens de todas as entradas ligadas passam sem modificações.
Adicione uma transformação de concatenação ao painel e ligue ambos os caminhos das ramificações a ela, depois ligue a concatenação ao destino.
A interface de linha de comandos (CLI) aplica o grafo completo a partir de um único ficheiro de configuração, por isso adiciona isto no local correspondente do teu graph.json e aplica-o com az iot ops dataflowgraph apply:
{
"nodeType": "Graph",
"name": "merge",
"graphSettings": {
"registryEndpointRef": "default",
"artifact": "azureiotoperations/graph-dataflow-concatenate:1.0.0"
}
}
{
nodeType: 'Graph'
name: 'merge'
graphSettings: {
registryEndpointRef: 'default'
artifact: 'azureiotoperations/graph-dataflow-concatenate:1.0.0'
}
}
Importante
A utilização dos manifestos de implementação do Kubernetes não é suportada em ambientes de produção e deve ser usada apenas para depuração e testes.
- nodeType: Graph
name: merge
graphSettings:
registryEndpointRef: default
artifact: azureiotoperations/graph-dataflow-concatenate:1.0.0
Exemplo: filtrar, ramificar e fundir
Este exemplo completo filtra leituras erróneas, faz a ramificação segundo a severidade, aplica diferentes transformações de mapa a cada caminho e combina os resultados.
Para construir este pipeline na experiência operacional:
- Crie um grafo de fluxo de dados e adicione uma fonte que leia de
telemetry/sensors.
- Adiciona uma transformação de filtro. Configure uma regra que elimine mensagens onde
temperature > 1000.
- Adicione uma transformação de ramificação . Configure a condição
severity > 5 para encaminhar mensagens de alta gravidade para o caminho verdadeiro.
- Adiciona uma transformação de mapa no caminho verdadeiro. Configure regras para renomear
deviceId para id, temperature para temp, e adicione um campo alert definido para true.
- Adicione uma transformação de mapa no trajeto falso. Configure regras para renomear
deviceId para id e temperature para temp.
- Adicione uma transformação de concatenação para unir os dois caminhos.
- Adicione um destino que envie para
telemetry/processed.
- Ligue os elementos: fonte → filtro → ramificação → (caminho verdadeiro: mapa de alerta, caminho falso: mapa normal) → concatenar → destino.
A CLI do Azure aplica um grafo de fluxo de dados a partir de um único ficheiro de configuração JSON. Cria um graph.json ficheiro com as propriedades do grafo. No graph.json ficheiro, as regras de cada transformação são armazenadas no value campo como uma string JSON escapada. Para a forma legível das regras de cada transformação, veja o tutorial para esse tipo de transformação.
{
"mode": "Enabled",
"nodes": [
{
"nodeType": "Source",
"name": "sensors",
"sourceSettings": {
"endpointRef": "default",
"dataSources": [
"telemetry/sensors"
]
}
},
{
"nodeType": "Graph",
"name": "remove-bad-data",
"graphSettings": {
"registryEndpointRef": "default",
"artifact": "azureiotoperations/graph-dataflow-filter:1.0.0",
"configuration": [
{
"key": "rules",
"value": "{\"filter\":[{\"inputs\":[\"temperature\"],\"expression\":\"$1 > 1000\",\"description\":\"Drop impossible temperature readings\"}]}"
}
]
}
},
{
"nodeType": "Graph",
"name": "severity-check",
"graphSettings": {
"registryEndpointRef": "default",
"artifact": "azureiotoperations/graph-dataflow-branch:1.1.0",
"configuration": [
{
"key": "rules",
"value": "{\"branch\":{\"inputs\":[\"severity\"],\"expression\":\"$1 > 5\",\"description\":\"Route high-severity messages\"}}"
}
]
}
},
{
"nodeType": "Graph",
"name": "alert-transform",
"graphSettings": {
"registryEndpointRef": "default",
"artifact": "azureiotoperations/graph-dataflow-map:1.0.0",
"configuration": [
{
"key": "rules",
"value": "{\"map\":[{\"inputs\":[\"deviceId\"],\"output\":\"id\"},{\"inputs\":[\"temperature\"],\"output\":\"temp\"},{\"inputs\":[],\"output\":\"alert\",\"expression\":\"true\"}]}"
}
]
}
},
{
"nodeType": "Graph",
"name": "normal-transform",
"graphSettings": {
"registryEndpointRef": "default",
"artifact": "azureiotoperations/graph-dataflow-map:1.0.0",
"configuration": [
{
"key": "rules",
"value": "{\"map\":[{\"inputs\":[\"deviceId\"],\"output\":\"id\"},{\"inputs\":[\"temperature\"],\"output\":\"temp\"}]}"
}
]
}
},
{
"nodeType": "Graph",
"name": "merge",
"graphSettings": {
"registryEndpointRef": "default",
"artifact": "azureiotoperations/graph-dataflow-concatenate:1.0.0"
}
},
{
"nodeType": "Destination",
"name": "output",
"destinationSettings": {
"endpointRef": "default",
"dataDestination": "telemetry/processed"
}
}
],
"nodeConnections": [
{
"from": {
"name": "sensors"
},
"to": {
"name": "remove-bad-data"
}
},
{
"from": {
"name": "remove-bad-data"
},
"to": {
"name": "severity-check"
}
},
{
"from": {
"name": "severity-check.output.true"
},
"to": {
"name": "alert-transform"
}
},
{
"from": {
"name": "severity-check.output.false"
},
"to": {
"name": "normal-transform"
}
},
{
"from": {
"name": "alert-transform"
},
"to": {
"name": "merge"
}
},
{
"from": {
"name": "normal-transform"
},
"to": {
"name": "merge"
}
},
{
"from": {
"name": "merge"
},
"to": {
"name": "output"
}
}
]
}
Aplica o ficheiro de configuração.
az iot ops dataflowgraph apply \
--name alert-routing \
--instance $AIO_INSTANCE_NAME \
--resource-group $RESOURCE_GROUP \
--config-file graph.json
resource dataflowGraph 'Microsoft.IoTOperations/instances/dataflowProfiles/dataflowGraphs@2026-03-01' = {
name: 'alert-routing'
parent: dataflowProfile
properties: {
profileRef: dataflowProfileName
mode: 'Enabled'
nodes: [
{
nodeType: 'Source'
name: 'sensors'
sourceSettings: {
endpointRef: 'default'
dataSources: [ 'telemetry/sensors' ]
}
}
{
nodeType: 'Graph'
name: 'remove-bad-data'
graphSettings: {
registryEndpointRef: 'default'
artifact: 'azureiotoperations/graph-dataflow-filter:1.0.0'
configuration: [
{
key: 'rules'
value: '{"filter":[{"inputs":["temperature"],"expression":"$1 > 1000","description":"Drop impossible temperature readings"}]}'
}
]
}
}
{
nodeType: 'Graph'
name: 'severity-check'
graphSettings: {
registryEndpointRef: 'default'
artifact: 'azureiotoperations/graph-dataflow-branch:1.1.0'
configuration: [
{
key: 'rules'
value: '{"branch":{"inputs":["severity"],"expression":"$1 > 5","description":"Route high-severity messages"}}'
}
]
}
}
{
nodeType: 'Graph'
name: 'alert-transform'
graphSettings: {
registryEndpointRef: 'default'
artifact: 'azureiotoperations/graph-dataflow-map:1.0.0'
configuration: [
{
key: 'rules'
value: '{"map":[{"inputs":["deviceId"],"output":"id"},{"inputs":["temperature"],"output":"temp"},{"inputs":[],"output":"alert","expression":"true"}]}'
}
]
}
}
{
nodeType: 'Graph'
name: 'normal-transform'
graphSettings: {
registryEndpointRef: 'default'
artifact: 'azureiotoperations/graph-dataflow-map:1.0.0'
configuration: [
{
key: 'rules'
value: '{"map":[{"inputs":["deviceId"],"output":"id"},{"inputs":["temperature"],"output":"temp"}]}'
}
]
}
}
{
nodeType: 'Graph'
name: 'merge'
graphSettings: {
registryEndpointRef: 'default'
artifact: 'azureiotoperations/graph-dataflow-concatenate:1.0.0'
}
}
{
nodeType: 'Destination'
name: 'output'
destinationSettings: {
endpointRef: 'default'
dataDestination: 'telemetry/processed'
}
}
]
nodeConnections: [
{ from: { name: 'sensors' }, to: { name: 'remove-bad-data' } }
{ from: { name: 'remove-bad-data' }, to: { name: 'severity-check' } }
{ from: { name: 'severity-check.output.true' }, to: { name: 'alert-transform' } }
{ from: { name: 'severity-check.output.false' }, to: { name: 'normal-transform' } }
{ from: { name: 'alert-transform' }, to: { name: 'merge' } }
{ from: { name: 'normal-transform' }, to: { name: 'merge' } }
{ from: { name: 'merge' }, to: { name: 'output' } }
]
}
}
Importante
A utilização dos manifestos de implementação do Kubernetes não é suportada em ambientes de produção e deve ser usada apenas para depuração e testes.
apiVersion: connectivity.iotoperations.azure.com/v1
kind: DataflowGraph
metadata:
name: alert-routing
namespace: azure-iot-operations
spec:
profileRef: default
nodes:
- nodeType: Source
name: sensors
sourceSettings:
endpointRef: default
dataSources:
- telemetry/sensors
- nodeType: Graph
name: remove-bad-data
graphSettings:
registryEndpointRef: default
artifact: azureiotoperations/graph-dataflow-filter:1.0.0
configuration:
- key: rules
value: |
{
"filter": [
{
"inputs": ["temperature"],
"expression": "$1 > 1000",
"description": "Drop impossible temperature readings"
}
]
}
- nodeType: Graph
name: severity-check
graphSettings:
registryEndpointRef: default
artifact: azureiotoperations/graph-dataflow-branch:1.1.0
configuration:
- key: rules
value: |
{
"branch": {
"inputs": ["severity"],
"expression": "$1 > 5",
"description": "Route high-severity messages"
}
}
- nodeType: Graph
name: alert-transform
graphSettings:
registryEndpointRef: default
artifact: azureiotoperations/graph-dataflow-map:1.0.0
configuration:
- key: rules
value: |
{
"map": [
{ "inputs": ["deviceId"], "output": "id" },
{ "inputs": ["temperature"], "output": "temp" },
{ "inputs": [], "output": "alert", "expression": "true" }
]
}
- nodeType: Graph
name: normal-transform
graphSettings:
registryEndpointRef: default
artifact: azureiotoperations/graph-dataflow-map:1.0.0
configuration:
- key: rules
value: |
{
"map": [
{ "inputs": ["deviceId"], "output": "id" },
{ "inputs": ["temperature"], "output": "temp" }
]
}
- nodeType: Graph
name: merge
graphSettings:
registryEndpointRef: default
artifact: azureiotoperations/graph-dataflow-concatenate:1.0.0
- nodeType: Destination
name: output
destinationSettings:
endpointRef: default
dataDestination: telemetry/processed
nodeConnections:
- from: { name: sensors }
to: { name: remove-bad-data }
- from: { name: remove-bad-data }
to: { name: severity-check }
- from: { name: severity-check.output.true }
to: { name: alert-transform }
- from: { name: severity-check.output.false }
to: { name: normal-transform }
- from: { name: alert-transform }
to: { name: merge }
- from: { name: normal-transform }
to: { name: merge }
- from: { name: merge }
to: { name: output }
Conteúdo relacionado