Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(service): add support for DeviceScope to import/export job #2040

Merged
merged 1 commit into from
Jun 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions e2e/test/iothub/service/RegistryManagerExportDevicesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public async Task RegistryManager_ExportDevices(StorageAuthenticationType storag
// arrange

StorageContainer storageContainer = null;
string edgeId = $"{nameof(RegistryManager_ExportDevices)}-Edge-{StorageContainer.GetRandomSuffix(4)}";
drwill-ms marked this conversation as resolved.
Show resolved Hide resolved
string deviceId = $"{nameof(RegistryManager_ExportDevices)}-{StorageContainer.GetRandomSuffix(4)}";
var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);

Expand All @@ -71,11 +72,21 @@ public async Task RegistryManager_ExportDevices(StorageAuthenticationType storag
? storageContainer.SasUri
: storageContainer.Uri;

var edge = await registryManager
.AddDeviceAsync(
new Device(edgeId)
{
Authentication = new AuthenticationMechanism { Type = AuthenticationType.Sas },
Capabilities = new Shared.DeviceCapabilities { IotEdge = true },
})
.ConfigureAwait(false);

await registryManager
.AddDeviceAsync(
new Device(deviceId)
{
Authentication = new AuthenticationMechanism { Type = AuthenticationType.Sas },
Scope = edge.Scope,
})
.ConfigureAwait(false);

Expand Down Expand Up @@ -151,6 +162,7 @@ await registryManager
{
Logger.Trace($"Found device in export as [{serializedDeivce}]");
foundDeviceInExport = true;
device.DeviceScope.Should().Be(edge.Scope);
break;
}
}
Expand All @@ -163,6 +175,7 @@ await registryManager
storageContainer?.Dispose();

await registryManager.RemoveDeviceAsync(deviceId).ConfigureAwait(false);
await registryManager.RemoveDeviceAsync(edgeId).ConfigureAwait(false);
}
catch { }
}
Expand Down
2 changes: 1 addition & 1 deletion iothub/service/src/Device.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public Device(string id)
/// relationship.
/// </summary>
/// <remarks>
/// For leaf devices, the value to set a parent edge device can be retrieved from the parent edge device's <see cref="Scope"/> property.
drwill-ms marked this conversation as resolved.
Show resolved Hide resolved
/// For leaf devices, the value to set a parent edge device can be retrieved from the parent edge device's Scope property.
///
/// For more information, see <see href="https://docs.microsoft.com/azure/iot-edge/iot-edge-as-gateway?view=iotedge-2020-11#parent-and-child-relationships"/>.
/// </remarks>
Expand Down
39 changes: 26 additions & 13 deletions iothub/service/src/ExportImportDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
// ---------------------------------------------------------------

using System;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Azure.Devices.Shared;
using Newtonsoft.Json;

namespace Microsoft.Azure.Devices
{
/// <summary>
/// Contains device properties specified during export/import operation
/// Contains device properties specified during export/import job operation.
/// </summary>
public sealed class ExportImportDevice
{
Expand All @@ -21,7 +22,7 @@ public sealed class ExportImportDevice
/// <summary>
/// Property container
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1034:Nested types should not be visible", Justification = "Public property. No behavior changes allowed.")]
[SuppressMessage("Design", "CA1034:Nested types should not be visible", Justification = "Public property. No behavior changes allowed.")]
public sealed class PropertyContainer
{
/// <summary>
Expand All @@ -38,14 +39,14 @@ public sealed class PropertyContainer
}

/// <summary>
/// Create an ExportImportDevice <see cref="ExportImportDevice" />
/// Create an ExportImportDevice.
/// </summary>
public ExportImportDevice()
{
}

/// <summary>
/// Create an ExportImportDevice <see cref="ExportImportDevice" />
/// Create an ExportImportDevice.
/// </summary>
/// <param name="device">Device properties</param>
/// <param name="importmode">Identifies the behavior when merging a device to the registry during import actions.</param>
Expand All @@ -66,13 +67,13 @@ public ExportImportDevice(Device device, ImportMode importmode)
}

/// <summary>
/// Id of the device
/// Id of the device.
/// </summary>
[JsonProperty(PropertyName = "id", Required = Required.Always)]
public string Id { get; set; }

/// <summary>
/// Module Id for the object
/// Module Id for the object.
/// </summary>
[JsonProperty(PropertyName = "moduleId", NullValueHandling = NullValueHandling.Ignore)]
public string ModuleId { get; set; }
Expand All @@ -88,31 +89,31 @@ public string ETag
}

/// <summary>
/// ImportMode of the device
/// Import mode of the device.
/// </summary>
[JsonProperty(PropertyName = "importMode", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public ImportMode ImportMode { get; set; }

/// <summary>
/// Status of the device
/// Status of the device.
/// </summary>
[JsonProperty(PropertyName = "status", Required = Required.Always)]
public DeviceStatus Status { get; set; }

/// <summary>
/// StatusReason of the device
/// Status reason of the device.
/// </summary>
[JsonProperty(PropertyName = "statusReason", NullValueHandling = NullValueHandling.Ignore)]
public string StatusReason { get; set; }

/// <summary>
/// AuthenticationMechanism of the device
/// Authentication mechanism of the device.
/// </summary>
[JsonProperty(PropertyName = "authentication")]
public AuthenticationMechanism Authentication { get; set; }

/// <summary>
/// string representing a Twin ETag for the entity, as per RFC7232.
/// String representing a Twin ETag for the entity, as per RFC7232.
/// </summary>
[JsonProperty(PropertyName = "twinETag", NullValueHandling = NullValueHandling.Ignore)]
public string TwinETag
Expand All @@ -128,17 +129,29 @@ public string TwinETag
public TwinCollection Tags { get; set; }

/// <summary>
/// Desired and Reported property bags
/// Desired and reported property bags
/// </summary>
[JsonProperty(PropertyName = "properties", NullValueHandling = NullValueHandling.Ignore)]
public PropertyContainer Properties { get; set; }

/// <summary>
/// Status of Capabilities enabled on the device
/// Status of capabilities enabled on the device
/// </summary>
[JsonProperty(PropertyName = "capabilities", NullValueHandling = NullValueHandling.Ignore)]
public DeviceCapabilities Capabilities { get; set; }

/// <summary>
/// The scope of the device. For edge devices, this is auto-generated and immutable. For leaf devices, set this to create child/parent
/// relationship.
/// </summary>
/// <remarks>
/// For leaf devices, the value to set a parent edge device can be retrieved from the parent edge device's device scope property.
///
/// For more information, see <see href="https://docs.microsoft.com/azure/iot-edge/iot-edge-as-gateway?view=iotedge-2020-11#parent-and-child-relationships"/>.
/// </remarks>
[JsonProperty(PropertyName = "deviceScope", NullValueHandling = NullValueHandling.Include)]
public string DeviceScope { get; set; }
drwill-ms marked this conversation as resolved.
Show resolved Hide resolved

private static string SanitizeETag(string eTag)
{
if (!string.IsNullOrWhiteSpace(eTag))
Expand Down