Fazer upload de arquivos do seu dispositivo na nuvem com o Hub IoT do Azure (Node.js)

Este artigo demonstra como usar as funcionalidades de upload de arquivos do Hub IoT para carregar um arquivo para o armazenamento de blobs do Azure usando Node.js.

O início rápido Enviar telemetria de um dispositivo para um hub IoT e o artigo Enviar mensagens de nuvem para dispositivo com o Hub IoT mostram a funcionalidade básica do sistema de mensagens de dispositivo para nuvem e de nuvem para dispositivo do Hub IoT. O tutorial Configurar o roteamento de mensagens com o Hub IoT descreve uma forma de armazenar mensagens de dispositivo para nuvem com confiança no Armazenamento de Blobs do Microsoft Azure. No entanto, em alguns cenários, não é possível mapear com facilidade os dados que seus dispositivos enviam em mensagens relativamente pequenas de dispositivo para nuvem e que o Hub IoT aceita. Por exemplo:

  • Vídeos
  • Arquivos grandes que contêm imagens
  • Dados de vibração amostrados a alta frequência
  • Alguma forma de dados pré-processados.

Esses arquivos normalmente são processados em lote na nuvem usando ferramentas como o Azure Data Factory ou a pilha do Hadoop. Quando você precisar carregar arquivos de um dispositivo, ainda poderá usar a segurança e a confiabilidade do Hub IoT. Este artigo mostra como fazer isso.

No final do tutorial, você executará dois aplicativos de console do Node.js:

  • O FileUpload.js, que carrega um arquivo no armazenamento usando um URI de SAS fornecido pelo hub IoT.

  • FileUploadNotification.js, que recebe notificações de upload de arquivo do seu Hub IoT.

Observação

O Hub IoT é compatível com muitas plataformas de dispositivo e linguagens (incluindo C, Java, Python e JavaScript) por meio dos SDKs do dispositivo IoT do Azure. Confira a Central do Desenvolvedor de IoT do Azure para saber como conectar seu dispositivo ao Hub IoT do Azure.

Importante

A funcionalidade de carregamento de arquivo em dispositivos que usam a autenticação da autoridade de certificação (AC) de certificados X.509 está em versão prévia. Além disso, é necessário habilitar o modo de versão prévia. Geralmente está disponível em dispositivos que usam a autenticação de impressão digital X. 509 ou o atestado de certificado X. 509 com o Serviço de Provisionamento de Dispositivos do Azure. Para saber mais sobre a autenticação X.509 com o Hub IoT, confira Certificados X.509 com suporte.

Pré-requisitos

  • Um hub IoT. Crie um com a CLI ou o portal do Azure.

  • Um dispositivo registrado. Registre um no portal do Azure.

  • Node.js versão 10.0.x ou posterior. Recomenda-se uma versão LTS. Baixe o Node.js em nodejs.org.

  • A porta 8883 deve estar aberta no firewall. O exemplo de dispositivo deste artigo usa o protocolo MQTT, que se comunica pela porta 8883. Essa porta poderá ser bloqueada em alguns ambientes de rede corporativos e educacionais. Para obter mais informações e maneiras de resolver esse problema, confira Como se conectar ao Hub IoT (MQTT).

Associar uma conta do Armazenamento do Azure ao Hub IoT

Para carregar arquivos de um dispositivo, você deve ter uma conta de Armazenamento do Azure e um contêiner de Armazenamento de Blobs do Azure associados ao Hub IoT. Depois de associar a conta de armazenamento e o contêiner ao Hub IoT, ele poderá fornecer os elementos de um URI de SAS quando solicitado por um dispositivo. Em seguida, o dispositivo pode usar esses elementos para criar o URI de SAS a ser usado na autenticação no Armazenamento do Azure e no upload de arquivos para o contêiner de blobs.

Para associar uma conta de Armazenamento do Azure ao Hub IoT:

  1. Em Configurações do hub, selecione Upload de arquivos no painel esquerdo do Hub IoT.

    Captura de tela que mostra as configurações de upload de arquivos selecionadas no portal.

  2. No painel Upload de arquivo, selecione Contêiner de Armazenamento do Azure. Para este artigo, é recomendado que a conta de armazenamento e o Hub IoT estejam na mesma região.

    • Se você já tiver uma conta de armazenamento que deseja usar, selecione-a na lista.

    • Para criar uma nova conta de armazenamento, selecione + Conta de armazenamento. Dê um nome à conta de armazenamento, verifique se o Local está definido para a mesma região do Hub IoT e selecione OK. A nova conta é criada no mesmo grupo de recursos do Hub IoT. Quando a implantação for concluída, selecione a conta de armazenamento na lista.

    Depois de selecionar a conta de armazenamento, o painel Contêineres é aberto.

  3. No painel Contêineres, selecione o contêiner de blobs.

    • Se você já tiver um contêiner de blobs que deseja usar, escolha-o na lista e clique em Selecionar.

    • Para criar um novo contêiner de blobs, selecione + Contêiner. Dê um nome ao novo contêiner. Para os fins deste artigo, você pode deixar todos os outros campos com o padrão. Selecione Criar. Quando a implantação for concluída, escolha o contêiner na lista e clique em Selecionar.

  4. Volte ao painel Upload de arquivo e verifique se as notificações de arquivo estão definidas como Ativado. Deixe todas as outras configurações com os valores padrão. Selecione Salvar e aguarde a conclusão da configuração antes de ir para a próxima seção.

    Captura de tela que mostra as configurações de confirmação de upload de arquivos no portal.

Para obter instruções mais detalhadas sobre a criação de contas de armazenamento do Azure, veja Criar uma conta de armazenamento. Para obter instruções mais detalhadas sobre a associação de uma conta de armazenamento e um contêiner de blobs a um Hub IoT, veja Configurar uploads de arquivo com o portal do Azure.

Carregar um arquivo de um aplicativo de dispositivo

Nesta seção, você criará um aplicativo de dispositivo para carregar um arquivo no Hub IoT. Esse código é baseado no código disponível na amostra upload_to_blob_advanced.js dos exemplos de dispositivo SDK de Node.js da Internet das Coisas do Azure.

  1. Crie uma pasta vazia chamada fileupload. Na pasta fileupload, crie um arquivo package.json usando o comando a seguir no seu prompt de comando. Aceite todos os padrões:

    npm init
    
  2. No prompt de comando, na pasta fileupload, execute o seguinte comando para instalar o SDK do dispositivo azure-iot-device, o azure-iot-device-mqtt e os pacotes @azure/storage-blob:

    npm install azure-iot-device azure-iot-device-mqtt @azure/storage-blob --save
    
  3. Com um editor de texto, crie um arquivo FileUpload.js na pasta fileupload e copie o código a seguir nele.

    'use strict';
    
    const Client = require('azure-iot-device').Client;
    const Protocol = require('azure-iot-device-mqtt').Mqtt;
    const errors = require('azure-iot-common').errors;
    const path = require('path');
    
    const {
      AnonymousCredential,
      BlockBlobClient,
      newPipeline
    } = require('@azure/storage-blob');
    
    // make sure you set these environment variables prior to running the sample.
    const deviceConnectionString = process.env.DEVICE_CONNECTION_STRING;
    const localFilePath = process.env.PATH_TO_FILE;
    const storageBlobName = path.basename(localFilePath);
    
    async function uploadToBlob(localFilePath, client) {
      const blobInfo = await client.getBlobSharedAccessSignature(storageBlobName);
      if (!blobInfo) {
        throw new errors.ArgumentError('Invalid upload parameters');
      }
    
      const pipeline = newPipeline(new AnonymousCredential(), {
        retryOptions: { maxTries: 4 },
        telemetry: { value: 'HighLevelSample V1.0.0' }, // Customized telemetry string
        keepAliveOptions: { enable: false }
      });
    
      // Construct the blob URL to construct the blob client for file uploads
      const { hostName, containerName, blobName, sasToken } = blobInfo;
      const blobUrl = `https://${hostName}/${containerName}/${blobName}${sasToken}`;
    
      // Create the BlockBlobClient for file upload to the Blob Storage Blob
      const blobClient = new BlockBlobClient(blobUrl, pipeline);
    
      // Setup blank status notification arguments to be filled in on success/failure
      let isSuccess;
      let statusCode;
      let statusDescription;
    
      try {
        const uploadStatus = await blobClient.uploadFile(localFilePath);
        console.log('uploadStreamToBlockBlob success');
    
        // Save successful status notification arguments
        isSuccess = true;
        statusCode = uploadStatus._response.status;
        statusDescription = uploadStatus._response.bodyAsText;
    
        // Notify IoT Hub of upload to blob status (success)
        console.log('notifyBlobUploadStatus success');
      }
      catch (err) {
        isSuccess = false;
        statusCode = err.code;
        statusDescription = err.message;
    
        console.log('notifyBlobUploadStatus failed');
        console.log(err);
      }
    
      await client.notifyBlobUploadStatus(blobInfo.correlationId, isSuccess, statusCode, statusDescription);
    }
    
    // Create a client device from the connection string and upload the local file to blob storage.
    const deviceClient = Client.fromConnectionString(deviceConnectionString, Protocol);
    uploadToBlob(localFilePath, deviceClient)
      .catch((err) => {
        console.log(err);
      })
      .finally(() => {
        process.exit();
      });
    
  4. Salve e feche o arquivo FileUpload.js.

  5. Copie um arquivo de imagem na pasta fileupload e nomeie o arquivo como myimage.png.

  6. Adicione variáveis de ambiente na cadeia de conexão do dispositivo e o caminho do arquivo que você deseja carregar. Você obteve a cadeia de conexão de dispositivo quando registrou um dispositivo no Hub IoT.

    • Para Windows:

      set DEVICE_CONNECTION_STRING={your device connection string}
      set PATH_TO_FILE={your image filepath}
      
    • Para Linux/Bash:

      export DEVICE_CONNECTION_STRING="{your device connection string}"
      export PATH_TO_FILE="{your image filepath}"
      

Obter a cadeia de conexão do hub IoT

Neste artigo, você criará um serviço de back-end para receber mensagens de notificação de upload de arquivo do Hub IoT criado. Para receber mensagens de notificação de upload de arquivo, seu serviço precisa da permissão conexão de serviço. Por padrão, todo Hub IoT é criado com uma política de acesso compartilhado chamada serviço que concede essa permissão.

Para obter a cadeia de conexão do Hub IoT para a política de serviço, siga estas etapas:

  1. No portal do Azure, selecione Grupos de recursos. Selecione o grupo de recursos em que o Hub está localizado e, em seguida, selecione o seu hub na lista de recursos.

  2. No painel do lado esquerdo do hub IoT, selecione Políticas de acesso compartilhado.

  3. Na lista de políticas, selecione a política de serviço.

  4. Copie a Cadeia de conexão primária e salve o valor.

Captura de tela que mostra como recuperar a cadeia de conexão do seu Hub IoT no portal do Azure.

Para obter mais informações sobre permissões e políticas de acesso compartilhado do Hub IoT, consulte Controle de acesso e permissões.

Receber uma notificação de upload de arquivo

Nesta seção, você criará um aplicativo de console do Node.js que receba mensagens de notificação de upload de arquivo do Hub IoT.

  1. Crie uma pasta vazia chamada fileuploadnotification. Na pasta fileuploadnotification, crie um arquivo package.json usando o comando a seguir no seu prompt de comando. Aceite todos os padrões:

    npm init
    
  2. No prompt de comando na pasta fileuploadnotification, execute o seguinte comando para instalar o pacote do SDK azure-iothub:

    npm install azure-iothub --save
    
  3. Usando um editor de texto, crie um arquivo FileUploadNotification.js na pasta fileuploadnotification.

  4. Adicione as seguintes instruções require no início do arquivo FileUploadNotification.js:

    'use strict';
    
    const Client = require('azure-iothub').Client;
    
  5. Leia a cadeia de conexão do Hub IoT no ambiente:

    const connectionString = process.env.IOT_HUB_CONNECTION_STRING;
    
  6. Adicione o seguinte código para criar um cliente de serviço da cadeia de conexão:

    const serviceClient = Client.fromConnectionString(connectionString);
    
  7. Abra o cliente e use a função getFileNotificationReceiver para receber atualizações de status.

    serviceClient.open(function (err) {
      if (err) {
        console.error('Could not connect: ' + err.message);
      } else {
        console.log('Service client connected');
        serviceClient.getFileNotificationReceiver(function receiveFileUploadNotification(err, receiver){
          if (err) {
            console.error('error getting the file notification receiver: ' + err.toString());
          } else {
            receiver.on('message', function (msg) {
              console.log('File upload from device:')
              console.log(msg.getData().toString('utf-8'));
              receiver.complete(msg, function (err) {
                if (err) {
                  console.error('Could not finish the upload: ' + err.message);
                } else {
                  console.log('Upload complete');
                }
              });
            });
          }
        });
      }
    });
    

    Observação

    Para receber notificações de desconexão ao escutar notificações de upload de arquivo, registre 'error' usando receiver.on. Para continuar a receber notificações de upload de arquivo, reconecte-se ao Hub IoT usando o método serviceClient.open.

  8. Salve e feche o arquivo FileUploadNotification.js.

  9. Adicione uma variável de ambiente para a cadeia de conexão do Hub IoT. Você copiou essa cadeia anteriormente em Obter a cadeia de conexão do Hub IoT.

    • Para Windows:

      set IOT_HUB_CONNECTION_STRING={your iot hub connection string}
      
    • Para Linux/Bash:

      export IOT_HUB_CONNECTION_STRING="{your iot hub connection string}"
      

Executar os aplicativos

Agora você está pronto para executar os aplicativos.

Em um prompt de comando na pasta fileuploadnotification, execute o seguinte comando:

node FileUploadNotification.js

Em um prompt de comando na pasta fileupload, execute o seguinte comando:

node FileUpload.js

Veja a saída a seguir do aplicativo FileUpload após a conclusão do upload:

uploadStreamToBlockBlob success
notifyBlobUploadStatus success

Veja a saída de amostra a seguir do aplicativo FileUploadNotification após a conclusão do upload:

Service client connected
File upload from device:
{"deviceId":"myDeviceId","blobUri":"https://{your storage account name}.blob.core.windows.net/device-upload-container/myDeviceId/image.png","blobName":"myDeviceId/image.png","lastUpdatedTime":"2021-07-23T23:27:06+00:00","blobSizeInBytes":26214,"enqueuedTimeUtc":"2021-07-23T23:27:07.2580791Z"}

Verifique o carregamento do arquivo

Você pode usar o portal para exibir o arquivo carregado no contêiner de armazenamento configurado:

  1. Navegue até sua conta de armazenamento no portal do Azure.

  2. No painel esquerdo dela, selecione Contêineres.

  3. Selecione o contêiner em que você carregou o arquivo.

  4. Selecione a pasta com o nome do dispositivo.

  5. Selecione o blob em que você carregou o arquivo. Neste artigo, o blob tem o mesmo nome que o arquivo.

    Captura de tela da exibição do arquivo carregado no portal do Azure.

  6. Veja as propriedades do blob na página que é aberta. Você pode selecionar Baixar para baixar o arquivo e exibir o conteúdo dele localmente.

Próximas etapas

Neste artigo, você aprendeu a usar o recurso de carregamento de arquivos do Hub IoT para simplificar os carregamentos de arquivos de dispositivos. Você pode continuar a explorar esse recurso nos seguintes artigos: