Przekazywanie plików z urządzenia do chmury za pomocą usługi Azure IoT Hub (Java)

W tym artykule pokazano, jak przekazywać pliki możliwości przekazywania plików w usłudze IoT Hub do usługi Azure Blob Storage przy użyciu języka Java.

Artykuły Wysyłanie danych telemetrycznych z urządzenia do centrum IoT Hub i Wysyłanie komunikatów z chmury do urządzenia przy użyciu usługi IoT Hub pokazują podstawowe funkcje obsługi komunikatów między urządzeniami i chmurą w usłudze IoT Hub. Samouczek Konfigurowanie routingu komunikatów za pomocą usługi IoT Hub przedstawia sposób niezawodnego przechowywania komunikatów z urządzenia do chmury w usłudze Azure Blob Storage. Jednak w niektórych scenariuszach nie można łatwo mapować danych wysyłanych przez urządzenia do stosunkowo małych komunikatów z urządzenia do chmury akceptowanych przez usługę IoT Hub. Na przykład:

  • Filmy wideo
  • Duże pliki zawierające obrazy
  • Próbkowane dane drgań o wysokiej częstotliwości
  • Niektóre formy wstępnie przetworzonych danych.

Te pliki są zwykle przetwarzane wsadowo w chmurze przy użyciu narzędzi, takich jak usługa Azure Data Factory lub stos usługi Hadoop . Jeśli musisz przekazać pliki z urządzenia, nadal możesz korzystać z zabezpieczeń i niezawodności usługi IoT Hub. W tym artykule pokazano, jak to zrobić. Wyświetl dwa przykłady z witryny azure-iot-sdk-java w usłudze GitHub.

Uwaga

Usługa IoT Hub obsługuje wiele platform urządzeń i języków (w tym C, .NET i JavaScript) za pośrednictwem zestawów SDK urządzeń usługi Azure IoT. Zapoznaj się z centrum deweloperów usługi Azure IoT, aby dowiedzieć się, jak połączyć urządzenie z usługą Azure IoT Hub.

Ważne

Funkcje przekazywania plików na urządzeniach korzystających z uwierzytelniania urzędu certyfikacji X.509 są w publicznej wersji zapoznawczej, a tryb podglądu musi być włączony. Jest ona ogólnie dostępna na urządzeniach korzystających z uwierzytelniania odcisku palca X.509 lub zaświadczania certyfikatu X.509 za pomocą usługi Azure Device Provisioning Service. Aby dowiedzieć się więcej na temat uwierzytelniania X.509 w usłudze IoT Hub, zobacz Obsługiwane certyfikaty X.509.

Wymagania wstępne

  • Centrum IoT. Utwórz go za pomocą interfejsu wiersza polecenia lub witryny Azure Portal.

  • Zarejestrowane urządzenie. Zarejestruj je w witrynie Azure Portal.

  • Java SE Development Kit 8. Upewnij się, że wybrano środowisko Java 8 w obszarze Obsługa długoterminowa , aby pobrać plik JDK 8.

  • Maven 3

  • Port 8883 powinien być otwarty w zaporze. Przykład urządzenia w tym artykule używa protokołu MQTT, który komunikuje się za pośrednictwem portu 8883. Ten port może zostać zablokowany w niektórych środowiskach sieci firmowych i edukacyjnych. Aby uzyskać więcej informacji i sposobów obejścia tego problemu, zobacz Połączenie do usługi IoT Hub (MQTT).

Kojarzenie konta usługi Azure Storage z usługą IoT Hub

Aby przekazać pliki z urządzenia, musisz mieć konto usługi Azure Storage i kontener usługi Azure Blob Storage skojarzony z centrum IoT. Po skojarzeniu konta magazynu i kontenera z centrum IoT Hub centrum IoT hub może podać elementy identyfikatora URI sygnatury dostępu współdzielonego w przypadku żądania przez urządzenie. Następnie urządzenie może użyć tych elementów do skonstruowania identyfikatora URI sygnatury dostępu współdzielonego używanego do uwierzytelniania w usłudze Azure Storage i przekazywania plików do kontenera obiektów blob.

Aby skojarzyć konto usługi Azure Storage z centrum IoT:

  1. W obszarze Ustawienia centrum wybierz pozycję Przekazywanie pliku w okienku po lewej stronie centrum IoT Hub.

    Zrzut ekranu przedstawiający wybieranie ustawień przekazywania plików z portalu.

  2. W okienku Przekazywanie plików wybierz pozycję Kontener usługi Azure Storage. W tym artykule zaleca się, aby twoje konto magazynu i usługa IoT Hub znajdowały się w tym samym regionie.

    • Jeśli masz już konto magazynu, którego chcesz użyć, wybierz je z listy.

    • Aby utworzyć nowe konto magazynu, wybierz pozycję +Konto magazynu. Podaj nazwę konta magazynu i upewnij się, że lokalizacja jest ustawiona na ten sam region co centrum IoT, a następnie wybierz przycisk OK. Nowe konto jest tworzone w tej samej grupie zasobów co centrum IoT Hub. Po zakończeniu wdrażania wybierz konto magazynu z listy.

    Po wybraniu konta magazynu zostanie otwarte okienko Kontenery .

  3. W okienku Kontenery wybierz kontener obiektów blob.

    • Jeśli masz już kontener obiektów blob, którego chcesz użyć, wybierz go z listy i kliknij pozycję Wybierz.

    • Aby utworzyć nowy kontener obiektów blob, wybierz pozycję + Kontener. Podaj nazwę nowego kontenera. Na potrzeby tego artykułu można pozostawić wszystkie inne pola domyślnie. Wybierz pozycję Utwórz. Po zakończeniu wdrażania wybierz kontener z listy i kliknij pozycję Wybierz.

  4. Wróć do okienka Przekazywanie pliku, upewnij się, że powiadomienia o plikach są ustawione na włączone. Wszystkie inne ustawienia można pozostawić w ustawieniach domyślnych. Wybierz pozycję Zapisz i poczekaj na ukończenie ustawień przed przejściem do następnej sekcji.

    Przechwytywanie ekranu przedstawiające potwierdzanie ustawień przekazywania plików w portalu.

Aby uzyskać bardziej szczegółowe instrukcje dotyczące tworzenia konta usługi Azure Storage, zobacz Tworzenie konta magazynu. Aby uzyskać bardziej szczegółowe instrukcje dotyczące kojarzenia konta magazynu i kontenera obiektów blob z centrum IoT Hub, zobacz Konfigurowanie przekazywania plików przy użyciu witryny Azure Portal.

Tworzenie projektu przy użyciu narzędzia Maven

Utwórz katalog dla projektu i uruchom powłokę w tym katalogu. W wierszu polecenia wykonaj następujące polecenie

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

Spowoduje to wygenerowanie katalogu o takiej samej nazwie jak artifactId i standardowej strukturze projektu:

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

Za pomocą edytora tekstów zastąp plik pom.xml następującym kodem:


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

Przekazywanie pliku z aplikacji urządzenia

Skopiuj plik, który chcesz przekazać do my-app folderu w drzewie projektu. Za pomocą edytora tekstów zastąp App.java poniższym kodem. Podaj parametry połączenia urządzenia i nazwę pliku, gdzie jest zanotowany. Urządzenie zostało skopiowane parametry połączenia podczas rejestrowania urządzenia.

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

Kompilowanie i uruchamianie aplikacji

W wierszu polecenia w folderze my-app uruchom następujące polecenie:

mvn clean package -DskipTests

Po zakończeniu kompilacji uruchom następujące polecenie, aby uruchomić aplikację:

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

Za pomocą portalu możesz wyświetlić przekazany plik w skonfigurowanym kontenerze magazynu:

Zrzut ekranu przedstawiający plik przekazany do kontenera magazynu.

Otrzymywanie powiadomienia o przekazaniu pliku

W tej sekcji utworzysz aplikację konsolową Java, która odbiera komunikaty powiadomień o przekazaniu plików z usługi IoT Hub.

  1. Utwórz katalog dla projektu i uruchom powłokę w tym katalogu. W wierszu polecenia wykonaj następujące polecenie

    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false
    
  2. W wierszu polecenia przejdź do nowego my-app folderu.

  3. Za pomocą edytora tekstów zastąp pom.xml plik w my-app folderze następującym kodem. Dodanie zależności klienta usługi umożliwia używanie pakietu iothub-java-service-client w aplikacji do komunikowania się z usługą IoT Hub:

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

    Uwaga

    Możesz sprawdzić dostępność najnowszej wersji pakietu iot-service-client za pomocą funkcji wyszukiwania narzędzia Maven.

  4. Zapisz i zamknij pom.xml plik.

  5. Pobierz parametry połączenia usługi IoT Hub.

    Aby uzyskać parametry połączenia usługi IoT Hub dla zasad usługi, wykonaj następujące kroki:

    1. W witrynie Azure Portal wybierz pozycję Grupy zasobów. Wybierz grupę zasobów, w której znajduje się centrum, a następnie wybierz centrum z listy zasobów.

    2. W okienku po lewej stronie centrum IoT hub wybierz pozycję Zasady dostępu współdzielonego.

    3. Z listy zasad wybierz zasady usługi .

    4. Skopiuj parametry połączenia podstawową i zapisz wartość.

    Zrzut ekranu przedstawiający sposób pobierania parametry połączenia z usługi IoT Hub w witrynie Azure Portal.

    Aby uzyskać więcej informacji na temat zasad dostępu współdzielonego i uprawnień usługi IoT Hub, zobacz Kontrola dostępu i uprawnienia.

  6. Za pomocą edytora tekstów otwórz my-app\src\main\java\com\mycompany\app\App.java plik i zastąp kod poniższym kodem.

    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. Zapisz i zamknij my-app\src\main\java\com\mycompany\app\App.java plik.

  8. Użyj następującego polecenia, aby skompilować aplikację i sprawdzić, czy występują błędy:

    mvn clean package -DskipTests
    

Uruchamianie aplikacji

Teraz możesz uruchomić aplikację.

W wierszu polecenia w folderze my-app uruchom następujące polecenie:

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

Poniższy zrzut ekranu przedstawia dane wyjściowe z aplikacji read-file-upload-notification :

Dane wyjściowe z aplikacji read-file-upload-notification

Następne kroki

W tym artykule przedstawiono sposób użycia funkcji przekazywania plików usługi IoT Hub w celu uproszczenia przekazywania plików z urządzeń. Możesz kontynuować eksplorowanie tej funkcji, wykonując następujące artykuły:

Aby dokładniej zapoznać się z możliwościami usługi IoT Hub, zobacz: