Caricare file dal dispositivo al cloud con hub IoT di Azure (Java)

Questo articolo illustra come caricare file funzionalità di hub IoT caricare un file nell'archivio BLOB di Azure usando Java.

La guida introduttiva Inviare dati di telemetria da un dispositivo a un hub IoT e Inviare messaggi da cloud a dispositivo con hub IoT articoli illustrano le funzionalità di messaggistica da dispositivo a cloud e da cloud a dispositivo di hub IoT. L'esercitazione Configurare il routing dei messaggi con hub IoT illustra un modo per archiviare in modo affidabile i messaggi da dispositivo a cloud nell'archiviazione BLOB di Azure. In alcuni scenari, tuttavia, non è possibile eseguire facilmente il mapping dei dati inviati dai dispositivi nei messaggi da dispositivo a cloud relativamente piccoli accettati hub IoT. Ad esempio:

  • Video
  • File di grandi dimensioni che contengono immagini
  • Dati di vibrazione campionati ad alta frequenza
  • Qualche tipo di dati pre-elaborati.

Questi file vengono in genere elaborati in batch nel cloud, usando strumenti come Azure Data Factory o lo stack Hadoop . Quando è necessario caricare i file da un dispositivo, è comunque possibile usare la sicurezza e affidabilità dell'hub IoT. Questo articolo illustra i passaggi da eseguire. Visualizzare due esempi da azure-iot-sdk-java in GitHub.

Nota

hub IoT supporta molte piattaforme e linguaggi per dispositivi (tra cui C, .NET e JavaScript) tramite Azure IoT SDK per dispositivi. Fare riferimento al Centro per sviluppatori Azure IoT per informazioni su come connettere il dispositivo a hub IoT di Azure.

Importante

La funzionalità di caricamento dei file nei dispositivi che usano l'autenticazione dell'autorità di certificazione X.509 è in anteprima pubblica e la modalità di anteprima deve essere abilitata. È disponibile a livello generale nei dispositivi che usano l'autenticazione con identificazione personale X.509 o l'attestazione del certificato X.509 con il servizio Device Provisioning di Azure. Per altre informazioni sull'autenticazione X.509 con hub IoT, vedere Certificati X.509 supportati.

Prerequisiti

  • Un hub IoT. Crearne uno con l'interfaccia della riga di comando o il portale di Azure.

  • Un dispositivo registrato. Registrarne uno nel portale di Azure.

  • Java SE Development Kit 8. Assicurarsi di selezionare Java 8 in Supporto a lungo termine per passare ai download per JDK 8.

  • Maven 3

  • La porta 8883 deve essere aperta nel firewall. L'esempio di dispositivo di questo articolo usa il protocollo MQTT, che comunica tramite la porta 8883. Questa porta potrebbe essere bloccata in alcuni ambienti di rete aziendali e didattici. Per altre informazioni e soluzioni alternative per questo problema, vedere Connettersi all'hub IoT (MQTT).

Associare un account di archiviazione di Azure all'hub IoT

Per caricare file da un dispositivo, è necessario avere un account Archiviazione di Azure e Archiviazione BLOB di Azure contenitore associato all'hub IoT. Dopo aver associato l'account di archiviazione e il contenitore all'hub IoT, l'hub IoT può fornire gli elementi di un URI di firma di accesso condiviso quando richiesto da un dispositivo. Il dispositivo può quindi usare questi elementi per costruire l'URI di firma di accesso condiviso usato per eseguire l'autenticazione con Archiviazione di Azure e caricare i file nel contenitore BLOB.

Per associare un account Archiviazione di Azure all'hub IoT:

  1. In Impostazioni hub selezionare Caricamento file nel riquadro sinistro dell'hub IoT.

    Acquisizione schermo che mostra le impostazioni di caricamento dei file dal portale.

  2. Nel riquadro Caricamentofile selezionare Archiviazione di Azure Contenitore. Per questo articolo, è consigliabile che l'account di archiviazione e hub IoT trovarsi nella stessa area.

    • Se si ha già un account di archiviazione che si vuole usare, selezionarlo nell'elenco.

    • Per creare un nuovo account di archiviazione, selezionare +Archiviazione account. Specificare un nome per l'account di archiviazione e assicurarsi che Località sia impostata sulla stessa area dell'hub IoT, quindi selezionare OK. Il nuovo account viene creato nello stesso gruppo di risorse dell'hub IoT. Al termine della distribuzione, selezionare l'account di archiviazione nell'elenco.

    Dopo aver selezionato l'account di archiviazione, viene visualizzato il riquadro Contenitori .

  3. Nel riquadro Contenitori selezionare il contenitore BLOB.

    • Se si ha già un contenitore BLOB che si vuole usare, selezionarlo nell'elenco e fare clic su Seleziona.

    • Per creare un nuovo contenitore BLOB, selezionare + Contenitore. Specificare un nome per il nuovo contenitore. Ai fini di questo articolo, è possibile lasciare tutti gli altri campi come predefiniti. Seleziona Crea. Al termine della distribuzione, selezionare il contenitore dall'elenco e fare clic su Seleziona.

  4. Tornare al riquadro Caricamento file, assicurarsi che le notifiche dei file siano impostate su . È possibile lasciare tutte le altre impostazioni predefinite. Selezionare Salva e attendere il completamento delle impostazioni prima di passare alla sezione successiva.

    Acquisizione dello schermo che mostra la conferma delle impostazioni di caricamento dei file nel portale.

Per istruzioni più dettagliate su come creare un account Archiviazione di Azure, vedere Creare un account di archiviazione. Per istruzioni più dettagliate su come associare un account di archiviazione e un contenitore BLOB a un hub IoT, vedere Configurare i caricamenti di file usando il portale di Azure.

Creare un progetto usando Maven

Creare una directory per il progetto e avviare una shell in tale directory. Nella riga di comando eseguire quanto segue

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

Viene generata una directory con lo stesso nome di artifactId e una struttura di progetto standard:

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

Usando un editor di testo, sostituire il file pom.xml con quanto segue:


<?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>

Caricare un file da un'app per dispositivi

Copiare il file da caricare nella cartella nell'albero my-app del progetto. Usando un editor di testo, sostituire App.java con il codice seguente. Specificare il stringa di connessione del dispositivo e il nome del file, dove indicato. Il dispositivo è stato copiato stringa di connessione quando è stato registrato il dispositivo.

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();
    }
}

Compilare ed eseguire l'applicazione

Al prompt dei comandi nella cartella my-app eseguire il comando seguente:

mvn clean package -DskipTests

Al termine della compilazione, eseguire il comando seguente per eseguire l'applicazione:

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

Per visualizzare il file caricato nel contenitore di archiviazione configurato, è possibile usare il portale:

Screenshot che mostra un file caricato nel contenitore di archiviazione.

Ricevere la notifica di caricamento di un file

In questa sezione viene creata un'app console Java che riceve messaggi di notifica di caricamento file dall'hub IoT.

  1. Creare una directory per il progetto e avviare una shell in tale directory. Nella riga di comando eseguire quanto segue

    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false
    
  2. Al prompt dei comandi passare alla nuova cartella my-app.

  3. Usando un editor di testo, sostituire il pom.xml file nella my-app cartella con il codice seguente. L'aggiunta della dipendenza client del servizio consente di usare il pacchetto iothub-java-service-client nell'applicazione per comunicare con il servizio 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>
    

    Nota

    È possibile cercare la versione più recente di iot-service-client usando la ricerca di Maven.

  4. Salva e chiude il file pom.xml.

  5. Ottenere il stringa di connessione del servizio hub IoT.

    Per ottenere la stringa di connessione dell'hub IoT per i criteri del servizio, seguire questa procedura:

    1. Nel portale di Azure fare clic su Gruppi di risorse. Selezionare il gruppo di risorse in cui si trova l'hub e quindi selezionare l'hub dall'elenco di risorse.

    2. Nel riquadro sinistro dell'hub IoT selezionare Criteri di accesso condiviso.

    3. Dall'elenco dei criteri selezionare i criteri del servizio.

    4. Copiare il stringa di connessione primario e salvare il valore.

    Screenshot che mostra come recuperare il stringa di connessione dal hub IoT nella portale di Azure.

    Per altre informazioni sui criteri di accesso condiviso e sulle autorizzazioni dell'hub IoT, vedere Controllo dell'accesso e autorizzazioni.

  6. Usando un editor di testo, aprire il my-app\src\main\java\com\mycompany\app\App.java file e sostituire il codice con il codice seguente.

    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. Salva e chiude il file my-app\src\main\java\com\mycompany\app\App.java.

  8. Usare il comando seguente per compilare l'app e verificare la presenza di errori:

    mvn clean package -DskipTests
    

Eseguire l'applicazione

A questo punto è possibile eseguire l'applicazione.

Al prompt dei comandi nella cartella my-app eseguire il comando seguente:

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

Lo screenshot seguente presenta l'output dell'app read-file-upload-notification:

Output dell'app read-file-upload-notification

Passaggi successivi

In questo articolo si è appreso come usare la funzionalità di caricamento dei file di hub IoT per semplificare i caricamenti di file dai dispositivi. È possibile continuare a esplorare questa funzionalità con gli articoli seguenti:

Per altre informazioni sulle funzionalità dell'hub IoT, vedere: