Share via


Carregue arquivos do seu dispositivo para a nuvem com o Hub IoT do Azure (Java)

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 Java.

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 maneira de armazenar mensagens de dispositivo para nuvem com confiança no Armazenamento de Blobs do 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. Veja dois exemplos do azure-iot-sdk-java no GitHub.

Observação

O Hub IoT dá suporte a várias plataformas de dispositivo e linguagens (incluindo C, .NET 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.

  • Java SE Development Kit 8. Certifique-se de selecionar Java 8 em Suporte de longo prazo para obter downloads do JDK 8.

  • Maven 3

  • 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.

Criar um projeto usando o Maven

Crie um diretório para o seu projeto e inicie um shell nele. Na linha de comando, execute o seguinte:

mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false

Isso gera um diretório com o mesmo nome de artifactId e uma estrutura de projeto padrão:

  my-app
  |-- pom.xml
   -- src
      -- main
         -- java
            -- com
               -- mycompany
                  -- app
                     --App.Java

Com um editor de texto, substitua o arquivo pom.xml pelo seguinte:


<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>my-app</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
      <dependency>
      <groupId>com.microsoft.azure.sdk.iot</groupId>
      <artifactId>iot-device-client</artifactId>
      <version>1.30.1</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.29</version>
    </dependency>    
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.3</version>
            <configuration>
              <source>1.7</source>
              <target>1.7</target>
            </configuration>
        </plugin>
        <plugin>
          <artifactId>maven-shade-plugin</artifactId>
          <version>2.4</version>
          <executions>
              <execution>
                  <phase>package</phase>
                  <goals>
                    <goal>shade</goal>
                  </goals>
                  <configuration>
                      <filters>
                          <filter>
                              <artifact>*:*</artifact>
                              <excludes>
                                  <exclude>META-INF/*.SF</exclude>
                                  <exclude>META-INF/*.RSA</exclude>
                              </excludes>
                          </filter>
                      </filters>
                      <shadedArtifactAttached>true</shadedArtifactAttached>
                      <shadedClassifierName>with-deps</shadedClassifierName>
                  </configuration>
              </execution>
          </executions>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

Carregar um arquivo de um aplicativo de dispositivo

Copie o arquivo que você deseja carregar para a pasta my-app na árvore do projeto. Com um editor de texto, substitua App.java pelo código a seguir. Onde indicado, forneça a seu dispositivo a cadeia de conexão e o nome do arquivo. Você copiou a cadeia de conexão do dispositivo quando o registrou.

package com.mycompany.app;

import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.BlobClientBuilder;
import com.microsoft.azure.sdk.iot.deps.serializer.FileUploadCompletionNotification;
import com.microsoft.azure.sdk.iot.deps.serializer.FileUploadSasUriRequest;
import com.microsoft.azure.sdk.iot.deps.serializer.FileUploadSasUriResponse;
import com.microsoft.azure.sdk.iot.device.DeviceClient;
import com.microsoft.azure.sdk.iot.device.IotHubClientProtocol;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Scanner;

public class App 
{
    /**
     * Upload a single file to blobs using IoT Hub.
     *
     */
    public static void main(String[] args)throws IOException, URISyntaxException
    {
        String connString = "Your device connection string here";
        String fullFileName = "Path of the file to upload";

        System.out.println("Starting...");
        System.out.println("Beginning setup.");

        // File upload will always use HTTPS, DeviceClient will use this protocol only
        //   for the other services like Telemetry, Device Method and Device Twin.
        IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;

        System.out.println("Successfully read input parameters.");

        DeviceClient client = new DeviceClient(connString, protocol);

        System.out.println("Successfully created an IoT Hub client.");

        try
        {
            File file = new File(fullFileName);
            if (file.isDirectory())
            {
                throw new IllegalArgumentException(fullFileName + " is a directory, please provide a single file name, or use the FileUploadSample to upload directories.");
            }

            System.out.println("Retrieving SAS URI from IoT Hub...");
            FileUploadSasUriResponse sasUriResponse = client.getFileUploadSasUri(new FileUploadSasUriRequest(file.getName()));

            System.out.println("Successfully got SAS URI from IoT Hub");
            System.out.println("Correlation Id: " + sasUriResponse.getCorrelationId());
            System.out.println("Container name: " + sasUriResponse.getContainerName());
            System.out.println("Blob name: " + sasUriResponse.getBlobName());
            System.out.println("Blob Uri: " + sasUriResponse.getBlobUri());

            System.out.println("Using the Azure Storage SDK to upload file to Azure Storage...");

            try
            {
                BlobClient blobClient =
                    new BlobClientBuilder()
                        .endpoint(sasUriResponse.getBlobUri().toString())
                        .buildClient();

                blobClient.uploadFromFile(fullFileName);
            }
            catch (Exception e)
            {
                System.out.println("Exception encountered while uploading file to blob: " + e.getMessage());

                System.out.println("Failed to upload file to Azure Storage.");

                System.out.println("Notifying IoT Hub that the SAS URI can be freed and that the file upload failed.");

                // Note that this is done even when the file upload fails. IoT Hub has a fixed number of SAS URIs allowed active
                // at any given time. Once you are done with the file upload, you should free your SAS URI so that other
                // SAS URIs can be generated. If a SAS URI is not freed through this API, then it will free itself eventually
                // based on how long SAS URIs are configured to live on your IoT Hub.
                FileUploadCompletionNotification completionNotification = new FileUploadCompletionNotification(sasUriResponse.getCorrelationId(), false);
                client.completeFileUpload(completionNotification);

                System.out.println("Notified IoT Hub that the SAS URI can be freed and that the file upload was a failure.");

                client.closeNow();
                return;
            }

            System.out.println("Successfully uploaded file to Azure Storage.");

            System.out.println("Notifying IoT Hub that the SAS URI can be freed and that the file upload was a success.");
            FileUploadCompletionNotification completionNotification = new FileUploadCompletionNotification(sasUriResponse.getCorrelationId(), true);
            client.completeFileUpload(completionNotification);
            System.out.println("Successfully notified IoT Hub that the SAS URI can be freed, and that the file upload was a success");
        }
        catch (Exception e)
        {
            System.out.println("On exception, shutting down \n" + " Cause: " + e.getCause() + " \nERROR: " +  e.getMessage());
            System.out.println("Shutting down...");
            client.closeNow();
        }

        System.out.println("Press any key to exit...");

        Scanner scanner = new Scanner(System.in);
        scanner.nextLine();
        System.out.println("Shutting down...");
        client.closeNow();
    }
}

Compile e execute o aplicativo

Em um prompt de comando na pasta my-app, execute o seguinte comando:

mvn clean package -DskipTests

Depois que a compilação for concluída, use o comando a seguir para executar o aplicativo:

mvn exec:java -Dexec.mainClass="com.mycompany.app.App"

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

Captura de tela mostrando um arquivo que foi carregado no seu contêiner de armazenamento.

Receber uma notificação de upload de arquivo

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

  1. Crie um diretório para o seu projeto e inicie um shell nele. Na linha de comando, execute o seguinte:

    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false
    
  2. No prompt de comando, navegue até a nova pasta my-app.

  3. Com um editor de texto, substitua o arquivo pom.xml na pasta my-app pelo seguinte. Ao adicionar a dependência do cliente do serviço, você pode usar o pacote iothub-java-service-client no aplicativo para se comunicar com o serviço do Hub IoT:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>com.mycompany.app</groupId>
      <artifactId>my-app</artifactId>
      <version>1.0-SNAPSHOT</version>
    
      <name>my-app</name>
      <!-- FIXME change it to the project's website -->
      <url>http://www.example.com</url>
    
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
      </properties>
    
      <dependencies>
          <dependency>
          <groupId>com.microsoft.azure.sdk.iot</groupId>
          <artifactId>iot-device-client</artifactId>
          <version>1.30.1</version>
        </dependency>
        <dependency>
          <groupId>com.microsoft.azure.sdk.iot</groupId>
          <artifactId>iot-service-client</artifactId>
          <version>1.7.23</version>
        </dependency>
        <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-log4j12</artifactId>
          <version>1.7.29</version>
        </dependency>    
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.11</version>
          <scope>test</scope>
        </dependency>
      </dependencies>
    
      <build>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
          <plugins>
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                  <source>1.7</source>
                  <target>1.7</target>
                </configuration>
            </plugin>
            <plugin>
              <artifactId>maven-shade-plugin</artifactId>
              <version>2.4</version>
              <executions>
                  <execution>
                      <phase>package</phase>
                      <goals>
                        <goal>shade</goal>
                      </goals>
                      <configuration>
                          <filters>
                              <filter>
                                  <artifact>*:*</artifact>
                                  <excludes>
                                      <exclude>META-INF/*.SF</exclude>
                                      <exclude>META-INF/*.RSA</exclude>
                                  </excludes>
                              </filter>
                          </filters>
                          <shadedArtifactAttached>true</shadedArtifactAttached>
                          <shadedClassifierName>with-deps</shadedClassifierName>
                      </configuration>
                  </execution>
              </executions>
            </plugin>
          </plugins>
        </pluginManagement>
      </build>
    </project>
    

    Observação

    Você pode verificar a versão mais recente do iot-service-client usando a pesquisa do Maven.

  4. Salve e feche o arquivo pom.xml.

  5. Obter a cadeia de conexão do serviço Hub IoT.

    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.

  6. Com um editor de texto, abra o arquivo my-app\src\main\java\com\mycompany\app\App.java e substitua o código pelo seguinte.

    package com.mycompany.app;
    
    import com.microsoft.azure.sdk.iot.service.*;
    import java.io.IOException;
    import java.net.URISyntaxException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    
    public class App 
    {
        private static final String connectionString = "{Your service connection string here}";
        private static final IotHubServiceClientProtocol protocol = IotHubServiceClientProtocol.AMQPS;
    
        public static void main(String[] args) throws Exception
        {
            ServiceClient sc = ServiceClient.createFromConnectionString(connectionString, protocol);
    
            FileUploadNotificationReceiver receiver = sc.getFileUploadNotificationReceiver();
            receiver.open();
            FileUploadNotification fileUploadNotification = receiver.receive(2000);
    
            if (fileUploadNotification != null)
            {
                System.out.println("File Upload notification received");
                System.out.println("Device Id : " + fileUploadNotification.getDeviceId());
                System.out.println("Blob Uri: " + fileUploadNotification.getBlobUri());
                System.out.println("Blob Name: " + fileUploadNotification.getBlobName());
                System.out.println("Last Updated : " + fileUploadNotification.getLastUpdatedTimeDate());
                System.out.println("Blob Size (Bytes): " + fileUploadNotification.getBlobSizeInBytes());
                System.out.println("Enqueued Time: " + fileUploadNotification.getEnqueuedTimeUtcDate());
            }
            else
            {
                System.out.println("No file upload notification");
            }
    
            receiver.close();
        }
    
    }
    
  7. Salve e feche o arquivo my-app\src\main\java\com\mycompany\app\App.java.

  8. Use o seguinte comando para criar o aplicativo e verificar se há erros:

    mvn clean package -DskipTests
    

Executar o aplicativo

Agora você está pronto para executar o aplicativo.

Em um prompt de comando na pasta my-app, execute o seguinte comando:

mvn exec:java -Dexec.mainClass="com.mycompany.app.App"

A captura de tela a seguir mostra a saída do aplicativo read-file-upload-notification:

Saída do aplicativo read-file-upload-notification

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:

Para explorar melhor as funcionalidades do Hub IoT, consulte: