Bagikan melalui


Menjadwalkan dan menyiarkan pekerjaan (Java)

Gunakan Azure IoT Hub untuk menjadwalkan dan melacak pekerjaan yang memperbarui jutaan perangkat. Gunakan pekerjaan untuk:

  • Memperbarui properti yang diinginkan
  • Memperbarui tag
  • Memanggil metode langsung

Pekerjaan membungkus salah satu tindakan ini dan melacak eksekusi terhadap sekumpulan perangkat. Kueri perangkat kembar mendefinisikan kumpulan perangkat yang digunakan untuk menjalankan tugas. Misalnya, aplikasi ujung belakang dapat menggunakan pekerjaan untuk memanggil metode langsung pada 10.000 perangkat yang mereboot perangkat. Anda menentukan kumpulan perangkat dengan kueri perangkat kembar dan menjadwalkan pekerjaan untuk dijalankan di waktu mendatang. Pekerjaan melacak kemajuan saat masing-masing perangkat menerima dan menjalankan metode langsung reboot.

Untuk mempelajari lebih lanjut tentang masing-masing kemampuan ini, lihat:

Catatan

Fitur yang dijelaskan dalam artikel ini hanya tersedia di tingkat standar IoT Hub. Untuk informasi selengkapnya tentang tingkat IoT Hub dasar dan standar/gratis, lihat Memilih tingkat IoT Hub yang tepat untuk solusi Anda.

Artikel ini menunjukkan kepada Anda cara membuat dua aplikasi Java:

  • Sebuah aplikasi perangkat, simulated-device, yang menerapkan metode langsung yang disebut lockDoor, yang dapat dipanggil oleh aplikasi backend.

  • Aplikasi backend, schedule-job, yang membuat dua pekerjaan. Satu pekerjaan memanggil metode langsung lockDoor dan pekerjaan lain mengirimkan pembaruan properti yang diinginkan ke beberapa perangkat.

Catatan

Lihat Azure IoT SDK untuk informasi selengkapnya tentang alat SDK yang tersedia untuk membangun aplikasi perangkat dan back-end.

Prasyarat

  • IoT Hub di langganan Azure Anda. Jika belum memiliki hub, Anda dapat mengikuti langkah-langkah di Membuat IoT hub.

  • Perangkat yang terdaftar di hub IoT Anda. Jika Anda tidak memiliki perangkat di hub IoT Anda, ikuti langkah-langkah di Mendaftarkan perangkat.

  • Java SE Development Kit 8. Pastikan Anda memilih Java 8 pada Dukungan jangka panjang untuk mengunduh JDK 8.

  • Maven 3

  • Pastikan port 8883 terbuka di firewall Anda. Sampel perangkat dalam artikel ini menggunakan protokol MQTT, yang berkomunikasi melalui port 8883. Port ini dapat diblokir di beberapa lingkungan jaringan perusahaan dan pendidikan. Untuk informasi selengkapnya dan cara mengatasi masalah ini, lihat Menyambungkan ke Azure IoT Hub (MQTT).

Catatan

Untuk mempermudah, artikel ini tidak menerapkan kebijakan coba lagi. Dalam kode produksi, Anda harus menerapkan kebijakan percobaan kembali (seperti backoff eksponensial), seperti yang disarankan dalam artikel, Penanganan Kesalahan Sementara.

Mendapatkan string koneksi IoT Hub

Dalam artikel ini, Anda membuat layanan back-end yang menjadwalkan pekerjaan untuk memanggil metode langsung pada perangkat, menjadwalkan pekerjaan untuk memperbarui kembaran perangkat, dan memantau kemajuan setiap pekerjaan. Untuk melakukan operasi ini, layanan Anda memerlukan izin baca registri dan penulisan registri. Secara default, setiap hub IoT dibuat dengan kebijakan akses bersama bernama registryReadWrite yang memberikan izin ini.

Untuk mendapatkan string koneksi IoT Hub untuk kebijakan registryReadWrite, ikuti langkah-langkah berikut:

  1. Di portal Azure, pilih Grup sumber daya. Pilih grup sumber daya tempat hub Anda berada, lalu pilih hub Anda dari daftar sumber daya.

  2. Di panel sisi kiri hub Anda, pilih Kebijakan akses bersama.

  3. Dari daftar kebijakan, pilih kebijakan registryReadWrite.

  4. Salin String koneksi utama dan simpan nilainya.

    Cuplikan layar yang menampilkan cara mengambil string koneksi

Untuk mengetahui informasi selengkapnya tentang kebijakan dan izin akses bersama IoT Hub, lihat Kontrol akses dan izin.

Membuat aplikasi layanan

Di bagian ini, Anda membuat aplikasi konsol Java yang menggunakan pekerjaan untuk:

  • Panggil metode langsung lockDoor di beberapa perangkat.

  • Kirim properti yang diinginkan ke beberapa perangkat.

Untuk membuat aplikasi:

  1. Di mesin pengembangan Anda, buat folder kosong bernama iot-java-schedule-jobs.

  2. Di folder iot-java-schedule-jobs, buat proyek Maven bernama schedule-jobs menggunakan perintah berikut pada prompt perintah Anda. Perhatikan ini adalah perintah tunggal yang panjang:

    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=schedule-jobs -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    
  3. Pada prompt perintah Anda, arahkan ke folder schedule-jobs.

  4. Dengan menggunakan editor teks, buka file pom.xml di folder schedule-jobs dan tambahkan dependensi berikut ke simpul dependensi. Dependensi ini memungkinkan Anda menggunakan paket iot-service-client di aplikasi Anda untuk berkomunikasi dengan IoT hub Anda:

    <dependency>
      <groupId>com.microsoft.azure.sdk.iot</groupId>
      <artifactId>iot-service-client</artifactId>
      <version>1.17.1</version>
      <type>jar</type>
    </dependency>
    

    Catatan

    Anda dapat memeriksa versi terbaru iot-service-client menggunakan pencarian Maven.

  5. Tambahkan simpul build berikut setelah simpul dependensi. Konfigurasi ini menginstruksikan Maven untuk menggunakan Java 1.8 untuk membangun aplikasi:

    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.3</version>
          <configuration>
            <source>1.8</source>
            <target>1.8</target>
          </configuration>
        </plugin>
      </plugins>
    </build>
    
  6. Simpan dan tutup file pom.xml.

  7. Menggunakan editor teks, buka file schedule-jobs\src\main\java\com\mycompany\app\App.java.

  8. Tambahkan pernyataan impor berikut ke file:

    import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceTwinDevice;
    import com.microsoft.azure.sdk.iot.service.devicetwin.Pair;
    import com.microsoft.azure.sdk.iot.service.devicetwin.Query;
    import com.microsoft.azure.sdk.iot.service.devicetwin.SqlQuery;
    import com.microsoft.azure.sdk.iot.service.jobs.JobClient;
    import com.microsoft.azure.sdk.iot.service.jobs.JobResult;
    import com.microsoft.azure.sdk.iot.service.jobs.JobStatus;
    
    import java.util.Date;
    import java.time.Instant;
    import java.util.HashSet;
    import java.util.Set;
    import java.util.UUID;
    
  9. Tambahkan variabel tingkat kelas berikut ke kelas Aplikasi. Ganti {youriothubconnectionstring} dengan string koneksi IoT hub yang Anda salin sebelumnya di Dapatkan string koneksi IoT hub:

    public static final String iotHubConnectionString = "{youriothubconnectionstring}";
    public static final String deviceId = "myDeviceId";
    
    // How long the job is permitted to run without
    // completing its work on the set of devices
    private static final long maxExecutionTimeInSeconds = 30;
    
  10. Tambahkan metode berikut ke kelas Aplikasi untuk menjadwalkan pekerjaan untuk memperbarui properti Bangunan dan Lantai yang diinginkan di perangkat kembar:

    private static JobResult scheduleJobSetDesiredProperties(JobClient jobClient, String jobId) {
      DeviceTwinDevice twin = new DeviceTwinDevice(deviceId);
      Set<Pair> desiredProperties = new HashSet<Pair>();
      desiredProperties.add(new Pair("Building", 43));
      desiredProperties.add(new Pair("Floor", 3));
      twin.setDesiredProperties(desiredProperties);
      // Optimistic concurrency control
      twin.setETag("*");
    
      // Schedule the update twin job to run now
      // against a single device
      System.out.println("Schedule job " + jobId + " for device " + deviceId);
      try {
        JobResult jobResult = jobClient.scheduleUpdateTwin(jobId, 
          "deviceId='" + deviceId + "'",
          twin,
          new Date(),
          maxExecutionTimeInSeconds);
        return jobResult;
      } catch (Exception e) {
        System.out.println("Exception scheduling desired properties job: " + jobId);
        System.out.println(e.getMessage());
        return null;
      }
    }
    
  11. Untuk menjadwalkan tugas memanggil metode lockDoor, tambahkan metode berikut ke kelas Aplikasi:

    private static JobResult scheduleJobCallDirectMethod(JobClient jobClient, String jobId) {
      // Schedule a job now to call the lockDoor direct method
      // against a single device. Response and connection
      // timeouts are set to 5 seconds.
      System.out.println("Schedule job " + jobId + " for device " + deviceId);
      try {
        JobResult jobResult = jobClient.scheduleDeviceMethod(jobId,
          "deviceId='" + deviceId + "'",
          "lockDoor",
          5L, 5L, null,
          new Date(),
          maxExecutionTimeInSeconds);
        return jobResult;
      } catch (Exception e) {
        System.out.println("Exception scheduling direct method job: " + jobId);
        System.out.println(e.getMessage());
        return null;
      }
    };
    
  12. Untuk memantau pekerjaan, tambahkan metode berikut ke kelas Aplikasi:

    private static void monitorJob(JobClient jobClient, String jobId) {
      try {
        JobResult jobResult = jobClient.getJob(jobId);
        if(jobResult == null)
        {
          System.out.println("No JobResult for: " + jobId);
          return;
        }
        // Check the job result until it's completed
        while(jobResult.getJobStatus() != JobStatus.completed)
        {
          Thread.sleep(100);
          jobResult = jobClient.getJob(jobId);
          System.out.println("Status " + jobResult.getJobStatus() + " for job " + jobId);
        }
        System.out.println("Final status " + jobResult.getJobStatus() + " for job " + jobId);
      } catch (Exception e) {
        System.out.println("Exception monitoring job: " + jobId);
        System.out.println(e.getMessage());
        return;
      }
    }
    
  13. Untuk mengkueri detail pekerjaan yang Anda jalankan, tambahkan metode berikut:

    private static void queryDeviceJobs(JobClient jobClient, String start) throws Exception {
      System.out.println("\nQuery device jobs since " + start);
    
      // Create a jobs query using the time the jobs started
      Query deviceJobQuery = jobClient
          .queryDeviceJob(SqlQuery.createSqlQuery("*", SqlQuery.FromType.JOBS, "devices.jobs.startTimeUtc > '" + start + "'", null).getQuery());
    
      // Iterate over the list of jobs and print the details
      while (jobClient.hasNextJob(deviceJobQuery)) {
        System.out.println(jobClient.getNextJob(deviceJobQuery));
      }
    }
    
  14. Perbarui tanda tangan metode utama untuk menyertakan klausul throws berikut:

    public static void main( String[] args ) throws Exception
    
  15. Untuk menjalankan dan memantau dua pekerjaan secara berurutan, ganti kode dalam metode utama dengan kode berikut:

    // Record the start time
    String start = Instant.now().toString();
    
    // Create JobClient
    JobClient jobClient = JobClient.createFromConnectionString(iotHubConnectionString);
    System.out.println("JobClient created with success");
    
    // Schedule twin job desired properties
    // Maximum concurrent jobs is 1 for Free and S1 tiers
    String desiredPropertiesJobId = "DPCMD" + UUID.randomUUID();
    scheduleJobSetDesiredProperties(jobClient, desiredPropertiesJobId);
    monitorJob(jobClient, desiredPropertiesJobId);
    
    // Schedule twin job direct method
    String directMethodJobId = "DMCMD" + UUID.randomUUID();
    scheduleJobCallDirectMethod(jobClient, directMethodJobId);
    monitorJob(jobClient, directMethodJobId);
    
    // Run a query to show the job detail
    queryDeviceJobs(jobClient, start);
    
    System.out.println("Shutting down schedule-jobs app");
    
  16. Simpan dan tutup file schedule-jobs\src\main\java\com\mycompany\app\App.java

  17. Buat aplikasi schedule-jobs dan perbaiki kesalahan apa pun. Pada prompt perintah Anda, arahkan ke folder schedule-jobs dan jalankan perintah berikut:

    mvn clean package -DskipTests
    

Membuat aplikasi perangkat

Di bagian ini, Anda membuat aplikasi konsol Java yang menangani properti yang diinginkan yang dikirim dari IoT Hub dan mengimplementasikan panggilan metode langsung.

  1. Di folder iot-java-schedule-jobs, buat proyek Maven bernama simulated-device menggunakan perintah berikut di prompt perintah Anda. Perhatikan ini adalah perintah tunggal yang panjang:

    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=simulated-device -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    
  2. Pada perintah Anda, navigasikan ke folder simulated-device.

  3. Menggunakan editor teks, buka file pom.xml di folder perangkat yang disimulasi dan tambahkan dependensi berikut ke simpul dependensi. Dependensi ini memungkinkan Anda menggunakan paket iot-device-client di aplikasi Anda untuk berkomunikasi dengan IoT hub Anda:

    <dependency>
      <groupId>com.microsoft.azure.sdk.iot</groupId>
      <artifactId>iot-device-client</artifactId>
      <version>1.17.5</version>
    </dependency>
    

    Catatan

    Anda dapat memeriksa versi terbaru iot-device-client menggunakan penelusuran Maven.

  4. Tambahkan dependensi berikut ke simpul dependencies. Dependensi ini mengonfigurasi NOP untuk fasad pengelogan Apache SLF4J, yang digunakan oleh SDK klien perangkat untuk menerapkan pengelogan. Konfigurasi ini bersifat opsional, tetapi, jika Anda menghilangkannya, Anda mungkin melihat peringatan di konsol saat menjalankan aplikasi. Untuk informasi lebih lanjut tentang masuk di SDK klien perangkat, lihat Pengelogan di file readme Sampel untuk Azure IoT device SDK untuk Java.

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-nop</artifactId>
      <version>1.7.28</version>
    </dependency>
    
  5. Tambahkan simpul build berikut setelah simpul dependensi. Konfigurasi ini menginstruksikan Maven untuk menggunakan Java 1.8 untuk membangun aplikasi:

    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.3</version>
          <configuration>
            <source>1.8</source>
            <target>1.8</target>
          </configuration>
        </plugin>
      </plugins>
    </build>
    
  6. Simpan dan tutup file pom.xml.

  7. Menggunakan editor teks, buka file simulated-device\src\main\java\com\mycompany\app\App.java.

  8. Tambahkan pernyataan impor berikut ke file:

    import com.microsoft.azure.sdk.iot.device.*;
    import com.microsoft.azure.sdk.iot.device.DeviceTwin.*;
    
    import java.io.IOException;
    import java.net.URISyntaxException;
    import java.util.Scanner;
    
  9. Tambahkan variabel tingkat kelas berikut ke kelas Aplikasi. Ganti {yourdeviceconnectionstring} dengan string koneksi perangkat yang Anda lihat saat mendaftarkan perangkat di IoT Hub:

    private static String connString = "{yourdeviceconnectionstring}";
    private static IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;
    private static final int METHOD_SUCCESS = 200;
    private static final int METHOD_NOT_DEFINED = 404;
    

    Aplikasi sampel ini menggunakan variabel protokol saat membuat instans objek DeviceClient.

  10. Untuk mencetak pemberitahuan perangkat kembar ke konsol, tambahkan kelas bertumpuk berikut ke kelas Aplikasi:

    // Handler for device twin operation notifications from IoT Hub
    protected static class DeviceTwinStatusCallBack implements IotHubEventCallback {
      public void execute(IotHubStatusCode status, Object context) {
        System.out.println("IoT Hub responded to device twin operation with status " + status.name());
      }
    }
    
  11. Untuk mencetak pemberitahuan metode langsung ke konsol, tambahkan kelas bertumpuk berikut ke kelas Aplikasi:

    // Handler for direct method notifications from IoT Hub
    protected static class DirectMethodStatusCallback implements IotHubEventCallback {
      public void execute(IotHubStatusCode status, Object context) {
        System.out.println("IoT Hub responded to direct method operation with status " + status.name());
      }
    }
    
  12. Untuk menangani panggilan metode langsung dari IoT Hub, tambahkan kelas bertumpuk berikut ke kelas Aplikasi:

    // Handler for direct method calls from IoT Hub
    protected static class DirectMethodCallback
        implements DeviceMethodCallback {
      @Override
      public DeviceMethodData call(String methodName, Object methodData, Object context) {
        DeviceMethodData deviceMethodData;
        switch (methodName) {
          case "lockDoor": {
            System.out.println("Executing direct method: " + methodName);
            deviceMethodData = new DeviceMethodData(METHOD_SUCCESS, "Executed direct method " + methodName);
            break;
          }
          default: {
            deviceMethodData = new DeviceMethodData(METHOD_NOT_DEFINED, "Not defined direct method " + methodName);
          }
        }
        // Notify IoT Hub of result
        return deviceMethodData;
      }
    }
    
  13. Perbarui tanda tangan metode utama untuk menyertakan klausul throws berikut:

    public static void main( String[] args ) throws IOException, URISyntaxException
    
  14. Ganti kode pada metode utama dengan kode berikut ke:

    • Buat klien perangkat untuk berkomunikasi dengan IoT Hub.
    • Buat objek Perangkat untuk menyimpan properti perangkat ganda.
    // Create a device client
    DeviceClient client = new DeviceClient(connString, protocol);
    
    // An object to manage device twin desired and reported properties
    Device dataCollector = new Device() {
      @Override
      public void PropertyCall(String propertyKey, Object propertyValue, Object context)
      {
        System.out.println("Received desired property change: " + propertyKey + " " + propertyValue);
      }
    };
    
  15. Untuk memulai layanan klien perangkat, tambahkan kode berikut ke metode utama:

    try {
      // Open the DeviceClient
      // Start the device twin services
      // Subscribe to direct method calls
      client.open();
      client.startDeviceTwin(new DeviceTwinStatusCallBack(), null, dataCollector, null);
      client.subscribeToDeviceMethod(new DirectMethodCallback(), null, new DirectMethodStatusCallback(), null);
    } catch (Exception e) {
      System.out.println("Exception, shutting down \n" + " Cause: " + e.getCause() + " \n" + e.getMessage());
      dataCollector.clean();
      client.closeNow();
      System.out.println("Shutting down...");
    }
    
  16. Untuk menunggu pengguna menekan tombol Enter sebelum mematikan, tambahkan kode berikut di akhir metode utama:

    // Close the app
    System.out.println("Press any key to exit...");
    Scanner scanner = new Scanner(System.in);
    scanner.nextLine();
    dataCollector.clean();
    client.closeNow();
    scanner.close();
    
  17. Simpan dan tutup file simulated-device\src\main\java\com\mycompany\app\App.java.

  18. Bangun aplikasi simulated-device dan perbaiki kesalahan apa pun. Pada perintah Anda, navigasikan ke folder simulated-device dan jalankan perintah berikut:

    mvn clean package -DskipTests
    

Menjalankan aplikasi

Anda sekarang siap untuk menjalankan aplikasi konsol.

  1. Pada prompt perintah di folder perangkat simulasi, jalankan perintah berikut untuk memulai aplikasi perangkat mendengarkan perubahan properti yang diinginkan dan panggilan metode langsung:

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

    Klien perangkat dimulai

  2. Pada prompt perintah di folder schedule-jobs, jalankan perintah berikut untuk menjalankan aplikasi layanan schedule-jobs untuk menjalankan dua pekerjaan. Yang pertama mengatur nilai properti yang diinginkan, yang kedua memanggil metode langsung:

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

    Aplikasi layanan Java IoT Hub menciptakan dua pekerjaan

  3. Aplikasi perangkat menangani perubahan properti yang diinginkan dan pemanggilan metode langsung:

    Klien perangkat merespons perubahan

Langkah berikutnya

Dalam artikel ini, Anda menjadwalkan pekerjaan untuk menjalankan metode langsung dan memperbarui properti kembar perangkat.

Untuk terus menjelajahi IoT Hub dan pola pengelolaan perangkat, perbarui gambar di tutorial Pembaruan Perangkat untuk Azure IoT Hub menggunakan Gambar Referensi Raspberry Pi 3 B+.