Como trabalhar com cargas úteis binárias - AWS IoT Core

Como trabalhar com cargas úteis binárias

Para tratar a carga da mensagem como dados binários brutos (em vez de um objeto JSON), você pode usar o operador * para fazer referência a ela em uma cláusula SELECT.

Exemplos de cargas úteis binárias

Ao usar * para se referir à carga da mensagem como dados binários brutos, você pode adicionar dados à regra. Se você tiver uma carga vazia ou JSON, a carga resultante poderá ter dados adicionados usando a regra. Veja a seguir exemplos de cláusulas SELECT compatíveis.

  • Você pode usar as cláusulas SELECT a seguir com apenas um * para cargas binárias.

    • SELECT * FROM 'topic/subtopic'
    • SELECT * FROM 'topic/subtopic' WHERE timestamp() % 12 = 0
  • Você também pode adicionar dados e usar as cláusulas SELECT a seguir.

    • SELECT *, principal() as principal, timestamp() as time FROM 'topic/subtopic'
    • SELECT encode(*, 'base64') AS data, timestamp() AS ts FROM 'topic/subtopic'
  • Você também pode usar essas cláusulas SELECT com cargas binárias.

    • O seguinte se refere ao device_type na cláusula WHERE.

      SELECT * FROM 'topic/subtopic' WHERE device_type = 'thermostat'
    • Também há suporte para:

      { "sql": "SELECT * FROM 'topic/subtopic'", "actions": [ { "republish": { "topic": "device/${device_id}" } } ] }

As ações de regra a seguir não oferecem suporte a cargas binárias, portanto, você deve decodificá-las.

  • Algumas ações de regra não oferecem suporte a entrada de carga útil binária, como a ação do Lambda, então é necessário decodificar cargas úteis binárias. A ação de regra do Lambda poderá receber dados binários se estiverem codificados em base64 e em uma carga útil JSON. É possível fazer isso alterando a regra para a seguinte:

    SELECT encode(*, 'base64') AS data FROM 'my_topic'
  • A instrução SQL não oferece suporte a string como entrada. Para converter uma entrada de string em JSON, é possível executar o seguinte comando.

    SELECT decode(encode(*, 'base64'), 'base64') AS payload FROM 'topic'

Decodificar as cargas úteis da mensagem protobuf

Protocol Buffers (protobuf) é um formato de dados de código aberto usado para serializar dados estruturados em um formato binário compacto. É usado para transmitir dados por redes ou armazená-los em arquivos. O Protobuf permite que você envie dados em pacotes pequenos e em uma taxa mais rápida do que outros formatos de mensagens. AWS IoT Core As regras oferecem suporte ao protobuf fornecendo a função SQL decode (value, decodingScheme), que permite decodificar cargas de mensagens codificadas por protobuf para o formato JSON e roteá-las para serviços downstream. Esta seção detalha o processo passo a passo para configurar a decodificação do protobuf em Regras AWS IoT Core.

Pré-requisitos

Criar arquivos descritores

Se já tiver arquivos de descrição, você poderá ignorar esta etapa. Um arquivo descritor (.desc) é uma versão compilada de um arquivo .proto, que é um arquivo de texto que define as estruturas de dados e os tipos de mensagens a serem usados em uma serialização do protobuf. Para gerar um arquivo descritor, você deve definir um arquivo .proto e usar o compilador protoc para compilá-lo.

  1. Crie arquivos .proto que definam os tipos de mensagem. Um exemplo de arquivo .proto pode ser o seguinte:

    syntax = "proto3"; message Person { optional string name = 1; optional int32 id = 2; optional string email = 3; }

    Neste exemplo de arquivo .proto, você usa a sintaxe proto3 e define o tipo de mensagem Person. A definição da mensagem Person especifica três campos (nome, ID e e-mail). Para obter mais informações sobre formatos de mensagem de arquivo .proto, consulte o Guia de idiomas (proto3).

  2. Use o compilador protoc para compilar os arquivos .proto e gerar um arquivo descritor. Um exemplo de comando para criar um arquivo descritor (.desc) pode ser o seguinte:

    protoc --descriptor_set_out=<FILENAME>.desc \ --proto_path=<PATH_TO_IMPORTS_DIRECTORY> \ --include_imports \ <PROTO_FILENAME>.proto

    Esse exemplo de comando gera um arquivo descritor <FILENAME>.desc, que as regras de AWS IoT Core podem usar para decodificar cargas de protobuf que estejam em conformidade com a estrutura de dados definida em <PROTO_FILENAME>.proto.

    • --descriptor_set_out

      Especifica o nome do arquivo descritor (<FILENAME>.desc) que deve ser gerado.

    • --proto_path

      Especifica os locais de todos os arquivos .proto importados referenciados pelo arquivo que está sendo compilado. Você pode especificar o sinalizador várias vezes se tiver vários arquivos .proto importados com locais diferentes.

    • --include_imports

      Especifica que todos os arquivos .proto importados também devem ser compilados e incluídos no arquivo <FILENAME>.desc descritor.

    • <PROTO_FILENAME>.proto

      Especifica o nome do arquivo .proto que você deseja compilar.

    Para obter mais informações sobre a referência protoc, consulte Referência de API.

Upload de arquivos descritores em um bucket do S3

Depois de criar seus <FILENAME>.desc dos arquivos descritores, faça o upload dos <FILENAME>.desc dos arquivos descritores em um bucket do Amazon S3 usando a API da AWS, o AWS SDK ou o Console de gerenciamento da AWS.

Considerações importantes

  • Certifique-se de fazer o upload dos arquivos do descritor em um bucket do Amazon S3 na Conta da AWS na mesma Região da AWS em que você pretende configurar suas regras.

  • Certifique-se de conceder acesso AWS IoT Core para ler o FileDescriptorSet do S3. Se o seu bucket do S3 tiver a criptografia do lado do servidor (SSE) desativada ou se o bucket do S3 estiver criptografado usando chaves gerenciadas pelo Amazon S3 (SSE-S3), nenhuma configuração adicional de política será necessária. Isso pode ser feito com o exemplo de política de bucket:

    JSON
    { "Version":"2012-10-17", "Statement": [ { "Sid": "Statement1", "Effect": "Allow", "Principal": { "Service": "iot.amazonaws.com" }, "Action": "s3:Get*", "Resource": "arn:aws:s3:::<BUCKET NAME>/<FILENAME>.desc" } ] }
  • Se o bucket do S3 for criptografado usando uma chave AWS Key Management Service (SSE-KMS), certifique-se de conceder permissão do AWS IoT Core para usar a chave ao acessar o bucket do S3. Você pode fazer isso adicionando esta declaração à sua política de chave:

    { "Sid": "Statement1", "Effect": "Allow", "Principal": { "Service": "iot.amazonaws.com" }, "Action": [ "kms:Decrypt", "kms:GenerateDataKey*", "kms:DescribeKey" ], "Resource": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab" }

Configurar a decodificação do protobuf em Regras

Depois de fazer o upload dos arquivos do descritor no bucket do Amazon S3, configure uma regra que possa decodificar o formato de carga útil da mensagem protobuf usando a função SQL decode(value, decodingScheme). Uma assinatura de função detalhada e um exemplo podem ser encontrados na função SQL decode(value, decodingScheme) da referência SQL de AWS IoT.

Veja a seguir um exemplo de expressão SQL usando a função decode(value, decodingScheme):

SELECT VALUE decode(*, 'proto', '<BUCKET NAME>', '<FILENAME>.desc', '<PROTO_FILENAME>', '<PROTO_MESSAGE_TYPE>') FROM '<MY_TOPIC>'

Neste exemplo de expressão:

  • Você usa a função SQL decode(value, decodingScheme) para decodificar a carga útil da mensagem binária referenciada por *. Isso pode ser uma carga binária codificada por protobuf ou uma string JSON que representa uma carga útil protobuf codificada em base64.

  • A carga útil da mensagem fornecida é codificada usando o tipo de mensagem Person definido em PROTO_FILENAME.proto.

  • O bucket do Amazon S3 chamado BUCKET NAME contém o FILENAME.desc gerado de PROTO_FILENAME.proto.

Depois de concluir a configuração, publique uma mensagem no AWS IoT Core no tópico no qual a Regra está inscrita.

Limitações

As regras deAWS IoT Core oferecem suporte ao protobuf com as seguintes limitações:

  • A decodificação de cargas de mensagens protobuf em modelos de substituição não é suportada.

  • Ao decodificar cargas de mensagens protobuf, você pode usar a função decodificar SQL em uma única expressão SQL até duas vezes.

  • O tamanho máximo da carga útil de entrada é 128 KiB (1 KiB = 1024 bytes), o tamanho máximo da carga de saída é 128 KiB e o tamanho máximo de um objeto FileDescriptorSet armazenado em um bucket do Amazon S3 é 32 KiB.

  • Não há suporte para buckets do Amazon S3 criptografados com a criptografia SSE-C.

Práticas recomendadas

Veja a seguir algumas práticas recomendadas e dicas de solução de problemas.

  • Carregue seus arquivos proto no bucket no Amazon S3.

    É uma prática recomendada fazer backup de seus arquivos proto caso algo dê errado. Por exemplo, se você modificar incorretamente os arquivos proto sem backups ao executar protoc, isso pode causar problemas em sua pilha de produção. Há várias maneiras de fazer backup de arquivos em um bucket do Amazon S3. Por exemplo, você pode usar o versionamento em buckets do S3. Para obter mais informações sobre como fazer backup de arquivos em buckets do Amazon S3, consulte o Guia do desenvolvedor do Amazon S3.

  • Configure o registro de AWS IoT para visualizar as entradas de log.

    É uma boa prática configurar o registro de AWS IoT para que você possa verificar os logs de AWS IoT da sua conta no CloudWatch. Quando a consulta SQL de uma regra chama uma função externa, as regras do AWS IoT Core geram uma entrada de log com um eventType de FunctionExecution, que contém o campo de motivo que ajudará você a solucionar falhas. Os possíveis erros incluem um objeto do Amazon S3 não encontrado ou um descritor de arquivo protobuf inválido. Para obter mais informações sobre como configurar o registro de AWS IoT e ver as entradas de log, consulte Configurar o registro de AWS IoT e Entradas de log do mecanismo de regras.

  • Atualize o FileDescriptorSet usando uma nova chave de objeto e atualize a chave de objeto em sua regra.

    Você pode atualizar o FileDescriptorSet fazendo upload de um arquivo de descritor atualizado para o seu bucket do Amazon S3. Suas atualizações do FileDescriptorSet podem levar até 15 minutos para serem refletidas. Para evitar esse atraso, é uma prática recomendada carregar seu FileDescriptorSet atualizado usando uma nova chave de objeto e atualizar a chave de objeto em sua regra.