Mengimpor dan mengekspor identitas perangkat IoT Hub secara massal

Setiap hub IoT memiliki registri identitas yang dapat Anda gunakan untuk membuat sumber daya per perangkat dalam layanan. Registri identitas juga mengaktifkan Anda mengontrol akses ke titik akhir yang menghadap perangkat. Artikel ini menjelaskan cara mengimpor dan mengekspor identitas perangkat secara massal ke dan dari registri identitas. Untuk melihat sampel yang berfungsi di C# dan mempelajari bagaimana Anda dapat menggunakan kemampuan ini saat mengkloning hub ke wilayah lain, lihat Cara Mengkloning IoT Hub.

Catatan

IoT Hub baru-baru ini menambahkan dukungan jaringan virtual di sejumlah wilayah yang terbatas. Fitur ini mengamankan operasi impor dan ekspor dan menghilangkan kebutuhan meneruskan kunci untuk autentikasi. Awalnya, dukungan jaringan virtual hanya tersedia di wilayah ini: WestUS2, EastUS, dan SouthCentralUS. Untuk mempelajari selengkapnya tentang dukungan jaringan virtual dan panggilan API untuk mengimplementasikannya, lihat Dukungan Azure IoT Hub untuk jaringan virtual.

Operasi impor dan ekspor berlangsung dalam konteks Pekerjaan yang mengaktifkan Anda menjalankan operasi layanan massal terhadap hub IoT.

Kelas RegistryManager mencakup metode ExportDevicesAsync dan ImportDevicesAsync yang menggunakan kerangka kerja Pekerjaan. Metode ini mengaktifkan Anda untuk mengekspor, mengimpor, dan menyinkronkan keseluruhan registri identitas hub IoT.

Topik ini membahas penggunaan kelas RegistryManager dan sistem Pekerjaan untuk melakukan impor dan ekspor massal perangkat ke dan dari registri identitas hub IoT. Anda juga dapat menggunakan Azure IoT Hub Device Provisioning Service untuk mengaktifkan provisi just-in-time tanpa sentuhan ke satu atau beberapa hub IoT tanpa memerlukan intervensi manusia. Untuk mempelajari lebih lanjut, lihat dokumentasi layanan provisi.

Apa itu pekerjaan?

Operasi registri identitas menggunakan sistem Pekerjaan saat operasi:

  • BErpotensi memiliki waktu eksekusi yang lama dibandingkan dengan operasi run-time standar.

  • Memberikan sejumlah besar data kepada pengguna.

Alih-alih satu panggilan API menunggu atau memblok hasil operasi, operasi secara asinkron membuat Pekerjaan untuk hub IoT tersebut. Operasi kemudian segera mengembalikan objek JobProperties.

Cuplikan kode C# berikut menunjukkan cara membuat pekerjaan ekspor:

// Call an export job on the IoT Hub to retrieve all devices
JobProperties exportJob = await 
  registryManager.ExportDevicesAsync(containerSasUri, false);

Catatan

Untuk menggunakan kelas RegistryManager di kode C# Anda, tambahkan paket NuGet Microsoft.Azure.Devices ke proyek Anda. Kelas RegistryManager berada di ruang nama Microsoft.Azure.Devices.

Anda dapat menggunakan kelas RegistryManager untuk mengkueri status Pekerjaan menggunakan metadata JobProperties yang dihasilkan. Untuk membuat instans kelas RegistryManager, gunakan metode CreateFromConnectionString.

RegistryManager registryManager =
  RegistryManager.CreateFromConnectionString("{your IoT Hub connection string}");

Untuk menemukan string koneksi untuk hub IoT Anda, di portal Microsoft Azure:

  • Buka IoT Hub Anda.

  • Pilih Kebijakan akses bersama.

  • Pilih kebijakan, dengan mempertimbangkan izin yang Anda butuhkan.

  • Salin connectionstring dari panel di sisi kanan layar.

Cuplikan kode C# berikut menunjukkan cara melakukan polling setiap lima detik untuk melihat apakah pekerjaan telah selesai dieksekusi:

// Wait until job is finished
while(true)
{
  exportJob = await registryManager.GetJobAsync(exportJob.JobId);
  if (exportJob.Status == JobStatus.Completed || 
      exportJob.Status == JobStatus.Failed ||
      exportJob.Status == JobStatus.Cancelled)
  {
    // Job has finished executing
    break;
  }

  await Task.Delay(TimeSpan.FromSeconds(5));
}

Catatan

Jika akun penyimpanan Anda memiliki konfigurasi firewall yang membatasi konektivitas IoT Hub, pertimbangkan untuk menggunakan pengecualian pihak pertama tepercaya Microsoft (tersedia di wilayah tertentu untuk hub IoT dengan identitas layanan terkelola).

Batas pekerjaan impor/ekspor perangkat

Hanya 1 pekerjaan impor atau ekspor perangkat aktif yang diizinkan pada satu waktu untuk semua tingkat IoT Hub. IoT Hub juga memiliki batasan untuk tingkat operasi pekerjaan. Untuk mempelajari lebih lanjut, lihat Referensi - Kuota dan pembatasan Azure IoT Hub.

Mengekspor perangkat

Gunakan metode ExportDevicesAsync untuk mengekspor keseluruhan registri identitas hub IoT ke kontainer blob Microsoft Azure Storage menggunakan tanda tangan akses bersama (SAS). Untuk informasi selengkapnya tentang tanda tangan akses bersama, lihat Berikan akses terbatas ke sumber daya Azure Storage dengan menggunakan tanda tangan akses bersama (SAS).

Metode ini mengaktifkan Anda membuat cadangan informasi perangkat yang andal dalam kontainer blob yang Anda kontrol.

Metode ExportDevicesAsync memerlukan dua parameter:

  • String yang berisi URI dari kontainer blob. URI ini harus berisi token SAS yang memberikan akses tulis ke kontainer. Pekerjaan membuat blob blok dalam kontainer ini untuk menyimpan data perangkat ekspor berseri. Token SAS harus menyertakan izin ini:

    SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Read 
       | SharedAccessBlobPermissions.Delete
    
  • Boolean yang menunjukkan apakah Anda ingin mengecualikan kunci autentikasi dari data ekspor Anda. Jika tidak, kunci autentikasi disertakan dalam output ekspor. Jika sebaliknya, kunci diekspor sebagai null.

Cuplikan kode C# berikut menunjukkan cara memulai pekerjaan ekspor yang menyertakan kunci autentikasi perangkat dalam data ekspor dan kemudian polling untuk penyelesaian:

// Call an export job on the IoT Hub to retrieve all devices
JobProperties exportJob = 
  await registryManager.ExportDevicesAsync(containerSasUri, false);

// Wait until job is finished
while(true)
{
    exportJob = await registryManager.GetJobAsync(exportJob.JobId);
    if (exportJob.Status == JobStatus.Completed || 
        exportJob.Status == JobStatus.Failed ||
        exportJob.Status == JobStatus.Cancelled)
    {
    // Job has finished executing
    break;
    }

    await Task.Delay(TimeSpan.FromSeconds(5));
}

Pekerjaan menyimpan outputnya dalam kontainer blob yang disediakan sebagai blob blok dengan nama devices.txt. Data output terdiri dari data perangkat berseri JSON, dengan satu perangkat per baris.

Contoh berikut menunjukkan data output:

{"id":"Device1","eTag":"MA==","status":"enabled","authentication":{"symmetricKey":{"primaryKey":"abc=","secondaryKey":"def="}}}
{"id":"Device2","eTag":"MA==","status":"enabled","authentication":{"symmetricKey":{"primaryKey":"abc=","secondaryKey":"def="}}}
{"id":"Device3","eTag":"MA==","status":"disabled","authentication":{"symmetricKey":{"primaryKey":"abc=","secondaryKey":"def="}}}
{"id":"Device4","eTag":"MA==","status":"disabled","authentication":{"symmetricKey":{"primaryKey":"abc=","secondaryKey":"def="}}}
{"id":"Device5","eTag":"MA==","status":"enabled","authentication":{"symmetricKey":{"primaryKey":"abc=","secondaryKey":"def="}}}

Jika perangkat memiliki data kembar, maka data kembar juga diekspor bersama dengan data perangkat. Contoh berikut memperlihatkan format ini. Semua data dari baris "twinETag" hingga akhir adalah data kembar.

{
   "id":"export-6d84f075-0",
   "eTag":"MQ==",
   "status":"enabled",
   "statusReason":"firstUpdate",
   "authentication":null,
   "twinETag":"AAAAAAAAAAI=",
   "tags":{
      "Location":"LivingRoom"
   },
   "properties":{
      "desired":{
         "Thermostat":{
            "Temperature":75.1,
            "Unit":"F"
         },
         "$metadata":{
            "$lastUpdated":"2017-03-09T18:30:52.3167248Z",
            "$lastUpdatedVersion":2,
            "Thermostat":{
               "$lastUpdated":"2017-03-09T18:30:52.3167248Z",
               "$lastUpdatedVersion":2,
               "Temperature":{
                  "$lastUpdated":"2017-03-09T18:30:52.3167248Z",
                  "$lastUpdatedVersion":2
               },
               "Unit":{
                  "$lastUpdated":"2017-03-09T18:30:52.3167248Z",
                  "$lastUpdatedVersion":2
               }
            }
         },
         "$version":2
      },
      "reported":{
         "$metadata":{
            "$lastUpdated":"2017-03-09T18:30:51.1309437Z"
         },
         "$version":1
      }
   }
}

Jika Anda memerlukan akses ke data ini dalam kode, Anda dapat dengan mudah mendeserialisasi data ini menggunakan kelas ExportImportDevice. Cuplikan kode C# berikut menunjukkan cara membaca informasi perangkat yang sebelumnya diekspor ke blob blok:

var exportedDevices = new List<ExportImportDevice>();

using (var streamReader = new StreamReader(await blob.OpenReadAsync(AccessCondition.GenerateIfExistsCondition(), null, null), Encoding.UTF8))
{
  while (streamReader.Peek() != -1)
  {
    string line = await streamReader.ReadLineAsync();
    var device = JsonConvert.DeserializeObject<ExportImportDevice>(line);
    exportedDevices.Add(device);
  }
}

Mengimpor perangkat

Metode ImportDevicesAsync di kelas RegistryManager mengaktifkan Anda melakukan operasi impor dan sinkronisasi massal dalam registri identitas hub IoT. Seperti metode ExportDevicesAsync, metode ImportDevicesAsync menggunakan kerangka kerja Pekerjaan.

Berhati-hatilah menggunakan metode ImportDevicesAsync karena selain provisi perangkat baru di registri identitas Anda, ia juga dapat memperbarui dan menghapus perangkat yang ada.

Peringatan

Operasi impor tak bisa dibatalkan. Selalu cadangkan data Anda yang ada menggunakan metode ExportDevicesAsync ke kontainer blob lain sebelum Anda membuat perubahan massal pada registri identitas Anda.

Metode ExportDevicesAsync memerlukan dua parameter:

  • String yang berisi URI dari kontainer blob Azure Storage untuk digunakan sebagai input ke pekerjaan. URI ini harus berisi token SAS yang memberikan akses baca ke kontainer. Kontainer ini harus berisi blob dengan nama devices.txt berisi data perangkat berseri untuk diimpor ke registri identitas Anda. Data impor harus berisi informasi perangkat dalam format JSON yang sama dengan yang digunakan oleh pekerjaan ExportImportDevice saat membuat blob devices.txt. Token SAS harus menyertakan izin ini:

    SharedAccessBlobPermissions.Read
    
  • String yang berisi URI dari kontainer blob Azure Storage untuk digunakan sebagai output dari pekerjaan. Pekerjaan membuat blob blok dalam kontainer ini untuk menyimpan informasi kesalahan dari pekerjaan impor yang telah selesai. Token SAS harus menyertakan izin ini:

    SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Read 
       | SharedAccessBlobPermissions.Delete
    

Catatan

Dua parameter dapat menunjuk ke kontainer blob yang sama. Parameter terpisah hanya mengaktifkan lebih banyak kontrol atas data Anda karena kontainer output memerlukan izin tambahan.

Cuplikan kode C# berikut ini memperlihatkan cara memulai pekerjaan impor:

JobProperties importJob = 
   await registryManager.ImportDevicesAsync(containerSasUri, containerSasUri);

Metode ini juga dapat digunakan untuk mengimpor data untuk perangkat kembar. Format untuk input data sama dengan format yang diperlihatkan di bagian ExportDevicesAsync. Dengan cara ini, Anda dapat mengimpor kembali data yang diekspor. $metadata bersifat opsional.

Perilaku impor

Anda dapat menggunakan metode ImportDevicesAsync untuk melakukan operasi massal berikut di registri identitas Anda:

  • Pendaftaran massal perangkat baru
  • Penghapusan massal perangkat yang ada
  • Perubahan status massal (aktifkan atau nonaktifkan perangkat)
  • Penetapan massal kunci autentikasi perangkat baru
  • Regenerasi otomatis massal kunci autentikasi perangkat
  • Pembaruan data kembar secara massal

Anda dapat melakukan kombinasi operasi tadi dalam satu panggilan ImportDevicesAsync. Misalnya, Anda dapat mendaftarkan perangkat baru dan menghapus atau memperbarui perangkat yang ada secara bersamaan. Ketika digunakan bersama dengan metode ExportDevicesAsync, Anda dapat sepenuhnya memigrasikan semua perangkat Anda dari satu hub IoT ke hub IoT lainnya.

Jika file impor menyertakan metadata kembar, maka metadata ini menimpa metadata kembar yang ada. Jika file impor tidak menyertakan metadata kembar, maka hanya lastUpdateTime metadata yang diperbarui menggunakan waktu saat ini.

Gunakan properti importMode opsional dalam data serialisasi impor untuk setiap perangkat untuk mengontrol proses impor per perangkat. Properti importMode memiliki opsi berikut:

importMode Deskripsi
Buat Jika perangkat tidak ada dengan yang ID ditentukan, perangkat baru terdaftar. Jika perangkat sudah ada, kesalahan ditulis ke file log.
CreateOrUpdate Jika perangkat tidak ada dengan yang ID ditentukan, perangkat baru terdaftar. Jika perangkat sudah ada, informasi yang ada ditimpa dengan data input yang disediakan tanpa memperhatikan nilai ETag.
CreateOrUpdateIfMatchETag Jika perangkat tidak ada dengan yang ID ditentukan, perangkat baru terdaftar. Jika perangkat sudah ada, informasi yang ada ditimpa dengan data input yang disediakan hanya jika ada kecocokan ETag. Jika ada ketidakcocokan ETag, kesalahan ditulis ke file log.
Hapus Jika perangkat sudah ada dengan ID yang ditentukan, perangkat akan dihapus tanpa memperhatikan nilai ETag. Jika perangkat tidak ada, kesalahan ditulis ke file log.
DeleteIfMatchETag Jika perangkat sudah ada dengan ID yang ditentukan, perangkat akan dihapus hanya jika ada kecocokan ETag. Jika perangkat tidak ada, kesalahan ditulis ke file log. Jika ada ketidakcocokan ETag, kesalahan ditulis ke file log.
Pembaruan Jika perangkat sudah ada dengan ID yang ditentukan, informasi yang ada ditimpa dengan data input yang disediakan tanpa memperhatikan nilai ETag. Jika perangkat tidak ada, kesalahan ditulis ke file log.
UpdateIfMatchETag Jika perangkat sudah ada dengan ID yang ditentukan, informasi yang ada ditimpa dengan data input yang disediakan hanya jika ada kecocokan ETag. Jika perangkat tidak ada atau terdapat ketidakcocokan ETag, kesalahan ditulis ke file log.
UpdateTwin Jika kembar sudah ada dengan ID yang ditentukan, informasi yang ada ditimpa dengan data input yang disediakan tanpa memperhatikan nilai ETag kembar.
UpdateTwinIfMatchETag Jika perangkat sudah ada dengan ID yang ditentukan, informasi yang ada ditimpa dengan data input yang disediakan hanya jika ada kecocokan pada nilai ETag kembar. ETag kembar diproses secara independen dari ETag perangkat. Jika ada ketidakcocokan dengan ETag kembar yang ada, kesalahan ditulis ke file log.

Catatan

Jika data serialisasi tidak secara eksplisit menentukan bendera importMode untuk perangkat, data tersebut default untukcreateOrUpdate selama operasi impor.

Contoh impor perangkat – provisi perangkat massal

Sampel kode C# berikut ini menggambarkan cara menghasilkan beberapa identitas perangkat yang:

  • Menyertakan kunci autentikasi.
  • Menulis informasi perangkat itu ke blob blok.
  • Mengimpor perangkat ke dalam registri identitas.
// Provision 1,000 more devices
var serializedDevices = new List<string>();

for (var i = 0; i < 1000; i++)
{
  // Create a new ExportImportDevice
  // CryptoKeyGenerator is in the Microsoft.Azure.Devices.Common namespace
  var deviceToAdd = new ExportImportDevice()
  {
    Id = Guid.NewGuid().ToString(),
    Status = DeviceStatus.Enabled,
    Authentication = new AuthenticationMechanism()
    {
      SymmetricKey = new SymmetricKey()
      {
        PrimaryKey = CryptoKeyGenerator.GenerateKey(32),
        SecondaryKey = CryptoKeyGenerator.GenerateKey(32)
      }
    },
    ImportMode = ImportMode.Create
  };

  // Add device to the list
  serializedDevices.Add(JsonConvert.SerializeObject(deviceToAdd));
}

// Write the list to the blob
var sb = new StringBuilder();
serializedDevices.ForEach(serializedDevice => sb.AppendLine(serializedDevice));
await blob.DeleteIfExistsAsync();

using (CloudBlobStream stream = await blob.OpenWriteAsync())
{
  byte[] bytes = Encoding.UTF8.GetBytes(sb.ToString());
  for (var i = 0; i < bytes.Length; i += 500)
  {
    int length = Math.Min(bytes.Length - i, 500);
    await stream.WriteAsync(bytes, i, length);
  }
}

// Call import using the blob to add new devices
// Log information related to the job is written to the same container
// This normally takes 1 minute per 100 devices
JobProperties importJob =
   await registryManager.ImportDevicesAsync(containerSasUri, containerSasUri);

// Wait until job is finished
while(true)
{
  importJob = await registryManager.GetJobAsync(importJob.JobId);
  if (importJob.Status == JobStatus.Completed || 
      importJob.Status == JobStatus.Failed ||
      importJob.Status == JobStatus.Cancelled)
  {
    // Job has finished executing
    break;
  }

  await Task.Delay(TimeSpan.FromSeconds(5));
}

Contoh impor perangkat – penghapusan massal

Sampel kode berikut menunjukkan cara menghapus perangkat yang Anda tambahkan menggunakan sampel kode sebelumnya:

// Step 1: Update each device's ImportMode to be Delete
sb = new StringBuilder();
serializedDevices.ForEach(serializedDevice =>
{
  // Deserialize back to an ExportImportDevice
  var device = JsonConvert.DeserializeObject<ExportImportDevice>(serializedDevice);

  // Update property
  device.ImportMode = ImportMode.Delete;

  // Re-serialize
  sb.AppendLine(JsonConvert.SerializeObject(device));
});

// Step 2: Write the new import data back to the block blob
await blob.DeleteIfExistsAsync();
using (CloudBlobStream stream = await blob.OpenWriteAsync())
{
  byte[] bytes = Encoding.UTF8.GetBytes(sb.ToString());
  for (var i = 0; i < bytes.Length; i += 500)
  {
    int length = Math.Min(bytes.Length - i, 500);
    await stream.WriteAsync(bytes, i, length);
  }
}

// Step 3: Call import using the same blob to delete all devices
importJob = await registryManager.ImportDevicesAsync(containerSasUri, containerSasUri);

// Wait until job is finished
while(true)
{
  importJob = await registryManager.GetJobAsync(importJob.JobId);
  if (importJob.Status == JobStatus.Completed || 
      importJob.Status == JobStatus.Failed ||
      importJob.Status == JobStatus.Cancelled)
  {
    // Job has finished executing
    break;
  }

  await Task.Delay(TimeSpan.FromSeconds(5));
}

Mendapatkan kontainer SAS URI

Sampel kode berikut menunjukkan kepada Anda cara membuat SAS URI dengan izin baca, tulis, dan hapus untuk kontainer blob:

static string GetContainerSasUri(CloudBlobContainer container)
{
  // Set the expiry time and permissions for the container.
  // In this case no start time is specified, so the
  // shared access signature becomes valid immediately.
  var sasConstraints = new SharedAccessBlobPolicy();
  sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24);
  sasConstraints.Permissions = 
    SharedAccessBlobPermissions.Write | 
    SharedAccessBlobPermissions.Read | 
    SharedAccessBlobPermissions.Delete;

  // Generate the shared access signature on the container,
  // setting the constraints directly on the signature.
  string sasContainerToken = container.GetSharedAccessSignature(sasConstraints);

  // Return the URI string for the container,
  // including the SAS token.
  return container.Uri + sasContainerToken;
}

Langkah berikutnya

Dalam artikel ini, Anda belajar cara melakukan operasi massal terhadap registri identitas di hub IoT. Banyak dari operasi ini, termasuk cara memindahkan perangkat dari satu hub ke hub lainnya, digunakan di Mengelola perangkat yang terdaftar ke bagian hub IoT tentang Cara Mengkloning IoT Hub.

Artikel kloning memiliki sampel kerja yang terkait dengannya, yang terletak di sampel IoT C# di halaman ini: Sampel Azure IoT untuk C #, dengan proyek adalah ImportExportDevicesSample. Anda dapat mengunduh sampel dan mencobanya; ada instruksi di artikel Cara Mengkloning IoT Hub.

Untuk mempelajari selengkapnya tentang mengelola Azure IoT Hub, cek artikel berikut ini:

Untuk mempelajari lebih lanjut kemampuan IoT Hub, lihat:

Untuk menjelajahi penggunaan IoT Hub Device Provisioning Service untuk mengaktifkan ketentuan tepat waktu tanpa sentuhan, lihat: