2. Arquitetura do Agente IoT

Este documento descreve a arquitetura do agente IoT usada pela dojot. Ele define um conjunto de recursos e opções básicas que devem ser seguidos para serem alinhados com a arquitetura dojot.

2.1. Quem deve ler isso?

Desenvolvedores que desejam criar novos agentes IoT para serem usados com a dojot.

2.2. Introdução

Usar dojot envolve lidar com as seguintes entidades:

  • dispositivos físicos: dispositivos que enviam mensagens para agentes IoT. Eles podem ter sensores e podem ser configuráveis, mas isso não é obrigatório. Além disso, eles devem ter algum tipo de conectividade com outros serviços, para que possam enviar suas leituras para esses serviços.

  • usuários: quem envia solicitações a dojot para gerenciar recursos, recuperar dados históricos do dispositivo, criar subscrição, gerenciar fluxos e assim por diante.

  • tenants: separação lógica entre recursos que podem estar associados a vários usuários.

  • recursos: elementos associados a uma entidade específica. Eles são:

    • dispositivos: representação de um elemento que possui atributos. Esse elemento pode ser um dispositivo físico ou virtual - um que não recebe atualizações de atributos diretamente por um dispositivo.

    • modelos de dispositivo (templates): blueprints de dispositivos que contêm uma lista de atributos associados a essa classe de dispositivos. Todos os dispositivos são criados com base em um modelo, do qual herdarão atributos.

    • tópicos: Canais de comunicação Kafka usados para enviar e receber mensagens entre serviços dojot.

    • flows: Sequência de blocos de processamento criados por um usuário ou aplicativo e utilizados para analisar e pré-processar dados.

  • subjects: grupo de tópicos que compartilham um fluxo de mensagens comum. Por exemplo, pode haver muitos tópicos usados para transmitir dados do dispositivo. Todos eles pertencem ao mesmo subject device-data.

Quando um novo agente IoT é criado, todas essas entidades devem ser levadas em consideração de maneira coordenada. Este documento lista todos os requisitos básicos para um novo agente IoT e eles são categorizados nos seguintes grupos:

  1. Segurança do dispositivo: Os agentes IoT devem poder verificar se uma conexão de dispositivo é válida ou não. Uma conexão de dispositivo válida é definida como uma originada por um dispositivo físico confiável (ou qualquer elemento representativo, como gateways) que tem permissão para se conectar ao agente IoT. Um dispositivo é considerado confiável por: (1) criar um dispositivo associado a ele (que pode incluir informações de segurança, como chaves criptográficas) ou (2) indicar diretamente ao agente IoT que um dispositivo ou um elemento representativo tem permissão para conectar-se a ele (para que os elementos que servem como conexões de relé possam ser usados de maneira adequada e segura).

  2. Separação de contexto de informações: cada recurso (dispositivo, modelos, tópicos e fluxos) está associado a um tenant específico e as entidades que não pertencem a esse tenant não devem ter permissão para acessar seus recursos. Isso é válido em todo a dojot e não é uma exceção para agentes IoT. Portanto, um agente IoT deve tratar separadamente todos os dispositivos que pertencem a diferentes tenants - incluindo o fato de que ninguém em um tenant deve saber a existência de outros tenants. Por exemplo, um agente MQTT IoT não deve permitir que mensagens enviadas para seu broker de dispositivos associados ao tenant A sejam publicadas em dispositivos inscritos no mesmo tópico pertencente ao tenant B.

  3. Informações e gerenciamento de agentes IoT: qualquer agente IoT deve publicar seus recursos e modelos de informação. Por exemplo, ele deve informar outros serviços sobre qual é o modelo de dispositivo aceito para receber e enviar mensagens corretamente para um dispositivo físico específico. Também deve oferecer uma interface de gerenciamento para que um usuário possa alterar e recuperar seu comportamento, como opções de log, estatísticas, cotas etc.

  4. Operação do agente IoT:Os agentes IoT devem poder receber e enviar mensagens (se permitido pelo protocolo) aos dispositivos e, portanto, enviar atualizações para outros serviços dojot com base nas mensagens recebidas do dispositivo. Todas as mensagens recebidas de um dispositivo específico e enviadas para outros serviços dojot devem ser enviadas na mesma ordem em que foram recebidas. Os agentes IoT também devem poder ativar ou desativar o processamento de mensagens de um dispositivo específico e detectar o estado do dispositivo.

    Um recurso extra que um agente IoT pode implementar são as atualizações de firmware. Dependendo do protocolo, pode ser possível fazer isso de maneira fácil, segura e confiável.

Cada um desses grupos será detalhado nas seções a seguir.

2.3. Segurança do dispositivo

Um gerenciamento IoT deve levar em consideração os seguintes aspectos da comunicação do dispositivo:

  1. Identidade do dispositivo: deve aceitar apenas conexões de dispositivos físicos autorizados. A verificação se uma nova conexão foi originada por um dispositivo autorizado (que inclui verificar se um dispositivo específico está autorizado ou não) deve depender de chaves públicas e/ ou certificados assinados.

  2. Segurança do canal de comunicação: todas as mensagens trocadas com um dispositivo físico devem ser criptografadas usando padrões criptográficos conhecidos, como TLS. Quaisquer protocolos de segurança próprios devem ser evitados.

  3. Revogação de certificado: o agente IoT deve poder descartar qualquer mensagem do dispositivo autorizado anteriormente se seus dados de segurança tiverem sido comprometidos de alguma forma. Por exemplo, se a chave privada associada a um dispositivo específico vazar, todas as suas mensagens deverão ser ignoradas, pois não há garantia de que elas vieram desse dispositivo.

Cada um desses aspectos será detalhado nas seções a seguir.

2.3.1. Identidade do dispositivo

A verificação de identidade do dispositivo é o ponto de partida para lidar com a segurança da comunicação. Essa validação indicará ao agente IoT se o dispositivo que abriu a conexão é quem diz que é. Além disso, o agente IoT deve, uma vez que essa validação for bem-sucedida, verificar se este dispositivo pode se conectar a ele, verificando seu ID. Esta seção mostrará como fazer isso.

Para protocolos orientados a conexão, o agente IoT deve aceitar apenas conexões para dispositivos que possuem um certificado assinado por uma autoridade confiável pela dojot. Dado que esse certificado é válido, a identidade do dispositivo pode ser verificada de duas formas:

  • ID do dispositivo codificado no certificado: embora seja um mecanismo menos confiável, ele permite maior flexibilidade usando muitos dispositivos em uma implantação controlada. Isso se baseia na configuração do nome comum (campo de certificado CN) como ID do dispositivo dojot. Portanto, o agente IoT deve verificar se este dispositivo existe ou não e permitir ou negar a conexão imediatamente, dependendo dessa verificação. Os pontos fracos desses mecanismos é que o certificado do dispositivo deve ser assinado pela CA interna da dojot (uma vez que existe um procedimento para assinar apenas um certificado por dispositivo) e, se esse certificado for válido, seu ID também deverá ser válido. Se qualquer outra autoridade de certificação for usada, esse mecanismo não terá uso válido.

  • O agente IoT possui todos os certificados válidos: se um administrador deseja usar uma CA externa para assinar todos os certificados de dispositivo, não há controle real de qual ID de dispositivo foi usado para gerar um certificado específico. Portanto, o agente IoT deve ter todos os certificados válidos mapeados adequadamente em uma lista de dispositivos - isso garantirá que apenas um certificado seja permitido para um dispositivo específico e vice-versa.

Usando o primeiro mecanismo, o dispositivo (ou um operador que configura um dispositivo pela primeira vez) deve chamar a CA dojot para gerar um certificado assinado para si. Não há nenhuma ação adicional para o agente IoT usar a CA da dojot.

O segundo mecanismo, no entanto, exige que um agente IoT ofereça métodos para gerenciar certificados. O desenvolvedor deve levar em conta também que esse agente IoT deve poder escalar - esses certificados devem estar acessíveis a todas as instâncias do agente IoT, se permitido pela implantação.

2.3.2. Segurança da comunicação

Com um certificado válido, um dispositivo pode criar um canal de comunicação com a dojot. Para canais orientados a conexão, esse certificado deve ser usado juntamente com chaves criptográficas para fornecer um canal criptografado. Para outros tipos de canal (como canais para troca de mensagens por meio de um gateway, como LoRa ou sigfox), basta garantir que a conexão entre a dojot e o servidor de back-end seja segura. A identidade do back-end deve ser declarada previamente. Uma vez que se sabe que é confiável, todas as suas mensagens podem ser processadas sem grandes preocupações.

2.3.3. Revogação de certificado

Um agente IoT deve poder ser informado sobre certificados revogados. Ele deve expor uma API ou mensagens de configuração para permitir isso. Não deve permitir nenhuma comunicação com um dispositivo específico que usa um certificado revogado.

2.4. Separação de contexto de informações

Um tenant pode ser pensado simplesmente como um grupo de usuários que compartilham alguns recursos. Mas seu significado pode ir além disso - pode implicar que esses recursos não compartilhem nenhuma infraestrutura comum (considerando qualquer coisa que transmita, processe ou armazene dados) com recursos pertencentes a outros tenants. Pode-se ter instâncias de software separadas para processar dados de tenants diferentes, para que o processamento de dados de um tenant não afete o processamento de dados do outro, atingindo um nível mais alto de separação de contexto.

Embora isso seja desejável, alguns cenários de implantação podem forçar o uso de parte da mesma infraestrutura para diferentes tenants (por exemplo, quando a implantação tem um número reduzido de unidades de processamento ou conexões de rede). Portanto, para ter uma separação mínima de contexto entre os tenants, um agente IoT deve usar tudo o que puder para separá-los, como diferentes threads, filas, soquetes etc., e não deve confiar apenas nos recursos dos cenários de implantação (como agentes IoT diferentes para diferentes tenants). Por exemplo, para protocolos baseados em tópicos, como o MQTT, pode-se forçar tópicos diferentes para diferentes tenants. Se um dispositivo publicar dados em um tópico específico de propriedade de outro tenant, essa mensagem será ignorada ou bloqueada (o envio de um erro de volta ao dispositivo pode ser um comportamento opcional). Portanto, nenhum dispositivo de um tenant pode enviar mensagens para qualquer dispositivo de outro tenant.

O mecanismo pelo qual a separação de contexto é implementada depende muito de qual protocolo é usado. Uma análise completa deve ser realizada para implementar adequadamente esse recurso.

2.5. Informações e gerenciamento de agentes IoT

Um agente IoT deve expor todas as informações necessárias para usá-lo corretamente. Deve expor:

  • Modelo de dispositivo: um agente IoT deve publicar qual é o modelo de dados aceito para um dispositivo válido. Isso deve ser feito publicando um novo modelo de dispositivo em outros serviços dojot. Deve haver um mecanismo para que instâncias diferentes do mesmo agente IoT publiquem o mesmo modelo de dispositivo (incluindo quaisquer IDs de modelo). Se o modelo do dispositivo for atualizado em uma versão mais recente de um agente IoT, o ID do modelo do dispositivo deverá mudar.

  • APIs de gerenciamento: um agente IoT deve ser gerenciável e deve expor suas APIs para isso. O conjunto mínimo de APIs de gerenciamento que um agente IoT deve oferecer são:

    • Log: deve haver uma maneira de alterar o nível de log de um agente IoT;

    • Estatísticas: um agente IoT pode expor uma API para permitir que um usuário ou aplicativo recupere informações estatísticas sobre sua execução. Um administrador pode querer ativar ou desativar a geração de uma variável estatística específica, como o tempo de processamento.

Um agente IoT também deve ser capaz de coletar informações estatísticas relacionadas à sua execução. Além disso, deve permitir que um administrador defina cotas para essas quantidades medidas. Essas quantidades podem incluir, mas não estão limitadas a:

  • estatísticas de transmissão

    • número de mensagens recebidas do dispositivo (total, por dispositivo, por tenant)

    • número de mensagens publicadas do dispositivo para dojot (total, por dispositivo, por tenant)

    • número de mensagens enviadas aos dispositivos (total, por dispositivo, por tenant)

    • [opcional] tempo decorrido entre o recebimento de uma mensagem de um dispositivo físico e a publicação (total - média, por dispositivo - média, por tenant - média)

  • Verificação de integridade do serviço do agente IoT - estatísticas do sistema (memória, disco etc.) usadas pelo serviço

Muitos outros valores podem ser reunidos. A lista acima é a lista mínima que um agente IoT deve expor a outros serviços. Especialmente para verificação de integridade, há um documento detalhando como expô-lo.

2.6. Operação do agente IoT

O principal objetivo de um agente IoT é publicar dados de um dispositivo específico em outros serviços dojot. Sua operação é dupla: receba e processe mensagens relacionadas ao gerenciamento de dispositivos de outros serviços, bem como receba mensagens dos próprios dispositivos (ou de seus elementos representativos) e publique esses dados em outros serviços.

As seções a seguir descrevem como um agente IoT pode enviar e receber mensagens de/para outros serviços da dojot e quais são os pontos que ele deve levar em consideração ao receber mensagens de dispositivos físicos.

2.6.1. Mensagens

2.6.1.1. Tenants

No início, todos os agentes IoT (na verdade, todos os serviços que precisam receber ou enviar mensagens relacionadas aos dispositivos) devem conhecer a lista de tenants configurados. Esta é a informação mais básica que o agente IoT precisa saber para funcionar corretamente. A solicitação que deve ser enviada ao serviço Auth é esta (todas as solicitações enviadas dos serviços dojot para seus próprios serviços devem usar o usuário e tenant ‘dojot-management’ ):

Host: Auth

Endpoint: /admin/tenants

Método: GET

Requisição

Cabeçalhos

Authorization: Bearer ${JWT}

Resposta

Cabeçalhos

Content-Type: application/json

Formato do corpo

tenants =>
  tenant => string

Um exemplo de resposta para esta requisição:

{
  "tenants": [
    "admin",
    "users",
    "system"
  ]
}

Após o bootstrap, é necessário se inscrever para receber eventos de tenant usando o tópico dojot-management.dojot.tenancy do Kafka.

O tópico dojot-management.dojot.tenancy do Kafka será usado para receber eventos de ciclo de vida dos tenants. Sempre que um novo tenant é criado ou excluído, a seguinte mensagem será publicada:

Tópico: dojot-management.dojot.tenancy

Formato do corpo (JSON)

type="CREATE"/"DELETE"
tenant=>string

Uma mensagem de exemplo recebida por este tópico é:

{
  "type": "CREATE",
  "tenant": "new_tenant"
}

Este prefixo do tópico pode ser configurado, veja mais na documentação do componente Auth Componentes e APIs.

Veja mais sobre Inicialização dos tenants na comunicação interna.

2.6.1.2. Subjects

Os seguintes subjects devem ser usados pelo agente IoT:

  • Subject: dojot.device-manager.device

  • Subject: device-data

Com a lista de tenants, o agente IoT pode solicitar tópicos para receber eventos de ciclo de vida do dispositivo e para publicar novos dados de atributo do dispositivo. Isso é feito enviando os subjects como na seguinte solicitação ao DataBroker:

Host: DataBroker

Endpoint: /topic/{subject}

Método: GET

Requisição

Cabeçalhos

Authorization: Bearer ${JWT}

Resposta

Cabeçalhos

Content-Type: application/json

Formato do corpo

topic => string

Um exemplo de resposta para esta requisição:

{
  "topic": "admin.device-data"
}

Cada um desses aspectos será detalhado nas seções a seguir

2.6.1.2.1. Subject: dojot.device-manager.device

O tópico relacionado a este subject será usado para receber eventos do ciclo de vida do dispositivo para um tenant específico. Seu formato é:

Subject: dojot.device-manager.device

Formato do corpo (JSON)

event => "create" / "update"
meta => service
  service => string
data =>
  id => string
  label => string
  templates => *number
  attrs => [*template_attrs]
  created => iso_date

Formato do corpo (JSON)

event => "remove"
meta =>
  service => string
data =>
  id => string

Formato do corpo (JSON)

event => "configure"
meta =>
  service => string
  timestamp => int (Unix Timestamp - ms)
data =>
  id => string
  attrs => *device_attrs

O atributo device_attrs é um JSON de chave/valor ainda mais simples, como:

{
  "temperature" : 10,
  "height" : 280
}

Uma mensagem de exemplo recebida por este tópico é:

{
  "event": "create",
  "meta": {
    "service": "admin"
  },
  "data": {
    "id": "efac",
    "label": "Device 1",
    "templates": [1, 2, 3],
    "attrs": {
      "1": [
        {
          "template_id": "1",
          "created": "2018-01-05T15:41:54.840116+00:00",
          "label": "this-is-a-sample-attribute",
          "value_type": "float",
          "type": "dynamic",
          "id": 1
        }
      ]
    },
    "created": "2018-02-06T10:43:40.890330+00:00"
  }
}
2.6.1.2.2. Subject: device-data

O tópico relacionado a este subject será usado para publicar dados recuperados de um dispositivo físico em outros serviços da dojot. Seu formato é:

Subject: device-data

Formato do corpo (JSON)

metadata => deviceid tenant timestamp
  deviceid => string
  tenant => string
  timestamp => int (Unix Timestamp - ms or s)
attrs => *device_attrs

O timestamp está associado a quando os valores de atributo foram coletados pelo dispositivo (isso pode ser feito pelo próprio dispositivo - ao enviar diretamente o atributo timestamp na mensagem - ou pelo agente IoT, se nenhum timestamp foi definido pelo dispositivo). O timestamp pode ser tanto UNIX quanto ISO, em segundos ou milissegundos.

Uma mensagem de exemplo recebida por este tópico é:

{
  "metadata": {
    "deviceid": "c6ea4b",
    "tenant": "admin",
    "timestamp": 1528226137452,
  },
  "attrs": {
    "humidity": 60
  }
}

Veja mais sobre Enviando mensagens via Kafka na comunicação interna.

2.6.2. Atualização de Firmware

Um agente IoT pode implementar mecanismos para atualizar o firmware nos dispositivos.

2.7. Comportamento

A ordem na qual um dispositivo físico envia seus atributos não deve ser alterada quando o agente IoT publica esses dados em outros serviços dojot.

Se o protocolo impuser qualquer ID único externo para cada dispositivo, o agente IoT deverá criar uma tabela de correlação para converter adequadamente esse ID único externo em ID de dispositivo dojot e vice-versa.

2.8. Bibliotecas para auxiliar no desenvolvimento de novos agentes IoT

Temos bibliotecas que abstraem alguns pontos descritos nos tópicos anteriores para facilitar o desenvolvimento de um Agente Iot.

Existem duas bibliotecas: