diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 32f03d8e6a..981ce363a2 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -31,6 +31,8 @@ Please follow the instructions and template below to save us time requesting add Below is a generic bug report format. We recommend you use it as a template and replace the information below each header with your own. +Note that bugs that only affect unsupported platforms will likely be treated as feature requests, and may be closed as "won't fix" if we have no plans to support that platform. See [this document](../../supported_platforms.md) for details on which platforms are officially supported. + ------------------------------- delete above ------------------------------- diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index ba999c8c9c..cfc496eb27 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -26,6 +26,8 @@ Thank you for raising a feature request! To get started, here's a few things to As an open source project, we welcome PRs for new features, and we don't want to reject any hard work you've done to contribute. **So propose your solution through an issue first** so we can discuss the changes, and if things look good we will ask you submit a PR to implement the changes. +Note that feature requests that only affect unsupported platforms may be closed as "won't fix" if we have no plans to support that platform. See [this document](../../supported_platforms.md) for details on which platforms are officially supported. + ------------------------------- delete above ------------------------------- **Is your feature request related to a problem? Please describe.** diff --git a/.github/workflows/github_issues.yml b/.github/workflows/github_issues.yml index e64c1ca8b2..8b65bd7d7f 100644 --- a/.github/workflows/github_issues.yml +++ b/.github/workflows/github_issues.yml @@ -12,7 +12,6 @@ jobs: - uses: danhellem/github-actions-issue-to-work-item@master env: ado_token: "${{ secrets.ADO_PERSONAL_ACCESS_TOKEN }}" - github_token: "${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}" ado_organization: "${{ secrets.ADO_ORGANIZATION }}" ado_project: "${{ secrets.ADO_PROJECT }}" ado_area_path: "${{ secrets.ADO_AREA_PATH }}" diff --git a/common/src/service/CommonConstants.cs b/common/src/service/CommonConstants.cs index c31d2d8473..35de847097 100644 --- a/common/src/service/CommonConstants.cs +++ b/common/src/service/CommonConstants.cs @@ -130,6 +130,8 @@ internal static class CommonConstants public const string HttpErrorCodeName = "iothub-errorcode"; + public static readonly string[] IotHubAadTokenScopes = new string[] { "https://iothubs.azure.net/.default" }; + //Service Analytics related public static class ServiceAnalytics { diff --git a/e2e/test/Helpers/StorageContainer.cs b/e2e/test/Helpers/StorageContainer.cs index 94bb4cfcfe..ac450b81cc 100644 --- a/e2e/test/Helpers/StorageContainer.cs +++ b/e2e/test/Helpers/StorageContainer.cs @@ -136,7 +136,7 @@ protected virtual void Dispose(bool disposing) private async Task InitializeAsync() { - CloudStorageAccount storageAccount = CloudStorageAccount.Parse(Configuration.Storage.ConnectionString); + CloudStorageAccount storageAccount = CloudStorageAccount.Parse(TestConfiguration.Storage.ConnectionString); CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient(); CloudBlobContainer = cloudBlobClient.GetContainerReference(ContainerName); await CloudBlobContainer.CreateIfNotExistsAsync().ConfigureAwait(false); diff --git a/e2e/test/Helpers/TestDevice.cs b/e2e/test/Helpers/TestDevice.cs index 0f78f7c292..215100d669 100644 --- a/e2e/test/Helpers/TestDevice.cs +++ b/e2e/test/Helpers/TestDevice.cs @@ -72,7 +72,7 @@ private static async Task CreateDeviceAsync(TestDeviceType type, str string deviceName = "E2E_" + prefix + Guid.NewGuid(); // Delete existing devices named this way and create a new one. - using var rm = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var rm = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); s_logger.Trace($"{nameof(GetTestDeviceAsync)}: Creating device {deviceName} with type {type}."); Client.IAuthenticationMethod auth = null; @@ -84,11 +84,11 @@ private static async Task CreateDeviceAsync(TestDeviceType type, str { X509Thumbprint = new X509Thumbprint { - PrimaryThumbprint = Configuration.IoTHub.GetCertificateWithPrivateKey().Thumbprint + PrimaryThumbprint = TestConfiguration.IoTHub.GetCertificateWithPrivateKey().Thumbprint } }; - auth = new DeviceAuthenticationWithX509Certificate(deviceName, Configuration.IoTHub.GetCertificateWithPrivateKey()); + auth = new DeviceAuthenticationWithX509Certificate(deviceName, TestConfiguration.IoTHub.GetCertificateWithPrivateKey()); } Device device = null; @@ -118,7 +118,7 @@ public string ConnectionString { get { - string iotHubHostName = GetHostName(Configuration.IoTHub.ConnectionString); + string iotHubHostName = GetHostName(TestConfiguration.IoTHub.ConnectionString); return $"HostName={iotHubHostName};DeviceId={Device.Id};SharedAccessKey={Device.Authentication.SymmetricKey.PrimaryKey}"; } } @@ -126,7 +126,7 @@ public string ConnectionString /// /// Used in conjunction with DeviceClient.Create() /// - public string IoTHubHostName => GetHostName(Configuration.IoTHub.ConnectionString); + public string IoTHubHostName => GetHostName(TestConfiguration.IoTHub.ConnectionString); /// /// Device Id @@ -171,7 +171,7 @@ public DeviceClient CreateDeviceClient(ITransportSettings[] transportSettings, C } else { - deviceClient = DeviceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString, Device.Id, transportSettings, options); + deviceClient = DeviceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString, Device.Id, transportSettings, options); s_logger.Trace($"{nameof(CreateDeviceClient)}: Created {nameof(DeviceClient)} {Device.Id} from IoTHub connection string: ID={TestLogger.IdOf(deviceClient)}"); } } @@ -186,7 +186,7 @@ public DeviceClient CreateDeviceClient(ITransportSettings[] transportSettings, C public async Task RemoveDeviceAsync() { - using var rm = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var rm = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); await rm.RemoveDeviceAsync(Id).ConfigureAwait(false); } } diff --git a/e2e/test/Helpers/TestModule.cs b/e2e/test/Helpers/TestModule.cs index 72a0caaa2f..42f8c36ee9 100644 --- a/e2e/test/Helpers/TestModule.cs +++ b/e2e/test/Helpers/TestModule.cs @@ -28,7 +28,7 @@ public static async Task GetTestModuleAsync(string deviceNamePrefix, string deviceName = testDevice.Id; string moduleName = "E2E_" + moduleNamePrefix + Guid.NewGuid(); - using var rm = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var rm = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); logger.Trace($"{nameof(GetTestModuleAsync)}: Creating module for device {deviceName}."); var requestModule = new Module(deviceName, moduleName); @@ -49,7 +49,7 @@ public string ConnectionString { get { - string iotHubHostName = GetHostName(Configuration.IoTHub.ConnectionString); + string iotHubHostName = GetHostName(TestConfiguration.IoTHub.ConnectionString); return $"HostName={iotHubHostName};DeviceId={_module.DeviceId};ModuleId={_module.Id};SharedAccessKey={_module.Authentication.SymmetricKey.PrimaryKey}"; } } diff --git a/e2e/test/config/Configuration.AzureSecurityCenterForIoTLogAnalytics.cs b/e2e/test/config/TestConfiguration.AzureSecurityCenterForIoTLogAnalytics.cs similarity index 94% rename from e2e/test/config/Configuration.AzureSecurityCenterForIoTLogAnalytics.cs rename to e2e/test/config/TestConfiguration.AzureSecurityCenterForIoTLogAnalytics.cs index 43b6bb67ae..6f4b93b100 100644 --- a/e2e/test/config/Configuration.AzureSecurityCenterForIoTLogAnalytics.cs +++ b/e2e/test/config/TestConfiguration.AzureSecurityCenterForIoTLogAnalytics.cs @@ -3,7 +3,7 @@ namespace Microsoft.Azure.Devices.E2ETests { - public static partial class Configuration + public static partial class TestConfiguration { public static class AzureSecurityCenterForIoTLogAnalytics { diff --git a/e2e/test/config/Configuration.IoTHub.cs b/e2e/test/config/TestConfiguration.IoTHub.cs similarity index 99% rename from e2e/test/config/Configuration.IoTHub.cs rename to e2e/test/config/TestConfiguration.IoTHub.cs index 88565486c4..768bb1eb97 100644 --- a/e2e/test/config/Configuration.IoTHub.cs +++ b/e2e/test/config/TestConfiguration.IoTHub.cs @@ -19,7 +19,7 @@ namespace Microsoft.Azure.Devices.E2ETests { - public static partial class Configuration + public static partial class TestConfiguration { public static partial class IoTHub { diff --git a/e2e/test/config/Configuration.Provisioning.cs b/e2e/test/config/TestConfiguration.Provisioning.cs similarity index 97% rename from e2e/test/config/Configuration.Provisioning.cs rename to e2e/test/config/TestConfiguration.Provisioning.cs index fc0f036d46..a65f27e557 100644 --- a/e2e/test/config/Configuration.Provisioning.cs +++ b/e2e/test/config/TestConfiguration.Provisioning.cs @@ -6,7 +6,7 @@ namespace Microsoft.Azure.Devices.E2ETests { - public static partial class Configuration + public static partial class TestConfiguration { public static partial class Provisioning { diff --git a/e2e/test/config/Configuration.Storage.cs b/e2e/test/config/TestConfiguration.Storage.cs similarity index 85% rename from e2e/test/config/Configuration.Storage.cs rename to e2e/test/config/TestConfiguration.Storage.cs index b633840691..7d9b4a9f17 100644 --- a/e2e/test/config/Configuration.Storage.cs +++ b/e2e/test/config/TestConfiguration.Storage.cs @@ -4,7 +4,7 @@ namespace Microsoft.Azure.Devices.E2ETests { - public static partial class Configuration + public static partial class TestConfiguration { public static class Storage { @@ -17,7 +17,7 @@ public static class Storage static Storage() { - ConnectionString = Configuration.GetValue("STORAGE_ACCOUNT_CONNECTION_STRING"); + ConnectionString = TestConfiguration.GetValue("STORAGE_ACCOUNT_CONNECTION_STRING"); Name = s_saName.Match(ConnectionString).Value; Key = s_saKey.Match(ConnectionString).Value; } diff --git a/e2e/test/config/Configuration.cs b/e2e/test/config/TestConfiguration.cs similarity index 98% rename from e2e/test/config/Configuration.cs rename to e2e/test/config/TestConfiguration.cs index cf8ed2db34..3f7cb89e21 100644 --- a/e2e/test/config/Configuration.cs +++ b/e2e/test/config/TestConfiguration.cs @@ -6,7 +6,7 @@ namespace Microsoft.Azure.Devices.E2ETests { - public static partial class Configuration + public static partial class TestConfiguration { private static string GetValue(string envName, string defaultValue = null) { diff --git a/e2e/test/iothub/CombinedClientOperationsPoolAmqpTests.cs b/e2e/test/iothub/CombinedClientOperationsPoolAmqpTests.cs index 8fea36bb4b..2e20e6038f 100644 --- a/e2e/test/iothub/CombinedClientOperationsPoolAmqpTests.cs +++ b/e2e/test/iothub/CombinedClientOperationsPoolAmqpTests.cs @@ -122,7 +122,7 @@ private async Task DeviceCombinedClientOperationsAsync( ConnectionStringAuthScope authScope = ConnectionStringAuthScope.Device) { // Initialize service client for service-side operations - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); // Message payload and properties for C2D operation var messagesSent = new Dictionary>(); diff --git a/e2e/test/iothub/ConnectionStatusChangeHandlerTests.cs b/e2e/test/iothub/ConnectionStatusChangeHandlerTests.cs index f7e83f8a9e..63e894cb6f 100644 --- a/e2e/test/iothub/ConnectionStatusChangeHandlerTests.cs +++ b/e2e/test/iothub/ConnectionStatusChangeHandlerTests.cs @@ -109,7 +109,7 @@ private async Task DeviceClient_Gives_ConnectionStatus_DeviceDisabled_Base( TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix + $"_{Guid.NewGuid()}").ConfigureAwait(false); string deviceConnectionString = testDevice.ConnectionString; - var config = new Configuration.IoTHub.ConnectionStringParser(deviceConnectionString); + var config = new TestConfiguration.IoTHub.ConnectionStringParser(deviceConnectionString); string deviceId = config.DeviceID; ConnectionStatus? status = null; @@ -139,7 +139,7 @@ private async Task DeviceClient_Gives_ConnectionStatus_DeviceDisabled_Base( Assert.IsNotNull(twin); // Delete/disable the device in IoT Hub. This should trigger the ConnectionStatusChangesHandler. - using (RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString)) + using (RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString)) { await registryManagerOperation(registryManager, deviceId).ConfigureAwait(false); } @@ -198,7 +198,7 @@ private async Task ModuleClient_Gives_ConnectionStatus_DeviceDisabled_Base( Assert.IsNotNull(twin); // Delete/disable the device in IoT Hub. - using (RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString)) + using (RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString)) { await registryManagerOperation(registryManager, testModule.DeviceId).ConfigureAwait(false); } diff --git a/e2e/test/iothub/DeviceClientX509AuthenticationE2ETests.cs b/e2e/test/iothub/DeviceClientX509AuthenticationE2ETests.cs index 96c04852bf..2698350976 100644 --- a/e2e/test/iothub/DeviceClientX509AuthenticationE2ETests.cs +++ b/e2e/test/iothub/DeviceClientX509AuthenticationE2ETests.cs @@ -28,7 +28,7 @@ public class DeviceClientX509AuthenticationE2ETests : E2EMsTestBase public DeviceClientX509AuthenticationE2ETests() { - _hostName = GetHostName(Configuration.IoTHub.ConnectionString); + _hostName = GetHostName(TestConfiguration.IoTHub.ConnectionString); } [LoggedTestMethod] @@ -148,12 +148,12 @@ public async Task X509_Cert_Chain_Install_Test_MQTT_TCP() { // arrange var chainCerts = new X509Certificate2Collection(); - chainCerts.Add(Configuration.IoTHub.GetRootCACertificate()); - chainCerts.Add(Configuration.IoTHub.GetIntermediate1Certificate()); - chainCerts.Add(Configuration.IoTHub.GetIntermediate2Certificate()); + chainCerts.Add(TestConfiguration.IoTHub.GetRootCACertificate()); + chainCerts.Add(TestConfiguration.IoTHub.GetIntermediate1Certificate()); + chainCerts.Add(TestConfiguration.IoTHub.GetIntermediate2Certificate()); var auth = new DeviceAuthenticationWithX509Certificate( - Configuration.IoTHub.X509ChainDeviceName, - Configuration.IoTHub.GetChainDeviceCertificateWithPrivateKey(), + TestConfiguration.IoTHub.X509ChainDeviceName, + TestConfiguration.IoTHub.GetChainDeviceCertificateWithPrivateKey(), chainCerts); using var deviceClient = DeviceClient.Create( _hostName, @@ -173,12 +173,12 @@ public async Task X509_Cert_Chain_Install_Test_AMQP_TCP() { // arrange var chainCerts = new X509Certificate2Collection(); - chainCerts.Add(Configuration.IoTHub.GetRootCACertificate()); - chainCerts.Add(Configuration.IoTHub.GetIntermediate1Certificate()); - chainCerts.Add(Configuration.IoTHub.GetIntermediate2Certificate()); + chainCerts.Add(TestConfiguration.IoTHub.GetRootCACertificate()); + chainCerts.Add(TestConfiguration.IoTHub.GetIntermediate1Certificate()); + chainCerts.Add(TestConfiguration.IoTHub.GetIntermediate2Certificate()); var auth = new DeviceAuthenticationWithX509Certificate( - Configuration.IoTHub.X509ChainDeviceName, - Configuration.IoTHub.GetChainDeviceCertificateWithPrivateKey(), + TestConfiguration.IoTHub.X509ChainDeviceName, + TestConfiguration.IoTHub.GetChainDeviceCertificateWithPrivateKey(), chainCerts); using var deviceClient = DeviceClient.Create( _hostName, @@ -293,7 +293,7 @@ private async Task X509InvalidDeviceIdOpenAsyncTwiceTest(Client.TransportType tr private DeviceClient CreateDeviceClientWithInvalidId(Client.TransportType transportType) { string deviceName = $"DEVICE_NOT_EXIST_{Guid.NewGuid()}"; - var auth = new DeviceAuthenticationWithX509Certificate(deviceName, Configuration.IoTHub.GetCertificateWithPrivateKey()); + var auth = new DeviceAuthenticationWithX509Certificate(deviceName, TestConfiguration.IoTHub.GetCertificateWithPrivateKey()); return DeviceClient.Create(_hostName, auth, transportType); } } diff --git a/e2e/test/iothub/DeviceTokenRefreshE2ETests.cs b/e2e/test/iothub/DeviceTokenRefreshE2ETests.cs index f98db132d4..516d8ed6d9 100644 --- a/e2e/test/iothub/DeviceTokenRefreshE2ETests.cs +++ b/e2e/test/iothub/DeviceTokenRefreshE2ETests.cs @@ -30,7 +30,7 @@ public async Task DeviceClient_Not_Exist_AMQP() { TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); - var config = new Configuration.IoTHub.ConnectionStringParser(testDevice.ConnectionString); + var config = new TestConfiguration.IoTHub.ConnectionStringParser(testDevice.ConnectionString); using (DeviceClient deviceClient = DeviceClient.CreateFromConnectionString($"HostName={config.IotHubHostName};DeviceId=device_id_not_exist;SharedAccessKey={config.SharedAccessKey}", Client.TransportType.Amqp_Tcp_Only)) { await deviceClient.OpenAsync().ConfigureAwait(false); @@ -43,7 +43,7 @@ public async Task DeviceClient_Bad_Credentials_AMQP() { TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); - var config = new Configuration.IoTHub.ConnectionStringParser(testDevice.ConnectionString); + var config = new TestConfiguration.IoTHub.ConnectionStringParser(testDevice.ConnectionString); string invalidKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("invalid_key")); using (DeviceClient deviceClient = DeviceClient.CreateFromConnectionString($"HostName={config.IotHubHostName};DeviceId={config.DeviceID};SharedAccessKey={invalidKey}", Client.TransportType.Amqp_Tcp_Only)) { @@ -82,7 +82,7 @@ public async Task DeviceClient_TokenConnectionDoubleRelease_Ok() string deviceConnectionString = testDevice.ConnectionString; - var config = new Configuration.IoTHub.ConnectionStringParser(deviceConnectionString); + var config = new TestConfiguration.IoTHub.ConnectionStringParser(deviceConnectionString); string iotHub = config.IotHubHostName; string deviceId = config.DeviceID; string key = config.SharedAccessKey; diff --git a/e2e/test/iothub/FaultInjectionPoolAmqpTests.cs b/e2e/test/iothub/FaultInjectionPoolAmqpTests.cs index e02914dda0..2f0d65dff5 100644 --- a/e2e/test/iothub/FaultInjectionPoolAmqpTests.cs +++ b/e2e/test/iothub/FaultInjectionPoolAmqpTests.cs @@ -13,6 +13,6 @@ namespace Microsoft.Azure.Devices.E2ETests [TestCategory("LongRunning")] public partial class FaultInjectionPoolAmqpTests : E2EMsTestBase { - private static readonly string s_proxyServerAddress = Configuration.IoTHub.ProxyServerAddress; + private static readonly string s_proxyServerAddress = TestConfiguration.IoTHub.ProxyServerAddress; } } diff --git a/e2e/test/iothub/FileUploadE2ETests.cs b/e2e/test/iothub/FileUploadE2ETests.cs index 4282440676..3a0309a525 100644 --- a/e2e/test/iothub/FileUploadE2ETests.cs +++ b/e2e/test/iothub/FileUploadE2ETests.cs @@ -103,7 +103,7 @@ public async Task FileUpload_SmallFile_Http_GranularSteps_Proxy() using var fileStreamSource = new FileStream(filename, FileMode.Open, FileAccess.Read); var fileUploadTransportSettings = new Http1TransportSettings() { - Proxy = new WebProxy(Configuration.IoTHub.ProxyServerAddress) + Proxy = new WebProxy(TestConfiguration.IoTHub.ProxyServerAddress) }; await UploadFileGranularAsync(fileStreamSource, filename, fileUploadTransportSettings).ConfigureAwait(false); @@ -124,11 +124,10 @@ private async Task UploadFileGranularAsync(Stream source, string filename, Http1 if (x509auth) { - X509Certificate2 cert = Configuration.IoTHub.GetCertificateWithPrivateKey(); + X509Certificate2 cert = TestConfiguration.IoTHub.GetCertificateWithPrivateKey(); var auth = new DeviceAuthenticationWithX509Certificate(testDevice.Id, cert); - - deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, auth, Client.TransportType.Http1, clientOptions); + deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, auth, Client.TransportType.Http1); } else { @@ -166,7 +165,7 @@ private async Task UploadFileAsync(Client.TransportType transport, string filena DeviceClient deviceClient; if (x509auth) { - X509Certificate2 cert = Configuration.IoTHub.GetCertificateWithPrivateKey(); + X509Certificate2 cert = TestConfiguration.IoTHub.GetCertificateWithPrivateKey(); var auth = new DeviceAuthenticationWithX509Certificate(testDevice.Id, cert); deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, auth, transport); @@ -198,7 +197,7 @@ private async Task GetSasUriAsync(Client.TransportType transport, string blobNam DeviceClient deviceClient; if (x509auth) { - X509Certificate2 cert = Configuration.IoTHub.GetCertificateWithPrivateKey(); + X509Certificate2 cert = TestConfiguration.IoTHub.GetCertificateWithPrivateKey(); var auth = new DeviceAuthenticationWithX509Certificate(testDevice.Id, cert); deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, auth, transport); diff --git a/e2e/test/iothub/SasCredentialAuthenticationTests.cs b/e2e/test/iothub/SasCredentialAuthenticationTests.cs index 09881b57bb..827f05ec2b 100644 --- a/e2e/test/iothub/SasCredentialAuthenticationTests.cs +++ b/e2e/test/iothub/SasCredentialAuthenticationTests.cs @@ -39,9 +39,9 @@ public class SasCredentialAuthenticationTests : E2EMsTestBase public async Task RegistryManager_Http_SasCredentialAuth_Success() { // arrange - string signature = Configuration.IoTHub.GetIotHubSharedAccessSignature(TimeSpan.FromHours(1)); + string signature = TestConfiguration.IoTHub.GetIotHubSharedAccessSignature(TimeSpan.FromHours(1)); using var registryManager = RegistryManager.Create( - Configuration.IoTHub.GetIotHubHostName(), + TestConfiguration.IoTHub.GetIotHubHostName(), new AzureSasCredential(signature)); var device = new Device(Guid.NewGuid().ToString()); @@ -60,10 +60,10 @@ public async Task RegistryManager_Http_SasCredentialAuth_Success() public async Task RegistryManager_Http_SasCredentialAuth_Renewed_Success() { // arrange - string signature = Configuration.IoTHub.GetIotHubSharedAccessSignature(TimeSpan.FromHours(-1)); + string signature = TestConfiguration.IoTHub.GetIotHubSharedAccessSignature(TimeSpan.FromHours(-1)); var sasCredential = new AzureSasCredential(signature); using var registryManager = RegistryManager.Create( - Configuration.IoTHub.GetIotHubHostName(), + TestConfiguration.IoTHub.GetIotHubHostName(), sasCredential); var device = new Device(Guid.NewGuid().ToString()); @@ -78,7 +78,7 @@ public async Task RegistryManager_Http_SasCredentialAuth_Renewed_Success() { // Expected to be unauthorized exception. } - signature = Configuration.IoTHub.GetIotHubSharedAccessSignature(TimeSpan.FromHours(1)); + signature = TestConfiguration.IoTHub.GetIotHubSharedAccessSignature(TimeSpan.FromHours(1)); sasCredential.Update(signature); Device createdDevice = await registryManager.AddDeviceAsync(device).ConfigureAwait(false); @@ -93,9 +93,9 @@ public async Task RegistryManager_Http_SasCredentialAuth_Renewed_Success() public async Task JobClient_Http_SasCredentialAuth_Success() { // arrange - string signature = Configuration.IoTHub.GetIotHubSharedAccessSignature(TimeSpan.FromHours(1)); + string signature = TestConfiguration.IoTHub.GetIotHubSharedAccessSignature(TimeSpan.FromHours(1)); using var jobClient = JobClient.Create( - Configuration.IoTHub.GetIotHubHostName(), + TestConfiguration.IoTHub.GetIotHubHostName(), new AzureSasCredential(signature)); string jobId = "JOBSAMPLE" + Guid.NewGuid().ToString(); @@ -138,9 +138,9 @@ public async Task DigitalTwinClient_Http_SasCredentialAuth_Success() // Call openAsync() to open the device's connection, so that the ModelId is sent over Mqtt CONNECT packet. await deviceClient.OpenAsync().ConfigureAwait(false); - string signature = Configuration.IoTHub.GetIotHubSharedAccessSignature(TimeSpan.FromHours(1)); + string signature = TestConfiguration.IoTHub.GetIotHubSharedAccessSignature(TimeSpan.FromHours(1)); using var digitalTwinClient = DigitalTwinClient.Create( - Configuration.IoTHub.GetIotHubHostName(), + TestConfiguration.IoTHub.GetIotHubHostName(), new AzureSasCredential(signature)); // act @@ -164,9 +164,9 @@ public async Task Service_Amqp_SasCredentialAuth_Success() using DeviceClient deviceClient = testDevice.CreateDeviceClient(Client.TransportType.Mqtt); await deviceClient.OpenAsync().ConfigureAwait(false); - string signature = Configuration.IoTHub.GetIotHubSharedAccessSignature(TimeSpan.FromHours(1)); + string signature = TestConfiguration.IoTHub.GetIotHubSharedAccessSignature(TimeSpan.FromHours(1)); using var serviceClient = ServiceClient.Create( - Configuration.IoTHub.GetIotHubHostName(), + TestConfiguration.IoTHub.GetIotHubHostName(), new AzureSasCredential(signature), TransportType.Amqp); @@ -188,10 +188,10 @@ public async Task Service_Amqp_SasCredentialAuth_Renewed_Success() using DeviceClient deviceClient = testDevice.CreateDeviceClient(Client.TransportType.Mqtt); await deviceClient.OpenAsync().ConfigureAwait(false); - string signature = Configuration.IoTHub.GetIotHubSharedAccessSignature(TimeSpan.FromHours(-1)); + string signature = TestConfiguration.IoTHub.GetIotHubSharedAccessSignature(TimeSpan.FromHours(-1)); var sasCredential = new AzureSasCredential(signature); using var serviceClient = ServiceClient.Create( - Configuration.IoTHub.GetIotHubHostName(), + TestConfiguration.IoTHub.GetIotHubHostName(), sasCredential, TransportType.Amqp); @@ -206,7 +206,7 @@ public async Task Service_Amqp_SasCredentialAuth_Renewed_Success() // Expected to get an unauthorized exception. } - signature = Configuration.IoTHub.GetIotHubSharedAccessSignature(TimeSpan.FromHours(1)); + signature = TestConfiguration.IoTHub.GetIotHubSharedAccessSignature(TimeSpan.FromHours(1)); sasCredential.Update(signature); await serviceClient.OpenAsync().ConfigureAwait(false); using var message = new Message(Encoding.ASCII.GetBytes("Hello, Cloud!")); diff --git a/e2e/test/iothub/TokenCredentialAuthenticationTests.cs b/e2e/test/iothub/TokenCredentialAuthenticationTests.cs index 22d4448106..cbbcc0633c 100644 --- a/e2e/test/iothub/TokenCredentialAuthenticationTests.cs +++ b/e2e/test/iothub/TokenCredentialAuthenticationTests.cs @@ -40,8 +40,8 @@ public async Task RegistryManager_Http_TokenCredentialAuth_Success() { // arrange using var registryManager = RegistryManager.Create( - Configuration.IoTHub.GetIotHubHostName(), - Configuration.IoTHub.GetClientSecretCredential()); + TestConfiguration.IoTHub.GetIotHubHostName(), + TestConfiguration.IoTHub.GetClientSecretCredential()); var device = new Device(Guid.NewGuid().ToString()); @@ -60,8 +60,8 @@ public async Task JobClient_Http_TokenCredentialAuth_Success() { // arrange using var jobClient = JobClient.Create( - Configuration.IoTHub.GetIotHubHostName(), - Configuration.IoTHub.GetClientSecretCredential()); + TestConfiguration.IoTHub.GetIotHubHostName(), + TestConfiguration.IoTHub.GetClientSecretCredential()); string jobId = "JOBSAMPLE" + Guid.NewGuid().ToString(); string jobDeviceId = "JobsSample_Device"; @@ -104,8 +104,8 @@ public async Task DigitalTwinClient_Http_TokenCredentialAuth_Success() await deviceClient.OpenAsync().ConfigureAwait(false); using var digitalTwinClient = DigitalTwinClient.Create( - Configuration.IoTHub.GetIotHubHostName(), - Configuration.IoTHub.GetClientSecretCredential()); + TestConfiguration.IoTHub.GetIotHubHostName(), + TestConfiguration.IoTHub.GetClientSecretCredential()); // act HttpOperationResponse response = await digitalTwinClient @@ -129,8 +129,8 @@ public async Task Service_Amqp_TokenCredentialAuth_Success() await deviceClient.OpenAsync().ConfigureAwait(false); using var serviceClient = ServiceClient.Create( - Configuration.IoTHub.GetIotHubHostName(), - Configuration.IoTHub.GetClientSecretCredential(), + TestConfiguration.IoTHub.GetIotHubHostName(), + TestConfiguration.IoTHub.GetClientSecretCredential(), TransportType.Amqp); // act diff --git a/e2e/test/iothub/command/CommandE2ETests.cs b/e2e/test/iothub/command/CommandE2ETests.cs index 02bea0171d..e1f00fcc26 100644 --- a/e2e/test/iothub/command/CommandE2ETests.cs +++ b/e2e/test/iothub/command/CommandE2ETests.cs @@ -70,7 +70,7 @@ public static async Task DigitalTwinsSendCommandAndVerifyResponseAsync(string de int statusCode = 0; #if NET451 - ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); logger.Trace($"{nameof(DigitalTwinsSendCommandAndVerifyResponseAsync)}: Invoke command {commandName}."); @@ -95,7 +95,7 @@ await serviceClient.InvokeDeviceMethodAsync( serviceClient.Dispose(); #else - DigitalTwinClient digitalTwinClient = DigitalTwinClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + DigitalTwinClient digitalTwinClient = DigitalTwinClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); logger.Trace($"{nameof(DigitalTwinsSendCommandAndVerifyResponseAsync)}: Invoke command {commandName}."); diff --git a/e2e/test/iothub/messaging/AzureSecurityCenterForIoTLogAnalyticsClient.cs b/e2e/test/iothub/messaging/AzureSecurityCenterForIoTLogAnalyticsClient.cs index 05bb91e98e..32c58b13e0 100644 --- a/e2e/test/iothub/messaging/AzureSecurityCenterForIoTLogAnalyticsClient.cs +++ b/e2e/test/iothub/messaging/AzureSecurityCenterForIoTLogAnalyticsClient.cs @@ -38,10 +38,10 @@ public class AzureSecurityCenterForIoTLogAnalyticsClient : IDisposable | where DeviceId == ""{0}"" | where IoTRawEventId == ""{1}"""; - private readonly string _workspaceId = Configuration.AzureSecurityCenterForIoTLogAnalytics.WorkspacedId; - private readonly string _aadTenant = Configuration.AzureSecurityCenterForIoTLogAnalytics.AadTenant; - private readonly string _appId = Configuration.AzureSecurityCenterForIoTLogAnalytics.AadAppId; - private readonly string _appCertificate = Configuration.AzureSecurityCenterForIoTLogAnalytics.AadAppCertificate; + private readonly string _workspaceId = TestConfiguration.AzureSecurityCenterForIoTLogAnalytics.WorkspacedId; + private readonly string _aadTenant = TestConfiguration.AzureSecurityCenterForIoTLogAnalytics.AadTenant; + private readonly string _appId = TestConfiguration.AzureSecurityCenterForIoTLogAnalytics.AadAppId; + private readonly string _appCertificate = TestConfiguration.AzureSecurityCenterForIoTLogAnalytics.AadAppCertificate; private readonly TimeSpan _polingInterval = TimeSpan.FromSeconds(20); private readonly TimeSpan _timeout = TimeSpan.FromMinutes(5); diff --git a/e2e/test/iothub/messaging/FaultInjectionPoolAmqpTests.MessageReceiveFaultInjectionPoolAmqpTests.cs b/e2e/test/iothub/messaging/FaultInjectionPoolAmqpTests.MessageReceiveFaultInjectionPoolAmqpTests.cs index ebe911e96a..da01f7bc24 100644 --- a/e2e/test/iothub/messaging/FaultInjectionPoolAmqpTests.MessageReceiveFaultInjectionPoolAmqpTests.cs +++ b/e2e/test/iothub/messaging/FaultInjectionPoolAmqpTests.MessageReceiveFaultInjectionPoolAmqpTests.cs @@ -895,7 +895,7 @@ private async Task ReceiveMessageRecoveryPoolOverAmqpAsync( string proxyAddress = null) { // Initialize the service client - var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + var serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); async Task TestOperationAsync(DeviceClient deviceClient, TestDevice testDevice, TestDeviceCallbackHandler _) { @@ -955,7 +955,7 @@ private async Task ReceiveMessageUsingCallbackRecoveryPoolOverAmqpAsync( string proxyAddress = null) { // Initialize the service client - var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + var serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); async Task InitOperationAsync(DeviceClient deviceClient, TestDevice testDevice, TestDeviceCallbackHandler testDeviceCallbackHandler) { diff --git a/e2e/test/iothub/messaging/MessageFeedbackE2ETests.cs b/e2e/test/iothub/messaging/MessageFeedbackE2ETests.cs index 7968b17d46..81f867c9ef 100644 --- a/e2e/test/iothub/messaging/MessageFeedbackE2ETests.cs +++ b/e2e/test/iothub/messaging/MessageFeedbackE2ETests.cs @@ -33,7 +33,7 @@ private static async Task CompleteMessageMixOrder(TestDeviceType type, Client.Tr { TestDevice testDevice = await TestDevice.GetTestDeviceAsync(logger, s_devicePrefix, type).ConfigureAwait(false); using (DeviceClient deviceClient = testDevice.CreateDeviceClient(transport)) - using (ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString)) + using (ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString)) { await deviceClient.OpenAsync().ConfigureAwait(false); diff --git a/e2e/test/iothub/messaging/MessageReceiveE2EPoolAmqpTests.cs b/e2e/test/iothub/messaging/MessageReceiveE2EPoolAmqpTests.cs index 357c0dbbc8..3cdc8a4ece 100644 --- a/e2e/test/iothub/messaging/MessageReceiveE2EPoolAmqpTests.cs +++ b/e2e/test/iothub/messaging/MessageReceiveE2EPoolAmqpTests.cs @@ -205,7 +205,7 @@ private async Task ReceiveMessagePoolOverAmqpAsync( var messagesSent = new Dictionary>(); // Initialize the service client - var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + var serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); async Task InitOperationAsync(DeviceClient deviceClient, TestDevice testDevice, TestDeviceCallbackHandler _) { @@ -253,7 +253,7 @@ private async Task ReceiveMessageUsingCallbackPoolOverAmqpAsync( ConnectionStringAuthScope authScope = ConnectionStringAuthScope.Device) { // Initialize the service client - var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + var serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); async Task InitOperationAsync(DeviceClient deviceClient, TestDevice testDevice, TestDeviceCallbackHandler testDeviceCallbackHandler) { @@ -301,7 +301,7 @@ private async Task ReceiveMessageUsingCallbackAndUnsubscribePoolOverAmqpAsync( ConnectionStringAuthScope authScope = ConnectionStringAuthScope.Device) { // Initialize the service client - var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + var serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); async Task InitOperationAsync(DeviceClient deviceClient, TestDevice testDevice, TestDeviceCallbackHandler testDeviceCallbackHandler) { diff --git a/e2e/test/iothub/messaging/MessageReceiveE2ETests.cs b/e2e/test/iothub/messaging/MessageReceiveE2ETests.cs index b0a4516b4f..3bd205e88f 100644 --- a/e2e/test/iothub/messaging/MessageReceiveE2ETests.cs +++ b/e2e/test/iothub/messaging/MessageReceiveE2ETests.cs @@ -623,7 +623,7 @@ private async Task ReceiveSingleMessageAsync(TestDeviceType type, Client.Transpo { TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); await deviceClient.OpenAsync().ConfigureAwait(false); await serviceClient.OpenAsync().ConfigureAwait(false); @@ -667,7 +667,7 @@ private async Task ReceiveSingleMessageWithCancellationTokenAsync(TestDeviceType { TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); await deviceClient.OpenAsync().ConfigureAwait(false); await serviceClient.OpenAsync().ConfigureAwait(false); @@ -733,7 +733,7 @@ private async Task ReceiveSingleMessageUsingCallbackAsync(TestDeviceType type, C using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); using var testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger); - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); (Message msg, string payload, string p1Value) = ComposeC2dTestMessage(Logger); using (msg) @@ -760,7 +760,7 @@ private async Task ReceiveMessageUsingCallbackAndUnsubscribeAsync(TestDeviceType using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); using var testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger); - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); // For Mqtt - we will need to subscribe to the Mqtt receive telemetry topic // before the device can begin receiving c2d messages. @@ -837,7 +837,7 @@ private async Task ReceiveMessageUsingCallbackUpdateHandlerAsync(TestDeviceType TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); // Set the first C2D message handler. await deviceClient.SetReceiveMessageHandlerAsync( @@ -896,7 +896,7 @@ private async Task ReceiveMessagesSentBeforeSubscriptionAsync(TestDeviceType typ DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); var testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger); - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); (Message msg, string payload, string p1Value) = ComposeC2dTestMessage(Logger); @@ -939,7 +939,7 @@ private async Task DoNotReceiveMessagesSentBeforeSubscriptionAsync(TestDeviceTyp DeviceClient deviceClient = testDevice.CreateDeviceClient(settings); var testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger); - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); (Message msg, string payload, string p1Value) = ComposeC2dTestMessage(Logger); diff --git a/e2e/test/iothub/messaging/MessageReceiveFaultInjectionTests.cs b/e2e/test/iothub/messaging/MessageReceiveFaultInjectionTests.cs index 9b3a72bac1..cf30a99335 100644 --- a/e2e/test/iothub/messaging/MessageReceiveFaultInjectionTests.cs +++ b/e2e/test/iothub/messaging/MessageReceiveFaultInjectionTests.cs @@ -363,7 +363,7 @@ private async Task ReceiveMessageRecovery( TimeSpan delayInSec, string proxyAddress = null) { - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); async Task InitOperationAsync(DeviceClient deviceClient, TestDevice testDevice) { await serviceClient.OpenAsync().ConfigureAwait(false); @@ -418,7 +418,7 @@ private async Task ReceiveMessageWithCallbackRecoveryAsync( string proxyAddress = null) { TestDeviceCallbackHandler testDeviceCallbackHandler = null; - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); async Task InitOperationAsync(DeviceClient deviceClient, TestDevice testDevice) { diff --git a/e2e/test/iothub/messaging/MessageSendE2ETests.cs b/e2e/test/iothub/messaging/MessageSendE2ETests.cs index 6415c03e85..7cca652d71 100644 --- a/e2e/test/iothub/messaging/MessageSendE2ETests.cs +++ b/e2e/test/iothub/messaging/MessageSendE2ETests.cs @@ -20,10 +20,20 @@ namespace Microsoft.Azure.Devices.E2ETests.Messaging public partial class MessageSendE2ETests : E2EMsTestBase { private const int MessageBatchCount = 5; - private const int LargeMessageSizeInBytes = 255 * 1024; // The maximum message size for device to cloud messages is 256 KB. We are allowing 1 KB of buffer for message header information etc. - private readonly string DevicePrefix = $"{nameof(MessageSendE2ETests)}_"; - private readonly string ModulePrefix = $"{nameof(MessageSendE2ETests)}_"; - private static string ProxyServerAddress = Configuration.IoTHub.ProxyServerAddress; + + // The maximum message size for device to cloud messages is 256 KB. We are allowing 1 KB of buffer for message header information etc. + private const int LargeMessageSizeInBytes = 255 * 1024; + + // The size of a device to cloud message. This exceeds the the maximum message size set by the hub; 256 KB. + private const int ExceedAllowedMessageSizeInBytes = 300 * 1024; + + // The size of a device to cloud message. This overly exceeds the maximum message size set by the hub, which is 256 KB. The reason why we are testing for this case is because + // we noticed a different behavior between this case, and the case where the message size is less than 1 MB. + private const int OverlyExceedAllowedMessageSizeInBytes = 3000 * 1024; + + private readonly string _devicePrefix = $"{nameof(MessageSendE2ETests)}_"; + private readonly string _modulePrefix = $"{nameof(MessageSendE2ETests)}_"; + private static string s_proxyServerAddress = TestConfiguration.IoTHub.ProxyServerAddress; [LoggedTestMethod] public async Task Message_DeviceSendSingleMessage_Amqp() @@ -80,7 +90,7 @@ public async Task Message_DeviceSendSingleMessage_AmqpWs_WithHeartbeats() public async Task Message_DeviceSendSingleMessage_Http_WithProxy() { Client.Http1TransportSettings httpTransportSettings = new Client.Http1TransportSettings(); - httpTransportSettings.Proxy = new WebProxy(ProxyServerAddress); + httpTransportSettings.Proxy = new WebProxy(s_proxyServerAddress); ITransportSettings[] transportSettings = new ITransportSettings[] { httpTransportSettings }; await SendSingleMessage(TestDeviceType.Sasl, transportSettings).ConfigureAwait(false); @@ -105,7 +115,7 @@ public async Task Message_DeviceSendSingleMessage_Http_WithCustomProxy() public async Task Message_DeviceSendSingleMessage_AmqpWs_WithProxy() { Client.AmqpTransportSettings amqpTransportSettings = new Client.AmqpTransportSettings(Client.TransportType.Amqp_WebSocket_Only); - amqpTransportSettings.Proxy = new WebProxy(ProxyServerAddress); + amqpTransportSettings.Proxy = new WebProxy(s_proxyServerAddress); ITransportSettings[] transportSettings = new ITransportSettings[] { amqpTransportSettings }; await SendSingleMessage(TestDeviceType.Sasl, transportSettings).ConfigureAwait(false); @@ -117,7 +127,7 @@ public async Task Message_DeviceSendSingleMessage_MqttWs_WithProxy() { Client.Transport.Mqtt.MqttTransportSettings mqttTransportSettings = new Client.Transport.Mqtt.MqttTransportSettings(Client.TransportType.Mqtt_WebSocket_Only); - mqttTransportSettings.Proxy = new WebProxy(ProxyServerAddress); + mqttTransportSettings.Proxy = new WebProxy(s_proxyServerAddress); ITransportSettings[] transportSettings = new ITransportSettings[] { mqttTransportSettings }; await SendSingleMessage(TestDeviceType.Sasl, transportSettings).ConfigureAwait(false); @@ -128,7 +138,7 @@ public async Task Message_DeviceSendSingleMessage_MqttWs_WithProxy() public async Task Message_ModuleSendSingleMessage_AmqpWs_WithProxy() { Client.AmqpTransportSettings amqpTransportSettings = new Client.AmqpTransportSettings(Client.TransportType.Amqp_WebSocket_Only); - amqpTransportSettings.Proxy = new WebProxy(ProxyServerAddress); + amqpTransportSettings.Proxy = new WebProxy(s_proxyServerAddress); ITransportSettings[] transportSettings = new ITransportSettings[] { amqpTransportSettings }; await SendSingleMessageModule(transportSettings).ConfigureAwait(false); @@ -140,7 +150,7 @@ public async Task Message_ModuleSendSingleMessage_MqttWs_WithProxy() { Client.Transport.Mqtt.MqttTransportSettings mqttTransportSettings = new Client.Transport.Mqtt.MqttTransportSettings(Client.TransportType.Mqtt_WebSocket_Only); - mqttTransportSettings.Proxy = new WebProxy(ProxyServerAddress); + mqttTransportSettings.Proxy = new WebProxy(s_proxyServerAddress); ITransportSettings[] transportSettings = new ITransportSettings[] { mqttTransportSettings }; await SendSingleMessageModule(transportSettings).ConfigureAwait(false); @@ -212,7 +222,7 @@ public async Task X509_DeviceSendBatchMessages_Http() [ExpectedException(typeof(MessageTooLargeException))] public async Task Message_ClientThrowsForMqttTopicNameTooLong() { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); + TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(Client.TransportType.Mqtt); await deviceClient.OpenAsync().ConfigureAwait(false); @@ -245,9 +255,95 @@ public async Task Message_DeviceSendSingleLargeMessageAsync(TestDeviceType testD await SendSingleMessage(testDeviceType, transportType, messageSize).ConfigureAwait(false); } + [LoggedTestMethod] + [ExpectedException(typeof(MessageTooLargeException))] + public async Task Message_DeviceSendMessageOverAllowedSize_Amqp() + { + await SendSingleMessage(TestDeviceType.Sasl, Client.TransportType.Amqp_Tcp_Only, ExceedAllowedMessageSizeInBytes).ConfigureAwait(false); + } + + [LoggedTestMethod] + [ExpectedException(typeof(MessageTooLargeException))] + public async Task Message_DeviceSendMessageOverAllowedSize_AmqpWs() + { + await SendSingleMessage(TestDeviceType.Sasl, Client.TransportType.Amqp_WebSocket_Only, ExceedAllowedMessageSizeInBytes).ConfigureAwait(false); + } + + // MQTT protocol will throw an InvalidOperationException if the PUBLISH packet is greater than + // Hub limits: https://github.com/Azure/azure-iot-sdk-csharp/blob/d46e0f07fe8d80e21e07b41c2e75b0bd1fcb8f80/iothub/device/src/Transport/Mqtt/MqttIotHubAdapter.cs#L1175 + // This flow is a bit different from other protocols where we do not inspect the packet being sent but rather rely on service validating it + // and throwing a MessageTooLargeException, if relevant. + [LoggedTestMethod] + [ExpectedException(typeof(InvalidOperationException))] + public async Task Message_DeviceSendMessageOverAllowedSize_Mqtt() + { + await SendSingleMessage(TestDeviceType.Sasl, Client.TransportType.Mqtt_Tcp_Only, ExceedAllowedMessageSizeInBytes).ConfigureAwait(false); + } + + // MQTT protocol will throw an InvalidOperationException if the PUBLISH packet is greater than + // Hub limits: https://github.com/Azure/azure-iot-sdk-csharp/blob/d46e0f07fe8d80e21e07b41c2e75b0bd1fcb8f80/iothub/device/src/Transport/Mqtt/MqttIotHubAdapter.cs#L1175 + // This flow is a bit different from other protocols where we do not inspect the packet being sent but rather rely on service validating it + // and throwing a MessageTooLargeException, if relevant. + [LoggedTestMethod] + [ExpectedException(typeof(InvalidOperationException))] + public async Task Message_DeviceSendMessageOverAllowedSize_MqttWs() + { + await SendSingleMessage(TestDeviceType.Sasl, Client.TransportType.Mqtt_WebSocket_Only, ExceedAllowedMessageSizeInBytes).ConfigureAwait(false); + } + + [LoggedTestMethod] + [ExpectedException(typeof(MessageTooLargeException))] + public async Task Message_DeviceSendMessageOverAllowedSize_Http() + { + await SendSingleMessage(TestDeviceType.Sasl, Client.TransportType.Http1, ExceedAllowedMessageSizeInBytes).ConfigureAwait(false); + } + + [LoggedTestMethod] + [ExpectedException(typeof(MessageTooLargeException))] + public async Task Message_DeviceSendMessageWayOverAllowedSize_Amqp() + { + await SendSingleMessage(TestDeviceType.Sasl, Client.TransportType.Amqp_Tcp_Only, OverlyExceedAllowedMessageSizeInBytes).ConfigureAwait(false); + } + + [LoggedTestMethod] + [ExpectedException(typeof(MessageTooLargeException))] + public async Task Message_DeviceSendMessageWayOverAllowedSize_AmqpWs() + { + await SendSingleMessage(TestDeviceType.Sasl, Client.TransportType.Amqp_WebSocket_Only, OverlyExceedAllowedMessageSizeInBytes).ConfigureAwait(false); + } + + // MQTT protocol will throw an InvalidOperationException if the PUBLISH packet is greater than + // Hub limits: https://github.com/Azure/azure-iot-sdk-csharp/blob/d46e0f07fe8d80e21e07b41c2e75b0bd1fcb8f80/iothub/device/src/Transport/Mqtt/MqttIotHubAdapter.cs#L1175 + // This flow is a bit different from other protocols where we do not inspect the packet being sent but rather rely on service validating it + // and throwing a MessageTooLargeException, if relevant. + [LoggedTestMethod] + [ExpectedException(typeof(InvalidOperationException))] + public async Task Message_DeviceSendMessageWayOverAllowedSize_Mqtt() + { + await SendSingleMessage(TestDeviceType.Sasl, Client.TransportType.Mqtt_Tcp_Only, OverlyExceedAllowedMessageSizeInBytes).ConfigureAwait(false); + } + + // MQTT protocol will throw an InvalidOperationException if the PUBLISH packet is greater than + // Hub limits: https://github.com/Azure/azure-iot-sdk-csharp/blob/d46e0f07fe8d80e21e07b41c2e75b0bd1fcb8f80/iothub/device/src/Transport/Mqtt/MqttIotHubAdapter.cs#L1175 + // This flow is a bit different from other protocols where we do not inspect the packet being sent but rather rely on service validating it + // and throwing a MessageTooLargeException, if relevant. + [LoggedTestMethod] + [ExpectedException(typeof(InvalidOperationException))] + public async Task Message_DeviceSendMessageWayOverAllowedSize_MqttWs() + { + await SendSingleMessage(TestDeviceType.Sasl, Client.TransportType.Mqtt_WebSocket_Only, OverlyExceedAllowedMessageSizeInBytes).ConfigureAwait(false); + } + + [LoggedTestMethod] + [ExpectedException(typeof(MessageTooLargeException))] + public async Task Message_DeviceSendMessageWayOverAllowedSize_Http() + { + await SendSingleMessage(TestDeviceType.Sasl, Client.TransportType.Http1, OverlyExceedAllowedMessageSizeInBytes).ConfigureAwait(false); + } + private async Task SendSingleMessage(TestDeviceType type, Client.TransportType transport, int messageSize = 0) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix, type).ConfigureAwait(false); + TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix, type).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); await deviceClient.OpenAsync().ConfigureAwait(false); @@ -257,7 +353,7 @@ private async Task SendSingleMessage(TestDeviceType type, Client.TransportType t private async Task SendBatchMessages(TestDeviceType type, Client.TransportType transport) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix, type).ConfigureAwait(false); + TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix, type).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); await deviceClient.OpenAsync().ConfigureAwait(false); @@ -267,7 +363,7 @@ private async Task SendBatchMessages(TestDeviceType type, Client.TransportType t private async Task SendSingleMessage(TestDeviceType type, ITransportSettings[] transportSettings, int messageSize = 0) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix, type).ConfigureAwait(false); + TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix, type).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(transportSettings); await deviceClient.OpenAsync().ConfigureAwait(false); @@ -277,7 +373,7 @@ private async Task SendSingleMessage(TestDeviceType type, ITransportSettings[] t private async Task SendSingleMessageModule(ITransportSettings[] transportSettings) { - TestModule testModule = await TestModule.GetTestModuleAsync(DevicePrefix, ModulePrefix, Logger).ConfigureAwait(false); + TestModule testModule = await TestModule.GetTestModuleAsync(_devicePrefix, _modulePrefix, Logger).ConfigureAwait(false); using var moduleClient = ModuleClient.CreateFromConnectionString(testModule.ConnectionString, transportSettings); await moduleClient.OpenAsync().ConfigureAwait(false); diff --git a/e2e/test/iothub/messaging/MessageSendFaultInjectionTests.cs b/e2e/test/iothub/messaging/MessageSendFaultInjectionTests.cs index 7546178e68..c5a89c2236 100644 --- a/e2e/test/iothub/messaging/MessageSendFaultInjectionTests.cs +++ b/e2e/test/iothub/messaging/MessageSendFaultInjectionTests.cs @@ -18,7 +18,7 @@ namespace Microsoft.Azure.Devices.E2ETests.Messaging public partial class MessageSendFaultInjectionTests : E2EMsTestBase { private readonly string _devicePrefix = $"E2E_{nameof(MessageSendFaultInjectionTests)}_"; - private static readonly string s_proxyServerAddress = Configuration.IoTHub.ProxyServerAddress; + private static readonly string s_proxyServerAddress = TestConfiguration.IoTHub.ProxyServerAddress; [LoggedTestMethod] public async Task Message_TcpConnectionLossSendRecovery_Amqp() diff --git a/e2e/test/iothub/method/MethodE2ETests.cs b/e2e/test/iothub/method/MethodE2ETests.cs index 18bbebb510..d4b71ec71f 100644 --- a/e2e/test/iothub/method/MethodE2ETests.cs +++ b/e2e/test/iothub/method/MethodE2ETests.cs @@ -129,7 +129,7 @@ public async Task Method_ServiceSendsMethodThroughProxyWithDefaultTimeout() { var serviceClientTransportSettings = new ServiceClientTransportSettings { - HttpProxy = new WebProxy(Configuration.IoTHub.ProxyServerAddress) + HttpProxy = new WebProxy(TestConfiguration.IoTHub.ProxyServerAddress) }; await SendMethodAndRespondAsync( @@ -144,7 +144,7 @@ public async Task Method_ServiceSendsMethodThroughProxyWithCustomTimeout() { var serviceClientTransportSettings = new ServiceClientTransportSettings { - HttpProxy = new WebProxy(Configuration.IoTHub.ProxyServerAddress) + HttpProxy = new WebProxy(TestConfiguration.IoTHub.ProxyServerAddress) }; await SendMethodAndRespondAsync( @@ -159,7 +159,7 @@ await SendMethodAndRespondAsync( public async Task Method_ServiceInvokeDeviceMethodWithUnknownDeviceThrows() { // setup - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); var methodInvocation = new CloudToDeviceMethod("SetTelemetryInterval"); methodInvocation.SetPayloadJson("10"); @@ -233,7 +233,7 @@ public async Task Method_ServiceInvokeDeviceMethodWithUnknownModuleThrows() { // setup TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, "ModuleNotFoundTest").ConfigureAwait(false); - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); var methodInvocation = new CloudToDeviceMethod("SetTelemetryInterval"); methodInvocation.SetPayloadJson("10"); @@ -282,7 +282,7 @@ await deviceClient null) .ConfigureAwait(false); - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); var c2dMethod = new CloudToDeviceMethod(commandName, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1)).SetPayloadJson(null); // act @@ -313,8 +313,8 @@ public static async Task ServiceSendMethodAndVerifyNotReceivedAsync( ServiceClientTransportSettings serviceClientTransportSettings = default) { ServiceClient serviceClient = serviceClientTransportSettings == default - ? ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString) - : ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString, TransportType.Amqp, serviceClientTransportSettings); + ? ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString) + : ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString, TransportType.Amqp, serviceClientTransportSettings); TimeSpan methodTimeout = responseTimeout == default ? s_defaultMethodTimeoutMinutes : responseTimeout; logger.Trace($"{nameof(ServiceSendMethodAndVerifyResponseAsync)}: Invoke method {methodName}."); @@ -346,8 +346,8 @@ public static async Task ServiceSendMethodAndVerifyResponseAsync( ServiceClientTransportSettings serviceClientTransportSettings = default) { ServiceClient serviceClient = serviceClientTransportSettings == default - ? ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString) - : ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString, TransportType.Amqp, serviceClientTransportSettings); + ? ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString) + : ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString, TransportType.Amqp, serviceClientTransportSettings); TimeSpan methodTimeout = responseTimeout == default ? s_defaultMethodTimeoutMinutes : responseTimeout; logger.Trace($"{nameof(ServiceSendMethodAndVerifyResponseAsync)}: Invoke method {methodName}."); CloudToDeviceMethodResult response = @@ -375,8 +375,8 @@ public static async Task ServiceSendMethodAndVerifyResponseAsync( ServiceClientTransportSettings serviceClientTransportSettings = default) { ServiceClient serviceClient = serviceClientTransportSettings == default - ? ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString) - : ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString, TransportType.Amqp, serviceClientTransportSettings); + ? ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString) + : ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString, TransportType.Amqp, serviceClientTransportSettings); TimeSpan methodTimeout = responseTimeout == default ? s_defaultMethodTimeoutMinutes : responseTimeout; diff --git a/e2e/test/iothub/method/MethodFaultInjectionTests.cs b/e2e/test/iothub/method/MethodFaultInjectionTests.cs index 483e6df6e0..4b33787d59 100644 --- a/e2e/test/iothub/method/MethodFaultInjectionTests.cs +++ b/e2e/test/iothub/method/MethodFaultInjectionTests.cs @@ -214,7 +214,7 @@ private async Task ServiceSendMethodAndVerifyResponseAsync(string deviceName, st attempt++; try { - using ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); Logger.Trace($"{nameof(ServiceSendMethodAndVerifyResponseAsync)}: Invoke method {methodName}."); CloudToDeviceMethodResult response = diff --git a/e2e/test/iothub/properties/PropertiesE2ETests.cs b/e2e/test/iothub/properties/PropertiesE2ETests.cs index 0a2da2c3c7..7db552aa57 100644 --- a/e2e/test/iothub/properties/PropertiesE2ETests.cs +++ b/e2e/test/iothub/properties/PropertiesE2ETests.cs @@ -22,7 +22,7 @@ public class PropertiesE2ETests : E2EMsTestBase { private readonly string _devicePrefix = $"E2E_{nameof(PropertiesE2ETests)}_"; - private static readonly RegistryManager s_registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + private static readonly RegistryManager s_registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); private static readonly TimeSpan s_maxWaitTimeForCallback = TimeSpan.FromSeconds(30); private static readonly Dictionary s_mapOfPropertyValues = new Dictionary @@ -225,7 +225,7 @@ public static async Task Properties_DeviceSetsPropertyAndGetsItBackAsync(Devi public static async Task RegistryManagerUpdateWritablePropertyAsync(string deviceId, string propName, T propValue) { - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); var twinPatch = new Twin(); twinPatch.Properties.Desired[propName] = propValue; @@ -311,7 +311,7 @@ private async Task Properties_ServiceSetsWritablePropertyAndDeviceReceivesItOnNe string propValue = Guid.NewGuid().ToString(); TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); var twinPatch = new Twin(); @@ -333,7 +333,7 @@ private async Task Properties_DeviceSetsPropertyAndServiceReceivesItAsync(Client string propValue = Guid.NewGuid().ToString(); TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); var patch = new ClientPropertyCollection(); @@ -357,7 +357,7 @@ private async Task Properties_DeviceSendsNullValueForPropertyResultsServiceRemov string propEmptyValue = "{}"; TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); // First send a property patch with valid values for both prop1 and prop2. @@ -416,7 +416,7 @@ private async Task Properties_ClientHandlesRejectionInvalidPropertyNameAsync(Cli string propName2 = Guid.NewGuid().ToString(); TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); Func func = async () => diff --git a/e2e/test/iothub/properties/PropertiesFaultInjectionTests.cs b/e2e/test/iothub/properties/PropertiesFaultInjectionTests.cs index aa32c93a20..3c71d594f6 100644 --- a/e2e/test/iothub/properties/PropertiesFaultInjectionTests.cs +++ b/e2e/test/iothub/properties/PropertiesFaultInjectionTests.cs @@ -153,7 +153,7 @@ await FaultInjection private async Task RegistryManagerUpdateDesiredPropertyAsync(string deviceId, string propName, string propValue) { - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); var twinPatch = new Twin(); twinPatch.Properties.Desired[propName] = propValue; diff --git a/e2e/test/iothub/properties/PropertiesWithComponentsE2ETests.cs b/e2e/test/iothub/properties/PropertiesWithComponentsE2ETests.cs index 156c67f9fd..96040512d5 100644 --- a/e2e/test/iothub/properties/PropertiesWithComponentsE2ETests.cs +++ b/e2e/test/iothub/properties/PropertiesWithComponentsE2ETests.cs @@ -24,7 +24,7 @@ public class PropertiesWithComponentsE2ETests : E2EMsTestBase private readonly string _devicePrefix = $"E2E_{nameof(PropertiesWithComponentsE2ETests)}_"; - private static readonly RegistryManager s_registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + private static readonly RegistryManager s_registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); private static readonly TimeSpan s_maxWaitTimeForCallback = TimeSpan.FromSeconds(30); private static readonly Dictionary s_mapOfPropertyValues = new Dictionary @@ -227,7 +227,7 @@ public static async Task PropertiesWithComponents_DeviceSetsPropertyAndGetsItBac public static async Task RegistryManagerUpdateWritablePropertyAsync(string deviceId, string componentName, string propName, T propValue) { - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); var twinPatch = new Twin(); var componentProperties = new TwinCollection @@ -318,7 +318,7 @@ private async Task PropertiesWithComponents_ServiceSetsWritablePropertyAndDevice string propValue = Guid.NewGuid().ToString(); TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); var twinPatch = new Twin(); @@ -345,7 +345,7 @@ private async Task PropertiesWithComponents_DeviceSetsPropertyAndServiceReceives string propValue = Guid.NewGuid().ToString(); TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); var patch = new ClientPropertyCollection(); @@ -369,7 +369,7 @@ private async Task Properties_DeviceSendsNullValueForPropertyResultsServiceRemov string propEmptyValue = "{}"; TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); // First send a property patch with valid values for both prop1 and prop2. @@ -444,7 +444,7 @@ private async Task PropertiesWithComponents_ClientHandlesRejectionInvalidPropert string propName2 = Guid.NewGuid().ToString(); TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); Func func = async () => diff --git a/e2e/test/iothub/service/BulkOperationsE2ETests.cs b/e2e/test/iothub/service/BulkOperationsE2ETests.cs index 97880bb878..f748b217fa 100644 --- a/e2e/test/iothub/service/BulkOperationsE2ETests.cs +++ b/e2e/test/iothub/service/BulkOperationsE2ETests.cs @@ -25,7 +25,7 @@ public async Task BulkOperations_UpdateTwins2Device_Ok() var tagValue = Guid.NewGuid().ToString(); TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); Twin twin = await registryManager.GetTwinAsync(testDevice.Id).ConfigureAwait(false); @@ -52,7 +52,7 @@ public async Task BulkOperations_UpdateTwins2DevicePatch_Ok() var tagValue = Guid.NewGuid().ToString(); TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); Twin twin = new Twin(); twin.DeviceId = testDevice.Id; @@ -79,7 +79,7 @@ public async Task BulkOperations_UpdateTwins2Module_Ok() var tagValue = Guid.NewGuid().ToString(); TestModule testModule = await TestModule.GetTestModuleAsync(DevicePrefix, ModulePrefix, Logger).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); Twin twin = await registryManager.GetTwinAsync(testModule.DeviceId, testModule.Id).ConfigureAwait(false); @@ -108,7 +108,7 @@ public async Task BulkOperations_UpdateTwins2ModulePatch_Ok() TestModule testModule = await TestModule.GetTestModuleAsync(DevicePrefix, ModulePrefix, Logger).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); var twin = new Twin(); twin.DeviceId = testModule.DeviceId; twin.ModuleId = testModule.Id; diff --git a/e2e/test/iothub/service/DigitalTwinClientE2ETests.cs b/e2e/test/iothub/service/DigitalTwinClientE2ETests.cs index 4d8aee5168..435998214f 100644 --- a/e2e/test/iothub/service/DigitalTwinClientE2ETests.cs +++ b/e2e/test/iothub/service/DigitalTwinClientE2ETests.cs @@ -25,7 +25,7 @@ public class DigitalTwinClientE2ETests : E2EMsTestBase private const string TemperatureControllerModelId = "dtmi:com:example:TemperatureController;1"; private readonly string _devicePrefix = $"E2E_{nameof(DigitalTwinClientE2ETests)}_"; - private static readonly string s_connectionString = Configuration.IoTHub.ConnectionString; + private static readonly string s_connectionString = TestConfiguration.IoTHub.ConnectionString; [LoggedTestMethod] public async Task DigitalTwinWithOnlyRootComponentOperationsAsync() diff --git a/e2e/test/iothub/service/IoTHubCertificateValidationE2ETest.cs b/e2e/test/iothub/service/IoTHubCertificateValidationE2ETest.cs index 4ba550d855..0ebf0f1c5b 100644 --- a/e2e/test/iothub/service/IoTHubCertificateValidationE2ETest.cs +++ b/e2e/test/iothub/service/IoTHubCertificateValidationE2ETest.cs @@ -18,7 +18,7 @@ public class IoTHubCertificateValidationE2ETest : E2EMsTestBase [LoggedTestMethod] public async Task RegistryManager_QueryDevicesInvalidServiceCertificateHttp_Fails() { - var rm = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionStringInvalidServiceCertificate); + var rm = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionStringInvalidServiceCertificate); IQuery query = rm.CreateQuery("select * from devices"); var exception = await Assert.ThrowsExceptionAsync( () => query.GetNextAsTwinAsync()).ConfigureAwait(false); @@ -51,7 +51,7 @@ public async Task ServiceClient_SendMessageToDeviceInvalidServiceCertificateAmqp private static async Task TestServiceClientInvalidServiceCertificate(TransportType transport) { var service = ServiceClient.CreateFromConnectionString( - Configuration.IoTHub.ConnectionStringInvalidServiceCertificate, + TestConfiguration.IoTHub.ConnectionStringInvalidServiceCertificate, transport); await service.SendAsync("testDevice1", new Message()).ConfigureAwait(false); } @@ -59,7 +59,7 @@ private static async Task TestServiceClientInvalidServiceCertificate(TransportTy [LoggedTestMethod] public async Task JobClient_ScheduleTwinUpdateInvalidServiceCertificateHttp_Fails() { - var job = JobClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionStringInvalidServiceCertificate); + var job = JobClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionStringInvalidServiceCertificate); var exception = await Assert.ThrowsExceptionAsync( () => job.ScheduleTwinUpdateAsync( "testDevice", @@ -129,7 +129,7 @@ private static async Task TestDeviceClientInvalidServiceCertificate(Client.Trans { using (DeviceClient deviceClient = DeviceClient.CreateFromConnectionString( - Configuration.IoTHub.DeviceConnectionStringInvalidServiceCertificate, + TestConfiguration.IoTHub.DeviceConnectionStringInvalidServiceCertificate, transport)) { await deviceClient.SendEventAsync(new Client.Message()).ConfigureAwait(false); diff --git a/e2e/test/iothub/service/IoTHubServiceProxyE2ETests.cs b/e2e/test/iothub/service/IoTHubServiceProxyE2ETests.cs index da10526a10..042d6b854f 100644 --- a/e2e/test/iothub/service/IoTHubServiceProxyE2ETests.cs +++ b/e2e/test/iothub/service/IoTHubServiceProxyE2ETests.cs @@ -22,8 +22,8 @@ public class IoTHubServiceProxyE2ETests : E2EMsTestBase private readonly string DevicePrefix = $"{nameof(IoTHubServiceProxyE2ETests)}_"; private const string JobDeviceId = "JobsSample_Device"; private const string JobTestTagName = "JobsSample_Tag"; - private static string s_connectionString = Configuration.IoTHub.ConnectionString; - private static string s_proxyServerAddress = Configuration.IoTHub.ProxyServerAddress; + private static string s_connectionString = TestConfiguration.IoTHub.ConnectionString; + private static string s_proxyServerAddress = TestConfiguration.IoTHub.ProxyServerAddress; private const int MaxIterationWait = 30; private static readonly TimeSpan _waitDuration = TimeSpan.FromSeconds(5); diff --git a/e2e/test/iothub/service/PnpServiceTests.cs b/e2e/test/iothub/service/PnpServiceTests.cs index ad84bb3eed..b88e2c9e5d 100644 --- a/e2e/test/iothub/service/PnpServiceTests.cs +++ b/e2e/test/iothub/service/PnpServiceTests.cs @@ -43,7 +43,7 @@ public async Task DeviceTwin_Contains_ModelId() // Act // Get device twin. - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); Twin twin = await registryManager.GetTwinAsync(testDevice.Device.Id).ConfigureAwait(false); // Assert @@ -65,15 +65,15 @@ public async Task DeviceTwin_Contains_ModelId_X509() { ModelId = TestModelId, }; - string hostName = HostNameHelper.GetHostName(Configuration.IoTHub.ConnectionString); - var auth = new DeviceAuthenticationWithX509Certificate(testDevice.Id, Configuration.IoTHub.GetCertificateWithPrivateKey()); + string hostName = HostNameHelper.GetHostName(TestConfiguration.IoTHub.ConnectionString); + var auth = new DeviceAuthenticationWithX509Certificate(testDevice.Id, TestConfiguration.IoTHub.GetCertificateWithPrivateKey()); using var deviceClient = DeviceClient.Create(hostName, auth, Client.TransportType.Mqtt_Tcp_Only, options); await deviceClient.OpenAsync().ConfigureAwait(false); // Act // Get device twin. - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); Twin twin = await registryManager.GetTwinAsync(testDevice.Device.Id).ConfigureAwait(false); // Assert @@ -101,7 +101,7 @@ public async Task ModuleTwin_Contains_ModelId() // Act // Get module twin. - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); Twin twin = await registryManager.GetTwinAsync(testModule.DeviceId, testModule.Id).ConfigureAwait(false); // Assert diff --git a/e2e/test/iothub/service/RegistryManagerE2ETests.cs b/e2e/test/iothub/service/RegistryManagerE2ETests.cs index e3a257a7c5..9d93ffccc2 100644 --- a/e2e/test/iothub/service/RegistryManagerE2ETests.cs +++ b/e2e/test/iothub/service/RegistryManagerE2ETests.cs @@ -28,10 +28,10 @@ public async Task RegistryManager_BadProxy_ThrowsException() { // arrange var registryManager = RegistryManager.CreateFromConnectionString( - Configuration.IoTHub.ConnectionString, + TestConfiguration.IoTHub.ConnectionString, new HttpTransportSettings { - Proxy = new WebProxy(Configuration.IoTHub.InvalidProxyServerAddress), + Proxy = new WebProxy(TestConfiguration.IoTHub.InvalidProxyServerAddress), }); // act @@ -47,7 +47,7 @@ public async Task RegistryManager_AddAndRemoveDeviceWithScope() string edgeId2 = _devicePrefix + Guid.NewGuid(); string deviceId = _devicePrefix + Guid.NewGuid(); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); try { @@ -95,7 +95,7 @@ public async Task RegistryManager_AddDeviceWithTwinWithDeviceCapabilities() { string deviceId = _devicePrefix + Guid.NewGuid(); - using (var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString)) + using (var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString)) { var twin = new Twin { @@ -126,7 +126,7 @@ public async Task RegistryManager_BulkLifecycle() devices.Add(new Device(_devicePrefix + Guid.NewGuid())); } - var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); // Test that you can create devices in bulk var bulkAddResult = await registryManager.AddDevices2Async(devices).ConfigureAwait(false); @@ -176,10 +176,10 @@ public async Task RegistryManager_AddDeviceWithProxy() string deviceId = _devicePrefix + Guid.NewGuid(); var transportSettings = new HttpTransportSettings { - Proxy = new WebProxy(Configuration.IoTHub.ProxyServerAddress) + Proxy = new WebProxy(TestConfiguration.IoTHub.ProxyServerAddress) }; - using (var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString, transportSettings)) + using (var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString, transportSettings)) { var device = new Device(deviceId); await registryManager.AddDeviceAsync(device).ConfigureAwait(false); @@ -190,7 +190,7 @@ public async Task RegistryManager_AddDeviceWithProxy() public async Task RegistryManager_Query_Works() { // arrange - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); string deviceId = $"{_devicePrefix}{Guid.NewGuid()}"; try @@ -242,7 +242,7 @@ public async Task ModulesClient_GetModulesOnDevice() } Device device = null; - RegistryManager client = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + RegistryManager client = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); try { @@ -285,7 +285,7 @@ public async Task ModulesClient_IdentityLifecycle() string testDeviceId = $"IdentityLifecycleDevice{Guid.NewGuid()}"; string testModuleId = $"IdentityLifecycleModule{Guid.NewGuid()}"; - RegistryManager client = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + RegistryManager client = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); try { @@ -328,7 +328,7 @@ public async Task ModulesClient_IdentityLifecycle() [LoggedTestMethod] public async Task ModulesClient_DeviceTwinLifecycle() { - RegistryManager client = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + RegistryManager client = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); var module = await TestModule.GetTestModuleAsync(_devicePrefix, _modulePrefix, Logger).ConfigureAwait(false); try diff --git a/e2e/test/iothub/service/RegistryManagerExportDevicesTests.cs b/e2e/test/iothub/service/RegistryManagerExportDevicesTests.cs index ff8fe7b9da..1b1b8795be 100644 --- a/e2e/test/iothub/service/RegistryManagerExportDevicesTests.cs +++ b/e2e/test/iothub/service/RegistryManagerExportDevicesTests.cs @@ -54,8 +54,9 @@ public async Task RegistryManager_ExportDevices(StorageAuthenticationType storag // arrange StorageContainer storageContainer = null; + string edgeId = $"{nameof(RegistryManager_ExportDevices)}-Edge-{StorageContainer.GetRandomSuffix(4)}"; string deviceId = $"{nameof(RegistryManager_ExportDevices)}-{StorageContainer.GetRandomSuffix(4)}"; - var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); Logger.Trace($"Using deviceId {deviceId}"); @@ -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); @@ -90,7 +101,7 @@ await registryManager ManagedIdentity identity = null; if (isUserAssignedMsi) { - string userAssignedMsiResourceId = Configuration.IoTHub.UserAssignedMsiResourceId; + string userAssignedMsiResourceId = TestConfiguration.IoTHub.UserAssignedMsiResourceId; identity = new ManagedIdentity { userAssignedIdentity = userAssignedMsiResourceId @@ -151,6 +162,7 @@ await registryManager { Logger.Trace($"Found device in export as [{serializedDeivce}]"); foundDeviceInExport = true; + device.DeviceScope.Should().Be(edge.Scope); break; } } @@ -163,6 +175,7 @@ await registryManager storageContainer?.Dispose(); await registryManager.RemoveDeviceAsync(deviceId).ConfigureAwait(false); + await registryManager.RemoveDeviceAsync(edgeId).ConfigureAwait(false); } catch { } } diff --git a/e2e/test/iothub/service/RegistryManagerImportDevicesTests.cs b/e2e/test/iothub/service/RegistryManagerImportDevicesTests.cs index a7b47e1ae9..21bad7bb87 100644 --- a/e2e/test/iothub/service/RegistryManagerImportDevicesTests.cs +++ b/e2e/test/iothub/service/RegistryManagerImportDevicesTests.cs @@ -49,7 +49,7 @@ public async Task RegistryManager_ImportDevices(StorageAuthenticationType storag StorageContainer storageContainer = null; string deviceId = $"{nameof(RegistryManager_ImportDevices)}-{StorageContainer.GetRandomSuffix(4)}"; - var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); Logger.Trace($"Using deviceId {deviceId}"); @@ -88,7 +88,7 @@ public async Task RegistryManager_ImportDevices(StorageAuthenticationType storag ManagedIdentity identity = null; if (isUserAssignedMsi) { - string userAssignedMsiResourceId = Configuration.IoTHub.UserAssignedMsiResourceId; + string userAssignedMsiResourceId = TestConfiguration.IoTHub.UserAssignedMsiResourceId; identity = new ManagedIdentity { userAssignedIdentity = userAssignedMsiResourceId diff --git a/e2e/test/iothub/service/ServiceClientE2ETests.cs b/e2e/test/iothub/service/ServiceClientE2ETests.cs index e9af1c4eb3..3f5d8a11f8 100644 --- a/e2e/test/iothub/service/ServiceClientE2ETests.cs +++ b/e2e/test/iothub/service/ServiceClientE2ETests.cs @@ -48,7 +48,7 @@ private async Task DefaultTimeout() private async Task TestTimeout(TimeSpan? timeout) { TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); - using var sender = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var sender = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); Stopwatch sw = new Stopwatch(); sw.Start(); @@ -72,7 +72,7 @@ public async Task ServiceClient_SendsMessage(TransportType transportType) { // arrange TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); - using var sender = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString, transportType); + using var sender = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString, transportType); string messageId = Guid.NewGuid().ToString(); // act and expect no exception @@ -91,7 +91,7 @@ public async Task MessageIdDefaultNotSet_SendEventDoesNotSetMessageId() { // arrange TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); - using var sender = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var sender = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); string messageId = Guid.NewGuid().ToString(); // act @@ -120,7 +120,7 @@ public async Task MessageIdDefaultSetToNull_SendEventDoesNotSetMessageId() { SdkAssignsMessageId = Shared.SdkAssignsMessageId.Never, }; - using var sender = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString, options); + using var sender = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString, options); string messageId = Guid.NewGuid().ToString(); // act @@ -149,7 +149,7 @@ public async Task MessageIdDefaultSetToGuid_SendEventSetMessageIdIfNotSet() { SdkAssignsMessageId = Shared.SdkAssignsMessageId.WhenUnset, }; - using var sender = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString, options); + using var sender = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString, options); string messageId = Guid.NewGuid().ToString(); // act diff --git a/e2e/test/iothub/twin/TwinE2ETests.cs b/e2e/test/iothub/twin/TwinE2ETests.cs index bdea63b787..48dbbaa582 100644 --- a/e2e/test/iothub/twin/TwinE2ETests.cs +++ b/e2e/test/iothub/twin/TwinE2ETests.cs @@ -21,7 +21,7 @@ public class TwinE2ETests : E2EMsTestBase { private readonly string _devicePrefix = $"E2E_{nameof(TwinE2ETests)}_"; - private static readonly RegistryManager _registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + private static readonly RegistryManager _registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); private static readonly List s_listOfPropertyValues = new List { @@ -523,7 +523,7 @@ await deviceClient public static async Task RegistryManagerUpdateDesiredPropertyAsync(string deviceId, string propName, object propValue) { - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); var twinPatch = new Twin(); twinPatch.Properties.Desired[propName] = propValue; @@ -602,7 +602,7 @@ private async Task Twin_ServiceSetsDesiredPropertyAndDeviceReceivesItOnNextGetAs var propValue = Guid.NewGuid().ToString(); TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); var twinPatch = new Twin(); @@ -622,7 +622,7 @@ private async Task Twin_DeviceSetsReportedPropertyAndServiceReceivesItAsync(Clie var propValue = Guid.NewGuid().ToString(); TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); var patch = new TwinCollection(); @@ -643,7 +643,7 @@ private async Task Twin_ServiceDoesNotCreateNullPropertyInCollectionAsync(Client var propEmptyValue = "{}"; TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); await deviceClient @@ -694,7 +694,7 @@ private async Task Twin_ClientHandlesRejectionInvalidPropertyNameAsync(Client.Tr var propName2 = Guid.NewGuid().ToString(); TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); var exceptionThrown = false; diff --git a/e2e/test/iothub/twin/TwinFaultInjectionTests.cs b/e2e/test/iothub/twin/TwinFaultInjectionTests.cs index 688303f08d..0f163d994f 100644 --- a/e2e/test/iothub/twin/TwinFaultInjectionTests.cs +++ b/e2e/test/iothub/twin/TwinFaultInjectionTests.cs @@ -256,7 +256,7 @@ await FaultInjection private async Task RegistryManagerUpdateDesiredPropertyAsync(string deviceId, string propName, string propValue) { - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); var twinPatch = new Twin(); twinPatch.Properties.Desired[propName] = propValue; @@ -273,7 +273,7 @@ private async Task Twin_DeviceDesiredPropertyUpdateRecoveryAsync( string proxyAddress = null) { TestDeviceCallbackHandler testDeviceCallbackHandler = null; - var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString); using var cts = new CancellationTokenSource(FaultInjection.RecoveryTime); var propName = Guid.NewGuid().ToString(); diff --git a/e2e/test/provisioning/ProvisioningCertificateValidationE2ETest.cs b/e2e/test/provisioning/ProvisioningCertificateValidationE2ETest.cs index ba2c52a6b4..21482a1ec7 100644 --- a/e2e/test/provisioning/ProvisioningCertificateValidationE2ETest.cs +++ b/e2e/test/provisioning/ProvisioningCertificateValidationE2ETest.cs @@ -19,7 +19,7 @@ public class ProvisioningCertificateValidationE2ETest : E2EMsTestBase public async Task ProvisioningServiceClient_QueryInvalidServiceCertificateHttp_Fails() { using var provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString( - Configuration.Provisioning.ConnectionStringInvalidServiceCertificate); + TestConfiguration.Provisioning.ConnectionStringInvalidServiceCertificate); Query q = provisioningServiceClient.CreateEnrollmentGroupQuery( new QuerySpecification("SELECT * FROM enrollmentGroups")); @@ -97,9 +97,9 @@ public async Task ProvisioningDeviceClient_RegisterAsyncInvalidServiceCertificat private static async Task TestInvalidServiceCertificate(ProvisioningTransportHandler transport) { using var security = - new SecurityProviderX509Certificate(Configuration.Provisioning.GetIndividualEnrollmentCertificate()); + new SecurityProviderX509Certificate(TestConfiguration.Provisioning.GetIndividualEnrollmentCertificate()); ProvisioningDeviceClient provisioningDeviceClient = ProvisioningDeviceClient.Create( - Configuration.Provisioning.GlobalDeviceEndpointInvalidServiceCertificate, + TestConfiguration.Provisioning.GlobalDeviceEndpointInvalidServiceCertificate, "0ne00000001", security, transport); diff --git a/e2e/test/provisioning/ProvisioningE2ETests.cs b/e2e/test/provisioning/ProvisioningE2ETests.cs index 68947e2a49..0cd498d760 100644 --- a/e2e/test/provisioning/ProvisioningE2ETests.cs +++ b/e2e/test/provisioning/ProvisioningE2ETests.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Net.Sockets; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Text; @@ -31,8 +32,8 @@ public class ProvisioningE2ETests : E2EMsTestBase private const string InvalidIdScope = "0neFFFFFFFF"; private const string PayloadJsonData = "{\"testKey\":\"testValue\"}"; private const string InvalidGlobalAddress = "httpbin.org"; - private static readonly string s_globalDeviceEndpoint = Configuration.Provisioning.GlobalDeviceEndpoint; - private static readonly string s_proxyServerAddress = Configuration.IoTHub.ProxyServerAddress; + private static readonly string s_globalDeviceEndpoint = TestConfiguration.Provisioning.GlobalDeviceEndpoint; + private static readonly string s_proxyServerAddress = TestConfiguration.IoTHub.ProxyServerAddress; private readonly string _idPrefix = $"e2e-{nameof(ProvisioningE2ETests).ToLower()}-"; private readonly VerboseTestLogger _verboseLog = VerboseTestLogger.GetInstance(); @@ -372,17 +373,17 @@ private async Task ProvisioningDeviceClientCustomAllocationPolicyAsync( bool setCustomProxy, string customServerProxy = null) { - var closeHostName = IotHubConnectionStringBuilder.Create(Configuration.IoTHub.ConnectionString).HostName; + var closeHostName = IotHubConnectionStringBuilder.Create(TestConfiguration.IoTHub.ConnectionString).HostName; - ICollection iotHubsToProvisionTo = new List() { closeHostName, Configuration.Provisioning.FarAwayIotHubHostName }; + ICollection iotHubsToProvisionTo = new List() { closeHostName, TestConfiguration.Provisioning.FarAwayIotHubHostName }; string expectedDestinationHub = ""; - if (closeHostName.Length > Configuration.Provisioning.FarAwayIotHubHostName.Length) + if (closeHostName.Length > TestConfiguration.Provisioning.FarAwayIotHubHostName.Length) { expectedDestinationHub = closeHostName; } - else if (closeHostName.Length < Configuration.Provisioning.FarAwayIotHubHostName.Length) + else if (closeHostName.Length < TestConfiguration.Provisioning.FarAwayIotHubHostName.Length) { - expectedDestinationHub = Configuration.Provisioning.FarAwayIotHubHostName; + expectedDestinationHub = TestConfiguration.Provisioning.FarAwayIotHubHostName; } else { @@ -432,6 +433,62 @@ public async Task ProvisioningDeviceClient_ValidRegistrationId_MqttWsWithProxy_S await ProvisioningDeviceClient_ValidRegistrationId_Register_Ok(Client.TransportType.Mqtt, AttestationMechanismType.SymmetricKey, EnrollmentType.Individual, true, s_proxyServerAddress).ConfigureAwait(false); } + [LoggedTestMethod] + public async Task ProvisioningDeviceClient_ValidRegistrationId_TimeSpanTimeoutRespected_Mqtt() + { + try + { + await ProvisioningDeviceClient_ValidRegistrationId_Register_Ok(Client.TransportType.Mqtt_Tcp_Only, AttestationMechanismType.SymmetricKey, EnrollmentType.Individual, TimeSpan.Zero).ConfigureAwait(false); + } + catch (OperationCanceledException) + { + return; // expected exception was thrown, so exit the test + } + + throw new AssertFailedException("Expected an OperationCanceledException to be thrown since the timeout was set to TimeSpan.Zero"); + } + + [LoggedTestMethod] + public async Task ProvisioningDeviceClient_ValidRegistrationId_TimeSpanTimeoutRespected_Https() + { + try + { + await ProvisioningDeviceClient_ValidRegistrationId_Register_Ok(Client.TransportType.Http1, AttestationMechanismType.SymmetricKey, EnrollmentType.Individual, TimeSpan.Zero).ConfigureAwait(false); + } + catch (OperationCanceledException) + { + return; // expected exception was thrown, so exit the test + } + + throw new AssertFailedException("Expected an OperationCanceledException to be thrown since the timeout was set to TimeSpan.Zero"); + } + + [LoggedTestMethod] + public async Task ProvisioningDeviceClient_ValidRegistrationId_TimeSpanTimeoutRespected_Amqps() + { + try + { + await ProvisioningDeviceClient_ValidRegistrationId_Register_Ok(Client.TransportType.Amqp_Tcp_Only, AttestationMechanismType.SymmetricKey, EnrollmentType.Individual, TimeSpan.Zero).ConfigureAwait(false); + } + catch (ProvisioningTransportException ex) when (ex.InnerException is SocketException && ((SocketException) ex.InnerException).SocketErrorCode == SocketError.TimedOut) + { + // The expected exception is a bit different in AMQP compared to MQTT/HTTPS + return; // expected exception was thrown, so exit the test + } + + throw new AssertFailedException("Expected an OperationCanceledException to be thrown since the timeout was set to TimeSpan.Zero"); + } + + public async Task ProvisioningDeviceClient_ValidRegistrationId_Register_Ok( + Client.TransportType transportType, + AttestationMechanismType attestationType, + EnrollmentType? enrollmentType, + TimeSpan timeout) + { + //Default reprovisioning settings: Hashed allocation, no reprovision policy, hub names, or custom allocation policy + await ProvisioningDeviceClientValidRegistrationIdRegisterOkAsync(transportType, attestationType, enrollmentType, false, null, AllocationPolicy.Hashed, null, null, null, timeout, s_proxyServerAddress).ConfigureAwait(false); + } + public async Task ProvisioningDeviceClient_ValidRegistrationId_Register_Ok( Client.TransportType transportType, AttestationMechanismType attestationType, @@ -440,7 +497,7 @@ public async Task ProvisioningDeviceClient_ValidRegistrationId_Register_Ok( string proxyServerAddress = null) { //Default reprovisioning settings: Hashed allocation, no reprovision policy, hub names, or custom allocation policy - await ProvisioningDeviceClientValidRegistrationIdRegisterOkAsync(transportType, attestationType, enrollmentType, setCustomProxy, null, AllocationPolicy.Hashed, null, null, null, s_proxyServerAddress).ConfigureAwait(false); + await ProvisioningDeviceClientValidRegistrationIdRegisterOkAsync(transportType, attestationType, enrollmentType, setCustomProxy, null, AllocationPolicy.Hashed, null, null, null, TimeSpan.MaxValue, proxyServerAddress).ConfigureAwait(false); } public async Task ProvisioningDeviceClient_ValidRegistrationId_Register_Ok( @@ -452,7 +509,7 @@ public async Task ProvisioningDeviceClient_ValidRegistrationId_Register_Ok( string proxyServerAddress = null) { //Default reprovisioning settings: Hashed allocation, no reprovision policy, hub names, or custom allocation policy - var iothubs = new List() { IotHubConnectionStringBuilder.Create(Configuration.IoTHub.ConnectionString).HostName }; + var iothubs = new List() { IotHubConnectionStringBuilder.Create(TestConfiguration.IoTHub.ConnectionString).HostName }; await ProvisioningDeviceClientValidRegistrationIdRegisterOkAsync( transportType, attestationType, @@ -463,7 +520,8 @@ await ProvisioningDeviceClientValidRegistrationIdRegisterOkAsync( null, iothubs, capabilities, - s_proxyServerAddress) + TimeSpan.MaxValue, + proxyServerAddress) .ConfigureAwait(false); } @@ -477,6 +535,7 @@ private async Task ProvisioningDeviceClientValidRegistrationIdRegisterOkAsync( CustomAllocationDefinition customAllocationDefinition, ICollection iothubs, DeviceCapabilities deviceCapabilities, + TimeSpan timeout, string proxyServerAddress = null) { string groupId = _idPrefix + AttestationTypeToString(attestationType) + "-" + Guid.NewGuid(); @@ -500,7 +559,7 @@ private async Task ProvisioningDeviceClientValidRegistrationIdRegisterOkAsync( var provClient = ProvisioningDeviceClient.Create( s_globalDeviceEndpoint, - Configuration.Provisioning.IdScope, + TestConfiguration.Provisioning.IdScope, security, transport); @@ -516,7 +575,14 @@ private async Task ProvisioningDeviceClientValidRegistrationIdRegisterOkAsync( { try { - result = await provClient.RegisterAsync(cts.Token).ConfigureAwait(false); + if (timeout != TimeSpan.MaxValue) + { + result = await provClient.RegisterAsync(timeout).ConfigureAwait(false); + } + else + { + result = await provClient.RegisterAsync(cts.Token).ConfigureAwait(false); + } break; } // Catching all ProvisioningTransportException as the status code is not the same for Mqtt, Amqp and Http. @@ -555,7 +621,7 @@ private async Task ProvisioningDeviceClientProvisioningFlowCustomAllocationAlloc var customAllocationDefinition = new CustomAllocationDefinition { - WebhookUrl = Configuration.Provisioning.CustomAllocationPolicyWebhook, + WebhookUrl = TestConfiguration.Provisioning.CustomAllocationPolicyWebhook, ApiVersion = "2019-03-31", }; @@ -578,7 +644,7 @@ private async Task ProvisioningDeviceClientProvisioningFlowCustomAllocationAlloc var provClient = ProvisioningDeviceClient.Create( s_globalDeviceEndpoint, - Configuration.Provisioning.IdScope, + TestConfiguration.Provisioning.IdScope, security, transport); using var cts = new CancellationTokenSource(PassingTimeoutMiliseconds); @@ -645,7 +711,7 @@ public async Task ProvisioningDeviceClient_InvalidRegistrationId_TpmRegister_Fai using SecurityProvider security = new SecurityProviderTpmSimulator("invalidregistrationid"); var provClient = ProvisioningDeviceClient.Create( s_globalDeviceEndpoint, - Configuration.Provisioning.IdScope, + TestConfiguration.Provisioning.IdScope, security, transport); @@ -812,7 +878,7 @@ private async Task ProvisioningDeviceClientInvalidGlobalAddressRegisterFailAsync ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create( InvalidGlobalAddress, - Configuration.Provisioning.IdScope, + TestConfiguration.Provisioning.IdScope, security, transport); @@ -893,7 +959,7 @@ private async Task CreateSecurityProviderFromNameAsync(Attesta { _verboseLog.WriteLine($"{nameof(CreateSecurityProviderFromNameAsync)}({attestationType})"); - var provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); + var provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(TestConfiguration.Provisioning.ConnectionString); switch (attestationType) { @@ -903,7 +969,7 @@ private async Task CreateSecurityProviderFromNameAsync(Attesta string base64Ek = Convert.ToBase64String(tpmSim.GetEndorsementKey()); - var provisioningService = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); + var provisioningService = ProvisioningServiceClient.CreateFromConnectionString(TestConfiguration.Provisioning.ConnectionString); Logger.Trace($"Getting enrollment: RegistrationID = {registrationId}"); IndividualEnrollment individualEnrollment = new IndividualEnrollment(registrationId, new TpmAttestation(base64Ek)) { AllocationPolicy = allocationPolicy, ReprovisionPolicy = reprovisionPolicy, IotHubs = iothubs, CustomAllocationDefinition = customAllocationDefinition, Capabilities = capabilities }; @@ -922,12 +988,12 @@ private async Task CreateSecurityProviderFromNameAsync(Attesta switch (enrollmentType) { case EnrollmentType.Individual: - certificate = Configuration.Provisioning.GetIndividualEnrollmentCertificate(); + certificate = TestConfiguration.Provisioning.GetIndividualEnrollmentCertificate(); break; case EnrollmentType.Group: - certificate = Configuration.Provisioning.GetGroupEnrollmentCertificate(); - collection = Configuration.Provisioning.GetGroupEnrollmentChain(); + certificate = TestConfiguration.Provisioning.GetGroupEnrollmentCertificate(); + collection = TestConfiguration.Provisioning.GetGroupEnrollmentChain(); break; default: diff --git a/e2e/test/provisioning/ProvisioningServiceClientE2ETests.cs b/e2e/test/provisioning/ProvisioningServiceClientE2ETests.cs index 6ec0b7eca2..79a540cb82 100644 --- a/e2e/test/provisioning/ProvisioningServiceClientE2ETests.cs +++ b/e2e/test/provisioning/ProvisioningServiceClientE2ETests.cs @@ -19,7 +19,7 @@ namespace Microsoft.Azure.Devices.E2ETests.Provisioning [TestCategory("DPS")] public class ProvisioningServiceClientE2ETests : E2EMsTestBase { - private static readonly string s_proxyServerAddress = Configuration.IoTHub.ProxyServerAddress; + private static readonly string s_proxyServerAddress = TestConfiguration.IoTHub.ProxyServerAddress; private static readonly string s_devicePrefix = $"E2E_{nameof(ProvisioningServiceClientE2ETests)}_"; #pragma warning disable CA1823 @@ -114,7 +114,7 @@ public async Task ProvisioningServiceClient_GetEnrollmentGroupAttestation_Symmet public async Task ProvisioningServiceClient_GetIndividualEnrollmentAttestation(AttestationMechanismType attestationType) { - ProvisioningServiceClient provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); + ProvisioningServiceClient provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(TestConfiguration.Provisioning.ConnectionString); IndividualEnrollment individualEnrollment = await CreateIndividualEnrollment(provisioningServiceClient, attestationType, null, AllocationPolicy.Static, null, null, null); AttestationMechanism attestationMechanism = await provisioningServiceClient.GetIndividualEnrollmentAttestationAsync(individualEnrollment.RegistrationId); @@ -144,7 +144,7 @@ public async Task ProvisioningServiceClient_GetIndividualEnrollmentAttestation(A public async Task ProvisioningServiceClient_GetEnrollmentGroupAttestation(AttestationMechanismType attestationType) { - ProvisioningServiceClient provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); + ProvisioningServiceClient provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(TestConfiguration.Provisioning.ConnectionString); string groupId = AttestationTypeToString(attestationType) + "-" + Guid.NewGuid(); EnrollmentGroup enrollmentGroup = await CreateEnrollmentGroup(provisioningServiceClient, attestationType, groupId, null, AllocationPolicy.Static, null, null, null); @@ -268,7 +268,7 @@ public static async Task CreateIndividualEnrollment(Provis using (var tpmSim = new SecurityProviderTpmSimulator(registrationId)) { string base64Ek = Convert.ToBase64String(tpmSim.GetEndorsementKey()); - var provisioningService = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); + var provisioningService = ProvisioningServiceClient.CreateFromConnectionString(TestConfiguration.Provisioning.ConnectionString); individualEnrollment = new IndividualEnrollment(registrationId, new TpmAttestation(base64Ek)) { Capabilities = capabilities, @@ -347,7 +347,7 @@ public static ProvisioningServiceClient CreateProvisioningService(string proxySe transportSettings.Proxy = new WebProxy(proxyServerAddress); } - return ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString, transportSettings); + return ProvisioningServiceClient.CreateFromConnectionString(TestConfiguration.Provisioning.ConnectionString, transportSettings); } /// diff --git a/e2e/test/provisioning/ReprovisioningE2ETests.cs b/e2e/test/provisioning/ReprovisioningE2ETests.cs index 60247d4123..c281e88f34 100644 --- a/e2e/test/provisioning/ReprovisioningE2ETests.cs +++ b/e2e/test/provisioning/ReprovisioningE2ETests.cs @@ -28,8 +28,8 @@ namespace Microsoft.Azure.Devices.E2ETests.Provisioning public class ReprovisioningE2ETests : E2EMsTestBase { private const int PassingTimeoutMiliseconds = 10 * 60 * 1000; - private static readonly string s_globalDeviceEndpoint = Configuration.Provisioning.GlobalDeviceEndpoint; - private static string s_proxyServerAddress = Configuration.IoTHub.ProxyServerAddress; + private static readonly string s_globalDeviceEndpoint = TestConfiguration.Provisioning.GlobalDeviceEndpoint; + private static string s_proxyServerAddress = TestConfiguration.IoTHub.ProxyServerAddress; private readonly string _devicePrefix = $"E2E_{nameof(ProvisioningE2ETests)}_"; #pragma warning disable CA1823 @@ -211,8 +211,8 @@ public async Task ProvisioningDeviceClient_ReprovisioningBlockingWorks_MqttWs_Sy /// private async Task ProvisioningDeviceClient_ReprovisioningFlow_ResetTwin(Client.TransportType transportProtocol, AttestationMechanismType attestationType, EnrollmentType enrollmentType, bool setCustomProxy, string customServerProxy = null) { - var connectionString = IotHubConnectionStringBuilder.Create(Configuration.IoTHub.ConnectionString); - ICollection iotHubsToStartAt = new List() { Configuration.Provisioning.FarAwayIotHubHostName }; + var connectionString = IotHubConnectionStringBuilder.Create(TestConfiguration.IoTHub.ConnectionString); + ICollection iotHubsToStartAt = new List() { TestConfiguration.Provisioning.FarAwayIotHubHostName }; ICollection iotHubsToReprovisionTo = new List() { connectionString.HostName }; await ProvisioningDeviceClient_ReprovisioningFlow(transportProtocol, attestationType, enrollmentType, setCustomProxy, new ReprovisionPolicy { MigrateDeviceData = false, UpdateHubAssignment = true }, AllocationPolicy.Hashed, null, iotHubsToStartAt, iotHubsToReprovisionTo, customServerProxy).ConfigureAwait(false); } @@ -223,8 +223,8 @@ private async Task ProvisioningDeviceClient_ReprovisioningFlow_ResetTwin(Client. /// private async Task ProvisioningDeviceClient_ReprovisioningFlow_KeepTwin(Client.TransportType transportProtocol, AttestationMechanismType attestationType, EnrollmentType enrollmentType, bool setCustomProxy, string customServerProxy = null) { - var connectionString = IotHubConnectionStringBuilder.Create(Configuration.IoTHub.ConnectionString); - ICollection iotHubsToStartAt = new List() { Configuration.Provisioning.FarAwayIotHubHostName }; + var connectionString = IotHubConnectionStringBuilder.Create(TestConfiguration.IoTHub.ConnectionString); + ICollection iotHubsToStartAt = new List() { TestConfiguration.Provisioning.FarAwayIotHubHostName }; ICollection iotHubsToReprovisionTo = new List() { connectionString.HostName }; await ProvisioningDeviceClient_ReprovisioningFlow(transportProtocol, attestationType, enrollmentType, setCustomProxy, new ReprovisionPolicy { MigrateDeviceData = true, UpdateHubAssignment = true }, AllocationPolicy.Hashed, null, iotHubsToStartAt, iotHubsToReprovisionTo, customServerProxy).ConfigureAwait(false); } @@ -234,8 +234,8 @@ private async Task ProvisioningDeviceClient_ReprovisioningFlow_KeepTwin(Client.T /// private async Task ProvisioningDeviceClient_ReprovisioningFlow_DoNotReprovision(Client.TransportType transportProtocol, AttestationMechanismType attestationType, EnrollmentType enrollmentType, bool setCustomProxy, string customServerProxy = null) { - var connectionString = IotHubConnectionStringBuilder.Create(Configuration.IoTHub.ConnectionString); - ICollection iotHubsToStartAt = new List() { Configuration.Provisioning.FarAwayIotHubHostName }; + var connectionString = IotHubConnectionStringBuilder.Create(TestConfiguration.IoTHub.ConnectionString); + ICollection iotHubsToStartAt = new List() { TestConfiguration.Provisioning.FarAwayIotHubHostName }; ICollection iotHubsToReprovisionTo = new List() { connectionString.HostName }; await ProvisioningDeviceClient_ReprovisioningFlow(transportProtocol, attestationType, enrollmentType, setCustomProxy, new ReprovisionPolicy { MigrateDeviceData = false, UpdateHubAssignment = false }, AllocationPolicy.Hashed, null, iotHubsToStartAt, iotHubsToReprovisionTo, customServerProxy).ConfigureAwait(false); } @@ -283,7 +283,7 @@ public async Task ProvisioningDeviceClient_ReprovisioningFlow( ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create( s_globalDeviceEndpoint, - Configuration.Provisioning.IdScope, + TestConfiguration.Provisioning.IdScope, security, transport); using var cts = new CancellationTokenSource(PassingTimeoutMiliseconds); @@ -348,7 +348,7 @@ private async Task CreateSecurityProviderFromName(AttestationM { _verboseLog.WriteLine($"{nameof(CreateSecurityProviderFromName)}({attestationType})"); - var provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); + var provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(TestConfiguration.Provisioning.ConnectionString); switch (attestationType) { @@ -358,7 +358,7 @@ private async Task CreateSecurityProviderFromName(AttestationM string base64Ek = Convert.ToBase64String(tpmSim.GetEndorsementKey()); - var provisioningService = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); + var provisioningService = ProvisioningServiceClient.CreateFromConnectionString(TestConfiguration.Provisioning.ConnectionString); Logger.Trace($"Getting enrollment: RegistrationID = {registrationId}"); IndividualEnrollment individualEnrollment = new IndividualEnrollment(registrationId, new TpmAttestation(base64Ek)) { AllocationPolicy = allocationPolicy, ReprovisionPolicy = reprovisionPolicy, IotHubs = iothubs, CustomAllocationDefinition = customAllocationDefinition, Capabilities = capabilities }; @@ -377,12 +377,12 @@ private async Task CreateSecurityProviderFromName(AttestationM switch (enrollmentType) { case EnrollmentType.Individual: - certificate = Configuration.Provisioning.GetIndividualEnrollmentCertificate(); + certificate = TestConfiguration.Provisioning.GetIndividualEnrollmentCertificate(); break; case EnrollmentType.Group: - certificate = Configuration.Provisioning.GetGroupEnrollmentCertificate(); - collection = Configuration.Provisioning.GetGroupEnrollmentChain(); + certificate = TestConfiguration.Provisioning.GetGroupEnrollmentCertificate(); + collection = TestConfiguration.Provisioning.GetGroupEnrollmentChain(); break; default: @@ -501,7 +501,7 @@ private void ConfirmDeviceInExpectedHub(DeviceRegistrationResult result, Reprovi if (allocationPolicy == AllocationPolicy.GeoLatency) { - Assert.AreNotEqual(result.AssignedHub, Configuration.Provisioning.FarAwayIotHubHostName); + Assert.AreNotEqual(result.AssignedHub, TestConfiguration.Provisioning.FarAwayIotHubHostName); } } else diff --git a/iothub/device/src/Transport/AmqpIot/AmqpIotExceptionAdapter.cs b/iothub/device/src/Transport/AmqpIot/AmqpIotExceptionAdapter.cs index fff5e23334..57babf2e13 100644 --- a/iothub/device/src/Transport/AmqpIot/AmqpIotExceptionAdapter.cs +++ b/iothub/device/src/Transport/AmqpIot/AmqpIotExceptionAdapter.cs @@ -15,17 +15,26 @@ internal static Exception ConvertToIotHubException(Exception exception) { return new IotHubCommunicationException(exception.Message, exception); } - else if (exception is UnauthorizedAccessException) + + if (exception is UnauthorizedAccessException) { return new UnauthorizedException(exception.Message, exception); } - else + + if (exception is OperationCanceledException + && exception.InnerException is AmqpException innerAmqpException + && innerAmqpException != null) { - var amqpException = exception as AmqpException; - return amqpException == null - ? exception - : AmqpIotErrorAdapter.ToIotHubClientContract(amqpException); + return AmqpIotErrorAdapter.ToIotHubClientContract(innerAmqpException); } + + if (exception is AmqpException amqpException + && amqpException != null) + { + return AmqpIotErrorAdapter.ToIotHubClientContract(amqpException); + } + + return exception; } internal static Exception ConvertToIotHubException(Exception exception, AmqpObject source) diff --git a/iothub/device/src/Transport/Mqtt/MqttTransportSettings.cs b/iothub/device/src/Transport/Mqtt/MqttTransportSettings.cs index a29e9cc92a..99fe30cbd9 100644 --- a/iothub/device/src/Transport/Mqtt/MqttTransportSettings.cs +++ b/iothub/device/src/Transport/Mqtt/MqttTransportSettings.cs @@ -26,7 +26,10 @@ public class MqttTransportSettings : ITransportSettings private const int DefaultMaxPendingInboundMessages = 50; private const QualityOfService DefaultPublishToServerQoS = QualityOfService.AtLeastOnce; private const QualityOfService DefaultReceivingQoS = QualityOfService.AtLeastOnce; - private static readonly TimeSpan s_defaultConnectArrivalTimeout = TimeSpan.FromSeconds(10); + + // The CONNACK timeout has been chosen to be 60 seconds to be in alignment with the service implemented timeout for processing connection requests. + private static readonly TimeSpan s_defaultConnectArrivalTimeout = TimeSpan.FromSeconds(60); + private static readonly TimeSpan s_defaultDeviceReceiveAckTimeout = TimeSpan.FromSeconds(300); private static readonly TimeSpan s_defaultReceiveTimeout = TimeSpan.FromMinutes(1); @@ -157,8 +160,15 @@ public bool CertificateRevocationCheck /// /// The time to wait for receiving an acknowledgment for a CONNECT packet. - /// The default is 10 seconds. + /// The default is 60 seconds. /// + /// + /// In the event that IoT Hub receives burst traffic, it will implement traffic shaping in order to process the incoming requests. + /// In such cases, during client connection the CONNECT requests can have a delay in being acknowledged and processed by IoT Hub. + /// The ConnectArrivalTimeout governs the duration the client will wait for a CONNACK packet before disconnecting and reopening the connection. + /// To know more about IoT Hub's throttling limits and traffic shaping feature, see + /// . + /// public TimeSpan ConnectArrivalTimeout { get; set; } /// @@ -239,4 +249,4 @@ public TransportType GetTransportType() /// internal string AuthenticationChain { get; set; } } -} \ No newline at end of file +} diff --git a/iothub/device/src/Transport/ProtocolRoutingDelegatingHandler.cs b/iothub/device/src/Transport/ProtocolRoutingDelegatingHandler.cs index d0b624cd8e..20636f8ef3 100644 --- a/iothub/device/src/Transport/ProtocolRoutingDelegatingHandler.cs +++ b/iothub/device/src/Transport/ProtocolRoutingDelegatingHandler.cs @@ -10,8 +10,8 @@ namespace Microsoft.Azure.Devices.Client.Transport { /// - /// Transport handler router. - /// Tries to open the connection in the protocol order it was set. + /// Transport handler router. + /// Tries to open the connection in the protocol order it was set. /// If fails tries to open the next one, etc. /// internal class ProtocolRoutingDelegatingHandler : DefaultDelegatingHandler @@ -22,6 +22,7 @@ internal class ProtocolRoutingDelegatingHandler : DefaultDelegatingHandler /// After we've verified that we could open the transport for any operation, we will stop attempting others in the list. /// private bool _transportSelectionComplete; + private int _nextTransportIndex; private SemaphoreSlim _handlerLock = new SemaphoreSlim(1, 1); diff --git a/iothub/service/src/Device.cs b/iothub/service/src/Device.cs index 610416e563..b5b3c7ccfd 100644 --- a/iothub/service/src/Device.cs +++ b/iothub/service/src/Device.cs @@ -114,7 +114,7 @@ public Device(string id) /// relationship. /// /// - /// For leaf devices, the value to set a parent edge device can be retrieved from the parent edge device's property. + /// 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 . /// diff --git a/iothub/service/src/DigitalTwin/Authentication/DigitalTwinTokenCredential.cs b/iothub/service/src/DigitalTwin/Authentication/DigitalTwinTokenCredential.cs index c5ce746e3a..3b0bc31fe7 100644 --- a/iothub/service/src/DigitalTwin/Authentication/DigitalTwinTokenCredential.cs +++ b/iothub/service/src/DigitalTwin/Authentication/DigitalTwinTokenCredential.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; using System.Collections.Generic; -using System.Linq; using System.Text; using System.Threading; using Azure.Core; @@ -19,14 +18,12 @@ namespace Microsoft.Azure.Devices.DigitalTwin.Authentication internal class DigitalTwinTokenCredential : DigitalTwinServiceClientCredentials { private readonly object _tokenLock = new object(); - private readonly string[] _tokenCredentialAuthenticationScopes; private AccessToken? _cachedAccessToken; private TokenCredential _credential; - public DigitalTwinTokenCredential(TokenCredential credential, IReadOnlyList tokenCredentialAuthenticationScopes) + public DigitalTwinTokenCredential(TokenCredential credential) { _credential = credential; - _tokenCredentialAuthenticationScopes = tokenCredentialAuthenticationScopes.ToArray(); } public override string GetAuthorizationHeader() @@ -38,7 +35,7 @@ public override string GetAuthorizationHeader() || TokenHelper.IsCloseToExpiry(_cachedAccessToken.Value.ExpiresOn)) { _cachedAccessToken = _credential.GetToken( - new TokenRequestContext(_tokenCredentialAuthenticationScopes), + new TokenRequestContext(CommonConstants.IotHubAadTokenScopes), new CancellationToken()); } } diff --git a/iothub/service/src/DigitalTwin/DigitalTwinClient.cs b/iothub/service/src/DigitalTwin/DigitalTwinClient.cs index 0d08b7b06e..a1289d8719 100644 --- a/iothub/service/src/DigitalTwin/DigitalTwinClient.cs +++ b/iothub/service/src/DigitalTwin/DigitalTwinClient.cs @@ -105,56 +105,23 @@ public static DigitalTwinClient CreateFromConnectionString(string connectionStri /// An instance of . /// /// For more information on configuring IoT hub with Azure Active Directory, see - /// This constructor internally uses , which is used for - /// any public or private cloud other than Azure US Government cloud. - /// For Azure US Government cloud users, use the constructor with and set the - /// to . /// public static DigitalTwinClient Create( string hostName, TokenCredential credential, params DelegatingHandler[] handlers) - { - return Create(hostName, credential, null, handlers); - } - - /// - /// Creates an instance of . - /// - /// IoT hub host name. - /// Azure Active Directory credentials to authenticate with IoT hub. See - /// Options that allow configuration of the DigitalTwinClient instance during initialization. - /// The delegating handlers to add to the http client pipeline. You can add handlers for tracing, implementing a retry strategy, routing requests through a proxy, etc. - /// An instance of . - /// - /// For more information on configuring IoT hub with Azure Active Directory, see - /// This constructor sets the default for to - /// , which is used for any public or private cloud other than Azure US Government cloud. - /// For Azure US Government cloud users, set the - /// to . - /// - public static DigitalTwinClient Create( - string hostName, - TokenCredential credential, - DigitalTwinClientOptions options, - params DelegatingHandler[] handlers) { if (string.IsNullOrEmpty(hostName)) { - throw new ArgumentNullException(nameof(hostName), "Parameter cannot be null or empty."); + throw new ArgumentNullException($"{nameof(hostName)}, Parameter cannot be null or empty"); } if (credential == null) { - throw new ArgumentNullException(nameof(credential)); - } - - if (options == null) - { - options = new DigitalTwinClientOptions(); + throw new ArgumentNullException($"{nameof(credential)}, Parameter cannot be null"); } - var tokenCredential = new DigitalTwinTokenCredential(credential, options.TokenCredentialAuthenticationScopes); + var tokenCredential = new DigitalTwinTokenCredential(credential); return new DigitalTwinClient(hostName, tokenCredential, handlers); } @@ -172,12 +139,12 @@ public static DigitalTwinClient Create( { if (string.IsNullOrEmpty(hostName)) { - throw new ArgumentNullException(nameof(hostName), "Parameter cannot be null or empty."); + throw new ArgumentNullException($"{nameof(hostName)}, Parameter cannot be null or empty"); } if (credential == null) { - throw new ArgumentNullException(nameof(credential)); + throw new ArgumentNullException($"{nameof(credential)}, Parameter cannot be null"); } var sasCredential = new DigitalTwinSasCredential(credential); diff --git a/iothub/service/src/DigitalTwin/DigitalTwinClientOptions.cs b/iothub/service/src/DigitalTwin/DigitalTwinClientOptions.cs deleted file mode 100644 index 096bda6000..0000000000 --- a/iothub/service/src/DigitalTwin/DigitalTwinClientOptions.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Microsoft.Azure.Devices -{ - /// - /// Options that allow configuration of the DigitalTwinClient instance during initialization. - /// - public class DigitalTwinClientOptions - { - /// - /// The authentication scopes to use when requesting access tokens from Azure Active Directory for authenticating with the - /// IoT Hub. - /// - /// - /// This value defaults , which is used for - /// any public or private cloud other than Azure US Government cloud. - /// For Azure US Government cloud users, this value must be set to . - /// - public IReadOnlyList TokenCredentialAuthenticationScopes { get; set; } = IotHubAuthenticationScopes.DefaultAuthenticationScopes; - } -} diff --git a/iothub/service/src/ExportImportDevice.cs b/iothub/service/src/ExportImportDevice.cs index 8d8ddb7e42..eacfc12b6d 100644 --- a/iothub/service/src/ExportImportDevice.cs +++ b/iothub/service/src/ExportImportDevice.cs @@ -5,13 +5,14 @@ // --------------------------------------------------------------- using System; +using System.Diagnostics.CodeAnalysis; using Microsoft.Azure.Devices.Shared; using Newtonsoft.Json; namespace Microsoft.Azure.Devices { /// - /// Contains device properties specified during export/import operation + /// Contains device properties specified during export/import job operation. /// public sealed class ExportImportDevice { @@ -21,7 +22,7 @@ public sealed class ExportImportDevice /// /// Property container /// - [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 { /// @@ -38,14 +39,14 @@ public sealed class PropertyContainer } /// - /// Create an ExportImportDevice + /// Create an ExportImportDevice. /// public ExportImportDevice() { } /// - /// Create an ExportImportDevice + /// Create an ExportImportDevice. /// /// Device properties /// Identifies the behavior when merging a device to the registry during import actions. @@ -66,13 +67,13 @@ public ExportImportDevice(Device device, ImportMode importmode) } /// - /// Id of the device + /// Id of the device. /// [JsonProperty(PropertyName = "id", Required = Required.Always)] public string Id { get; set; } /// - /// Module Id for the object + /// Module Id for the object. /// [JsonProperty(PropertyName = "moduleId", NullValueHandling = NullValueHandling.Ignore)] public string ModuleId { get; set; } @@ -88,31 +89,31 @@ public string ETag } /// - /// ImportMode of the device + /// Import mode of the device. /// [JsonProperty(PropertyName = "importMode", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] public ImportMode ImportMode { get; set; } /// - /// Status of the device + /// Status of the device. /// [JsonProperty(PropertyName = "status", Required = Required.Always)] public DeviceStatus Status { get; set; } /// - /// StatusReason of the device + /// Status reason of the device. /// [JsonProperty(PropertyName = "statusReason", NullValueHandling = NullValueHandling.Ignore)] public string StatusReason { get; set; } /// - /// AuthenticationMechanism of the device + /// Authentication mechanism of the device. /// [JsonProperty(PropertyName = "authentication")] public AuthenticationMechanism Authentication { get; set; } /// - /// string representing a Twin ETag for the entity, as per RFC7232. + /// String representing a Twin ETag for the entity, as per RFC7232. /// [JsonProperty(PropertyName = "twinETag", NullValueHandling = NullValueHandling.Ignore)] public string TwinETag @@ -128,17 +129,29 @@ public string TwinETag public TwinCollection Tags { get; set; } /// - /// Desired and Reported property bags + /// Desired and reported property bags /// [JsonProperty(PropertyName = "properties", NullValueHandling = NullValueHandling.Ignore)] public PropertyContainer Properties { get; set; } /// - /// Status of Capabilities enabled on the device + /// Status of capabilities enabled on the device /// [JsonProperty(PropertyName = "capabilities", NullValueHandling = NullValueHandling.Ignore)] public DeviceCapabilities Capabilities { get; set; } + /// + /// The scope of the device. For edge devices, this is auto-generated and immutable. For leaf devices, set this to create child/parent + /// relationship. + /// + /// + /// 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 . + /// + [JsonProperty(PropertyName = "deviceScope", NullValueHandling = NullValueHandling.Include)] + public string DeviceScope { get; set; } + private static string SanitizeETag(string eTag) { if (!string.IsNullOrWhiteSpace(eTag)) diff --git a/iothub/service/src/IotHubAuthenticationScopes.cs b/iothub/service/src/IotHubAuthenticationScopes.cs deleted file mode 100644 index 236c53fd59..0000000000 --- a/iothub/service/src/IotHubAuthenticationScopes.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Microsoft.Azure.Devices -{ - /// - /// This class contains the most commonly used Azure Active Directory token audience scopes. They should be used as - /// inputs when setting the authentication scopes in the client options classes. - /// - public static class IotHubAuthenticationScopes - { - /// - /// The default value for all client options. This value should be used for any public or private cloud other than Azure US Government cloud. - /// - public static readonly IReadOnlyList DefaultAuthenticationScopes = new List { "https://iothubs.azure.net/.default" }; - - /// - /// This value should be used for Azure US Government cloud. - /// - public static readonly IReadOnlyList AzureGovernmentAuthenticationScopes = new List { "https://iothubs.azure.us/.default" }; - } -} diff --git a/iothub/service/src/IotHubTokenCredentialProperties.cs b/iothub/service/src/IotHubTokenCredentialProperties.cs index abf3b02dd4..3591a66038 100644 --- a/iothub/service/src/IotHubTokenCredentialProperties.cs +++ b/iothub/service/src/IotHubTokenCredentialProperties.cs @@ -7,7 +7,6 @@ using Microsoft.Azure.Amqp; using System.Threading; using Microsoft.Azure.Devices.Common; -using System.Linq; #if !NET451 @@ -25,7 +24,6 @@ internal class IotHubTokenCrendentialProperties { #if !NET451 private const string _tokenType = "Bearer"; - private readonly string[] _tokenCredentialAuthenticationScopes; private readonly TokenCredential _credential; private readonly object _tokenLock = new object(); private AccessToken? _cachedAccessToken; @@ -39,10 +37,9 @@ public IotHubTokenCrendentialProperties() } #else - public IotHubTokenCrendentialProperties(string hostName, TokenCredential credential, IReadOnlyList tokenCredentialAuthenticationScopes) : base(hostName) + public IotHubTokenCrendentialProperties(string hostName, TokenCredential credential) : base(hostName) { _credential = credential; - _tokenCredentialAuthenticationScopes = tokenCredentialAuthenticationScopes.ToArray(); } #endif @@ -61,7 +58,7 @@ public override string GetAuthorizationHeader() || TokenHelper.IsCloseToExpiry(_cachedAccessToken.Value.ExpiresOn)) { _cachedAccessToken = _credential.GetToken( - new TokenRequestContext(_tokenCredentialAuthenticationScopes), + new TokenRequestContext(CommonConstants.IotHubAadTokenScopes), new CancellationToken()); } } @@ -82,7 +79,7 @@ public async override Task GetTokenAsync(Uri namespaceAddress, string #else AccessToken token = await _credential.GetTokenAsync( - new TokenRequestContext(_tokenCredentialAuthenticationScopes), + new TokenRequestContext(CommonConstants.IotHubAadTokenScopes), new CancellationToken()).ConfigureAwait(false); return new CbsToken( $"{_tokenType} {token.Token}", diff --git a/iothub/service/src/JobClient/JobClient.cs b/iothub/service/src/JobClient/JobClient.cs index d37c4d0b13..c5dca84b67 100644 --- a/iothub/service/src/JobClient/JobClient.cs +++ b/iothub/service/src/JobClient/JobClient.cs @@ -56,24 +56,18 @@ public static JobClient CreateFromConnectionString(string connectionString, Http /// IoT hub host name. /// Azure Active Directory credentials to authenticate with IoT hub. See /// The HTTP transport settings. - /// Options that allow configuration of the JobClient instance during initialization. /// An instance of . /// /// For more information on configuring IoT hub with Azure Active Directory, see - /// This constructor sets the default for to - /// , which is used for any public or private cloud other than Azure US Government cloud. - /// For Azure US Government cloud users, set the - /// to . /// public static JobClient Create( string hostName, TokenCredential credential, - HttpTransportSettings transportSettings = default, - JobClientOptions options = default) + HttpTransportSettings transportSettings = default) { if (string.IsNullOrEmpty(hostName)) { - throw new ArgumentNullException(nameof(hostName), "Parameter cannot be null or empty."); + throw new ArgumentNullException(nameof(hostName)); } if (credential == null) @@ -81,16 +75,7 @@ public static JobClient Create( throw new ArgumentNullException(nameof(credential)); } - if (options == null) - { - options = new JobClientOptions(); - } - - var tokenCredentialProperties = new IotHubTokenCrendentialProperties( - hostName, - credential, - options.TokenCredentialAuthenticationScopes); - + var tokenCredentialProperties = new IotHubTokenCrendentialProperties(hostName, credential); return new HttpJobClient(tokenCredentialProperties, transportSettings ?? new HttpTransportSettings()); } @@ -108,7 +93,7 @@ public static JobClient Create( { if (string.IsNullOrEmpty(hostName)) { - throw new ArgumentNullException(nameof(hostName), "Parameter cannot be null or empty."); + throw new ArgumentNullException(nameof(hostName)); } if (credential == null) diff --git a/iothub/service/src/JobClient/JobClientOptions.cs b/iothub/service/src/JobClient/JobClientOptions.cs deleted file mode 100644 index 0c4d5dcdbb..0000000000 --- a/iothub/service/src/JobClient/JobClientOptions.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Microsoft.Azure.Devices -{ - /// - /// Options that allow configuration of the JobClient instance during initialization. - /// - public class JobClientOptions - { - /// - /// The authentication scopes to use when requesting access tokens from Azure Active Directory for authenticating with the - /// IoT Hub. - /// - /// - /// This value defaults , which is used for - /// any public or private cloud other than Azure US Government cloud. - /// For Azure US Government cloud users, this value must be set to . - /// - public IReadOnlyList TokenCredentialAuthenticationScopes { get; set; } = IotHubAuthenticationScopes.DefaultAuthenticationScopes; - } -} diff --git a/iothub/service/src/RegistryManager.cs b/iothub/service/src/RegistryManager.cs index 73035e205d..ef7ce5c51b 100644 --- a/iothub/service/src/RegistryManager.cs +++ b/iothub/service/src/RegistryManager.cs @@ -62,41 +62,26 @@ public static RegistryManager CreateFromConnectionString(string connectionString /// IoT hub host name. /// Azure Active Directory credentials to authenticate with IoT hub. See /// The HTTP transport settings. - /// Options that allow configuration of the RegistryManager instance during initialization. /// An instance of . /// /// For more information on configuring IoT hub with Azure Active Directory, see - /// This constructor sets the default for to - /// , which is used for any public or private cloud other than Azure US Government cloud. - /// For Azure US Government cloud users, set the - /// to . /// public static RegistryManager Create( string hostName, TokenCredential credential, - HttpTransportSettings transportSettings = default, - RegistryManagerOptions options = default) + HttpTransportSettings transportSettings = default) { if (string.IsNullOrEmpty(hostName)) { - throw new ArgumentNullException(nameof(hostName), "Parameter cannot be null or empty."); + throw new ArgumentNullException($"{nameof(hostName)}, Parameter cannot be null or empty"); } if (credential == null) { - throw new ArgumentNullException(nameof(credential)); + throw new ArgumentNullException($"{nameof(credential)}, Parameter cannot be null"); } - if (options == null) - { - options = new RegistryManagerOptions(); - } - - var tokenCredentialProperties = new IotHubTokenCrendentialProperties( - hostName, - credential, - options.TokenCredentialAuthenticationScopes); - + var tokenCredentialProperties = new IotHubTokenCrendentialProperties(hostName, credential); return new HttpRegistryManager(tokenCredentialProperties, transportSettings ?? new HttpTransportSettings()); } @@ -114,12 +99,12 @@ public static RegistryManager Create( { if (string.IsNullOrEmpty(hostName)) { - throw new ArgumentNullException(nameof(hostName), "Parameter cannot be null or empty."); + throw new ArgumentNullException($"{nameof(hostName)}, Parameter cannot be null or empty"); } if (credential == null) { - throw new ArgumentNullException(nameof(credential)); + throw new ArgumentNullException($"{nameof(credential)}, Parameter cannot be null"); } var sasCredentialProperties = new IotHubSasCredentialProperties(hostName, credential); diff --git a/iothub/service/src/RegistryManagerOptions.cs b/iothub/service/src/RegistryManagerOptions.cs deleted file mode 100644 index 883aad2d1e..0000000000 --- a/iothub/service/src/RegistryManagerOptions.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Microsoft.Azure.Devices -{ - /// - /// Options that allow configuration of the RegistryManager instance during initialization. - /// - public class RegistryManagerOptions - { - /// - /// The authentication scopes to use when requesting access tokens from Azure Active Directory for authenticating with the - /// IoT Hub. - /// - /// - /// This value defaults , which is used for - /// any public or private cloud other than Azure US Government cloud. - /// For Azure US Government cloud users, this value must be set to . - /// - public IReadOnlyList TokenCredentialAuthenticationScopes { get; set; } = IotHubAuthenticationScopes.DefaultAuthenticationScopes; - } -} diff --git a/iothub/service/src/ServiceClient.cs b/iothub/service/src/ServiceClient.cs index 182159d996..bd2649b1a4 100644 --- a/iothub/service/src/ServiceClient.cs +++ b/iothub/service/src/ServiceClient.cs @@ -73,10 +73,6 @@ public static ServiceClient CreateFromConnectionString(string connectionString, /// An instance of . /// /// For more information on configuring IoT hub with Azure Active Directory, see - /// This constructor sets the default for to - /// , which is used for any public or private cloud other than Azure US Government cloud. - /// For Azure US Government cloud users, set the - /// to . /// public static ServiceClient Create( string hostName, @@ -87,24 +83,15 @@ public static ServiceClient Create( { if (string.IsNullOrEmpty(hostName)) { - throw new ArgumentNullException(nameof(hostName), "Parameter cannot be null or empty."); + throw new ArgumentNullException($"{nameof(hostName)}, Parameter cannot be null or empty"); } if (credential == null) { - throw new ArgumentNullException(nameof(credential)); + throw new ArgumentNullException($"{nameof(credential)}, Parameter cannot be null"); } - if (options == null) - { - options = new ServiceClientOptions(); - } - - var tokenCredentialProperties = new IotHubTokenCrendentialProperties( - hostName, - credential, - options.TokenCredentialAuthenticationScopes); - + var tokenCredentialProperties = new IotHubTokenCrendentialProperties(hostName, credential); bool useWebSocketOnly = transportType == TransportType.Amqp_WebSocket_Only; return new AmqpServiceClient( @@ -132,12 +119,12 @@ public static ServiceClient Create( { if (string.IsNullOrEmpty(hostName)) { - throw new ArgumentNullException(nameof(hostName), "Parameter cannot be null or empty."); + throw new ArgumentNullException($"{nameof(hostName)}, Parameter cannot be null or empty"); } if (credential == null) { - throw new ArgumentNullException(nameof(credential)); + throw new ArgumentNullException($"{nameof(credential)}, Parameter cannot be null"); } var sasCredentialProperties = new IotHubSasCredentialProperties(hostName, credential); diff --git a/iothub/service/src/ServiceClientOptions.cs b/iothub/service/src/ServiceClientOptions.cs index cca7694f49..c705b23b0d 100644 --- a/iothub/service/src/ServiceClientOptions.cs +++ b/iothub/service/src/ServiceClientOptions.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System.Collections.Generic; using Microsoft.Azure.Devices.Shared; namespace Microsoft.Azure.Devices @@ -16,16 +15,5 @@ public class ServiceClientOptions /// The default behavior is that is set only by the user. /// public SdkAssignsMessageId SdkAssignsMessageId { get; set; } = SdkAssignsMessageId.Never; - - /// - /// The authentication scopes to use when requesting access tokens from Azure Active Directory for authenticating with the - /// IoT Hub. - /// - /// - /// This value defaults , which is used for - /// any public or private cloud other than Azure US Government cloud. - /// For Azure US Government cloud users, this value must be set to . - /// - public IReadOnlyList TokenCredentialAuthenticationScopes { get; set; } = IotHubAuthenticationScopes.DefaultAuthenticationScopes; } } diff --git a/provisioning/device/src/ProvisioningDeviceClient.cs b/provisioning/device/src/ProvisioningDeviceClient.cs index 3c7fbb3f66..1703ff729f 100644 --- a/provisioning/device/src/ProvisioningDeviceClient.cs +++ b/provisioning/device/src/ProvisioningDeviceClient.cs @@ -3,6 +3,7 @@ using Microsoft.Azure.Devices.Provisioning.Client.Transport; using Microsoft.Azure.Devices.Shared; +using System; using System.Threading; using System.Threading.Tasks; @@ -63,45 +64,79 @@ private ProvisioningDeviceClient( /// /// Registers the current device using the Device Provisioning Service and assigns it to an IoT Hub. /// + /// The maximum amount of time to allow this operation to run for before timing out. + /// + /// Due to the AMQP library used by this library uses not accepting cancellation tokens, this overload and + /// are the only overloads for this method that allow for a specified timeout to be respected in the middle of an AMQP operation such as opening + /// the AMQP connection. MQTT and HTTPS connections do not share that same limitation, though. + /// /// The registration result. - public Task RegisterAsync() + public Task RegisterAsync(TimeSpan timeout) { - return RegisterAsync(CancellationToken.None); + return RegisterAsync(null, timeout); } /// /// Registers the current device using the Device Provisioning Service and assigns it to an IoT Hub. /// - /// The optional additional data. + /// + /// The optional additional data that is passed through to the custom allocation policy webhook if + /// a custom allocation policy webhook is setup for this enrollment. + /// + /// The maximum amount of time to allow this operation to run for before timing out. + /// + /// Due to the AMQP library used by this library uses not accepting cancellation tokens, this overload and + /// are the only overloads for this method that allow for a specified timeout to be respected in the middle of an AMQP operation such as opening + /// the AMQP connection. MQTT and HTTPS connections do not share that same limitation, though. + /// /// The registration result. - public Task RegisterAsync(ProvisioningRegistrationAdditionalData data) + public Task RegisterAsync(ProvisioningRegistrationAdditionalData data, TimeSpan timeout) { - return RegisterAsync(data, CancellationToken.None); + Logging.RegisterAsync(this, _globalDeviceEndpoint, _idScope, _transport, _security); + + var request = new ProvisioningTransportRegisterMessage(_globalDeviceEndpoint, _idScope, _security, data?.JsonData) + { + ProductInfo = ProductInfo, + }; + + return _transport.RegisterAsync(request, timeout); } /// /// Registers the current device using the Device Provisioning Service and assigns it to an IoT Hub. /// /// The cancellation token. + /// + /// Due to the AMQP library used by this library uses not accepting cancellation tokens, the provided cancellation token will only be checked + /// for cancellation in between AMQP operations, and not during. In order to have a timeout for this operation that is checked during AMQP operations + /// (such as opening the connection), you must use instead. MQTT and HTTPS connections do not have the same + /// behavior as AMQP connections in this regard. MQTT and HTTPS connections will check this cancellation token for cancellation during their protocol level operations. + /// /// The registration result. - public Task RegisterAsync(CancellationToken cancellationToken) + public Task RegisterAsync(CancellationToken cancellationToken = default) { Logging.RegisterAsync(this, _globalDeviceEndpoint, _idScope, _transport, _security); - var request = new ProvisioningTransportRegisterMessage(_globalDeviceEndpoint, _idScope, _security) - { - ProductInfo = ProductInfo - }; - return _transport.RegisterAsync(request, cancellationToken); + return RegisterAsync(null, cancellationToken); } /// /// Registers the current device using the Device Provisioning Service and assigns it to an IoT Hub. /// - /// The custom content. + /// + /// The optional additional data that is passed through to the custom allocation policy webhook if + /// a custom allocation policy webhook is setup for this enrollment. + /// /// The cancellation token. + /// + /// Due to the AMQP library used by this library uses not accepting cancellation tokens, the provided cancellation token will only be checked + /// for cancellation in between AMQP operations, and not during. In order to have a timeout for this operation that is checked during AMQP operations + /// (such as opening the connection), you must use this overload instead. + /// MQTT and HTTPS connections do not have the same behavior as AMQP connections in this regard. MQTT and HTTPS connections will check this cancellation + /// token for cancellation during their protocol level operations. + /// /// The registration result. - public Task RegisterAsync(ProvisioningRegistrationAdditionalData data, CancellationToken cancellationToken) + public Task RegisterAsync(ProvisioningRegistrationAdditionalData data, CancellationToken cancellationToken = default) { Logging.RegisterAsync(this, _globalDeviceEndpoint, _idScope, _transport, _security); @@ -109,6 +144,7 @@ public Task RegisterAsync(ProvisioningRegistrationAddi { ProductInfo = ProductInfo, }; + return _transport.RegisterAsync(request, cancellationToken); } } diff --git a/provisioning/device/src/ProvisioningTransportHandler.cs b/provisioning/device/src/ProvisioningTransportHandler.cs index 8208932cad..1ddc085cfb 100644 --- a/provisioning/device/src/ProvisioningTransportHandler.cs +++ b/provisioning/device/src/ProvisioningTransportHandler.cs @@ -85,6 +85,19 @@ public virtual Task RegisterAsync( return _innerHandler.RegisterAsync(message, cancellationToken); } + /// + /// Registers a device described by the message. + /// + /// The provisioning message. + /// The maximum amount of time to allow this operation to run for before timing out. + /// The registration result. + public virtual Task RegisterAsync( + ProvisioningTransportRegisterMessage message, + TimeSpan timeout) + { + return _innerHandler.RegisterAsync(message, timeout); + } + /// /// Releases the unmanaged resources and disposes of the managed resources used by the invoker. /// diff --git a/provisioning/transport/amqp/src/ProvisioningTransportHandlerAmqp.cs b/provisioning/transport/amqp/src/ProvisioningTransportHandlerAmqp.cs index 740d4265a2..675412e509 100644 --- a/provisioning/transport/amqp/src/ProvisioningTransportHandlerAmqp.cs +++ b/provisioning/transport/amqp/src/ProvisioningTransportHandlerAmqp.cs @@ -22,7 +22,9 @@ namespace Microsoft.Azure.Devices.Provisioning.Client.Transport /// public class ProvisioningTransportHandlerAmqp : ProvisioningTransportHandler { - private static readonly TimeSpan s_defaultOperationPoolingInterval = TimeSpan.FromSeconds(2); + // This polling interval is the default time between checking if the device has reached a terminal state in its registration process + // DPS will generally send a retry-after header that overrides this default value though. + private static readonly TimeSpan s_defaultOperationPollingInterval = TimeSpan.FromSeconds(2); private static readonly TimeSpan s_timeoutConstant = TimeSpan.FromMinutes(1); /// @@ -43,6 +45,19 @@ public ProvisioningTransportHandlerAmqp( Proxy = DefaultWebProxySettings.Instance; } + /// + /// Registers a device described by the message. + /// + /// The provisioning message. + /// The maximum amount of time to allow this operation to run for before timing out. + /// The registration result. + public override async Task RegisterAsync( + ProvisioningTransportRegisterMessage message, + TimeSpan timeout) + { + return await RegisterAsync(message, timeout, CancellationToken.None).ConfigureAwait(false); + } + /// /// Registers a device described by the message. /// @@ -52,6 +67,22 @@ public ProvisioningTransportHandlerAmqp( public override async Task RegisterAsync( ProvisioningTransportRegisterMessage message, CancellationToken cancellationToken) + { + return await RegisterAsync(message, s_timeoutConstant, cancellationToken).ConfigureAwait(false); + } + + /// + /// Registers a device described by the message. Because the AMQP library does not accept cancellation tokens, the provided cancellation token + /// will only be checked for cancellation between AMQP operations. The timeout will be respected during the AMQP operations. + /// + /// The provisioning message. + /// The maximum amount of time to allow this operation to run for before timing out. + /// The cancellation token. + /// The registration result. + private async Task RegisterAsync( + ProvisioningTransportRegisterMessage message, + TimeSpan timeout, + CancellationToken cancellationToken) { if (Logging.IsEnabled) { @@ -106,19 +137,21 @@ public override async Task RegisterAsync( string linkEndpoint = $"{message.IdScope}/registrations/{registrationId}"; using AmqpClientConnection connection = authStrategy.CreateConnection(builder.Uri, message.IdScope); - await authStrategy.OpenConnectionAsync(connection, s_timeoutConstant, useWebSocket, Proxy, RemoteCertificateValidationCallback).ConfigureAwait(false); + await authStrategy.OpenConnectionAsync(connection, timeout, useWebSocket, Proxy, RemoteCertificateValidationCallback).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); await CreateLinksAsync( connection, linkEndpoint, - message.ProductInfo).ConfigureAwait(false); + message.ProductInfo, + timeout).ConfigureAwait(false); + cancellationToken.ThrowIfCancellationRequested(); string correlationId = Guid.NewGuid().ToString(); DeviceRegistration deviceRegistration = (message.Payload != null && message.Payload.Length > 0) ? new DeviceRegistration { Payload = new JRaw(message.Payload) } : null; - RegistrationOperationStatus operation = await RegisterDeviceAsync(connection, correlationId, deviceRegistration).ConfigureAwait(false); + RegistrationOperationStatus operation = await RegisterDeviceAsync(connection, correlationId, deviceRegistration, timeout).ConfigureAwait(false); // Poll with operationId until registration complete. int attempts = 0; @@ -131,7 +164,7 @@ await CreateLinksAsync( cancellationToken.ThrowIfCancellationRequested(); await Task.Delay( - operation.RetryAfter ?? RetryJitter.GenerateDelayWithJitterForRetry(s_defaultOperationPoolingInterval), + operation.RetryAfter ?? RetryJitter.GenerateDelayWithJitterForRetry(s_defaultOperationPollingInterval), cancellationToken).ConfigureAwait(false); try @@ -139,7 +172,8 @@ await Task.Delay( operation = await OperationStatusLookupAsync( connection, operationId, - correlationId).ConfigureAwait(false); + correlationId, + timeout).ConfigureAwait(false); } catch (ProvisioningTransportException e) when (e.ErrorDetails is ProvisioningErrorDetailsAmqp amqp && e.IsTransient) { @@ -154,7 +188,7 @@ await Task.Delay( authStrategy.SaveCredentials(operation); } - await connection.CloseAsync(s_timeoutConstant).ConfigureAwait(false); + await connection.CloseAsync(timeout).ConfigureAwait(false); return ConvertToProvisioningRegistrationResult(operation.RegistrationState); } @@ -179,30 +213,31 @@ await Task.Delay( } } - private static async Task CreateLinksAsync(AmqpClientConnection connection, string linkEndpoint, string productInfo) + private static async Task CreateLinksAsync(AmqpClientConnection connection, string linkEndpoint, string productInfo, TimeSpan timeout) { AmqpClientSession amqpDeviceSession = connection.CreateSession(); - await amqpDeviceSession.OpenAsync(s_timeoutConstant).ConfigureAwait(false); + await amqpDeviceSession.OpenAsync(timeout).ConfigureAwait(false); AmqpClientLink amqpReceivingLink = amqpDeviceSession.CreateReceivingLink(linkEndpoint); amqpReceivingLink.AddClientVersion(productInfo); amqpReceivingLink.AddApiVersion(ClientApiVersionHelper.ApiVersion); - await amqpReceivingLink.OpenAsync(s_timeoutConstant).ConfigureAwait(false); + await amqpReceivingLink.OpenAsync(timeout).ConfigureAwait(false); AmqpClientLink amqpSendingLink = amqpDeviceSession.CreateSendingLink(linkEndpoint); amqpSendingLink.AddClientVersion(productInfo); amqpSendingLink.AddApiVersion(ClientApiVersionHelper.ApiVersion); - await amqpSendingLink.OpenAsync(s_timeoutConstant).ConfigureAwait(false); + await amqpSendingLink.OpenAsync(timeout).ConfigureAwait(false); } private async Task RegisterDeviceAsync( AmqpClientConnection client, string correlationId, - DeviceRegistration deviceRegistration) + DeviceRegistration deviceRegistration, + TimeSpan timeout) { AmqpMessage amqpMessage = null; @@ -226,11 +261,11 @@ private async Task RegisterDeviceAsync( .SendMessageAsync( amqpMessage, new ArraySegment(Guid.NewGuid().ToByteArray()), - s_timeoutConstant) + timeout) .ConfigureAwait(false); ValidateOutcome(outcome); - AmqpMessage amqpResponse = await client.AmqpSession.ReceivingLink.ReceiveMessageAsync(s_timeoutConstant).ConfigureAwait(false); + AmqpMessage amqpResponse = await client.AmqpSession.ReceivingLink.ReceiveMessageAsync(timeout).ConfigureAwait(false); client.AmqpSession.ReceivingLink.AcceptMessage(amqpResponse); using var streamReader = new StreamReader(amqpResponse.BodyStream); @@ -238,7 +273,7 @@ private async Task RegisterDeviceAsync( .ReadToEndAsync() .ConfigureAwait(false); RegistrationOperationStatus status = JsonConvert.DeserializeObject(jsonResponse); - status.RetryAfter = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, s_defaultOperationPoolingInterval); + status.RetryAfter = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, s_defaultOperationPollingInterval); return status; } finally @@ -250,7 +285,8 @@ private async Task RegisterDeviceAsync( private async Task OperationStatusLookupAsync( AmqpClientConnection client, string operationId, - string correlationId) + string correlationId, + TimeSpan timeout) { using var amqpMessage = AmqpMessage.Create(new AmqpValue { Value = DeviceOperations.GetOperationStatus }); @@ -263,12 +299,12 @@ private async Task OperationStatusLookupAsync( .SendMessageAsync( amqpMessage, new ArraySegment(Guid.NewGuid().ToByteArray()), - s_timeoutConstant) + timeout) .ConfigureAwait(false); ValidateOutcome(outcome); - AmqpMessage amqpResponse = await client.AmqpSession.ReceivingLink.ReceiveMessageAsync(s_timeoutConstant) + AmqpMessage amqpResponse = await client.AmqpSession.ReceivingLink.ReceiveMessageAsync(timeout) .ConfigureAwait(false); client.AmqpSession.ReceivingLink.AcceptMessage(amqpResponse); @@ -277,7 +313,7 @@ private async Task OperationStatusLookupAsync( string jsonResponse = await streamReader.ReadToEndAsync().ConfigureAwait(false); RegistrationOperationStatus status = JsonConvert.DeserializeObject(jsonResponse); - status.RetryAfter = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, s_defaultOperationPoolingInterval); + status.RetryAfter = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, s_defaultOperationPollingInterval); return status; } @@ -314,7 +350,7 @@ private void ValidateOutcome(Outcome outcome) bool isTransient = statusCode >= (int)HttpStatusCode.InternalServerError || statusCode == 429; if (isTransient) { - errorDetails.RetryAfter = ProvisioningErrorDetailsAmqp.GetRetryAfterFromRejection(rejected, s_defaultOperationPoolingInterval); + errorDetails.RetryAfter = ProvisioningErrorDetailsAmqp.GetRetryAfterFromRejection(rejected, s_defaultOperationPollingInterval); } throw new ProvisioningTransportException( diff --git a/provisioning/transport/http/src/ProvisioningTransportHandlerHttp.cs b/provisioning/transport/http/src/ProvisioningTransportHandlerHttp.cs index 59b3af6723..cdbd2bec00 100644 --- a/provisioning/transport/http/src/ProvisioningTransportHandlerHttp.cs +++ b/provisioning/transport/http/src/ProvisioningTransportHandlerHttp.cs @@ -32,6 +32,20 @@ public ProvisioningTransportHandlerHttp() Proxy = DefaultWebProxySettings.Instance; } + /// + /// Registers a device described by the message. + /// + /// The provisioning message. + /// The maximum amount of time to allow this operation to run for before timing out. + /// The registration result. + public override async Task RegisterAsync( + ProvisioningTransportRegisterMessage message, + TimeSpan timeout) + { + using var cts = new CancellationTokenSource(timeout); + return await RegisterAsync(message, cts.Token).ConfigureAwait(false); + } + /// /// Registers a device described by the message. /// diff --git a/provisioning/transport/mqtt/src/ProvisioningTransportHandlerMqtt.cs b/provisioning/transport/mqtt/src/ProvisioningTransportHandlerMqtt.cs index d62ee25bd4..99b596d641 100644 --- a/provisioning/transport/mqtt/src/ProvisioningTransportHandlerMqtt.cs +++ b/provisioning/transport/mqtt/src/ProvisioningTransportHandlerMqtt.cs @@ -63,6 +63,20 @@ public ProvisioningTransportHandlerMqtt( Proxy = DefaultWebProxySettings.Instance; } + /// + /// Registers a device described by the message. + /// + /// The provisioning message. + /// The maximum amount of time to allow this operation to run for before timing out. + /// The registration result. + public override async Task RegisterAsync( + ProvisioningTransportRegisterMessage message, + TimeSpan timeout) + { + using var cts = new CancellationTokenSource(timeout); + return await RegisterAsync(message, cts.Token).ConfigureAwait(false); + } + /// /// Registers a device described by the message. /// diff --git a/readme.md b/readme.md index a88b2df8a5..d0ca4c0a96 100644 --- a/readme.md +++ b/readme.md @@ -34,6 +34,15 @@ Due to security considerations, build logs are not publicly available. | Microsoft.Azure.Devices.DigitalTwin.Client | N/A | [![NuGet][pnp-device-prerelease]][pnp-device-nuget] | | Microsoft.Azure.Devices.DigitalTwin.Service | N/A | [![NuGet][pnp-service-prerelease]][pnp-service-nuget] | +> Note: +> Device streaming feature is not being included in our newer preview releases as there is no active development going on in the service. For more details on the feature, see [here](https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-device-streams-overview). It is not recommended to take dependency on preview nugets for production applications as breaking changes can be introduced in preview nugets. +> +> The feature has not been included in any preview release after [2020-10-14](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/preview_2020-10-14). However, the feature is still available under previews/deviceStreaming branch. +> +> The latest preview nuget versions that contain the feature are: +Microsoft.Azure.Devices.Client - 1.32.0-preview-001 +Microsoft.Azure.Devices - 1.28.0-preview-001 + The API reference documentation for .NET SDK is [here][dotnet-api-reference]. To find SDKs in other languages for Azure IoT, please refer to the [azure-iot-sdks][azure-iot-sdks] repository. @@ -63,22 +72,9 @@ If you would like to build or change the SDK source code, please follow the [dev ## OS platforms and hardware compatibility -> .NET Standard 1.3 (IoT Hub SDKs only) is last supported in the [2020-02-27](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/2020-2-27) and in the [2020-1-31 LTS](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/lts_2020-1-31) releases. - -The IoT Hub device SDK for .NET can be used with a broad range of OS platforms and devices, mainly modern versions Windows and Linux. - -The NuGet packages provide support for the following .NET flavors: -- .NET Standard 2.1 -- .NET Standard 2.0 -- .NET Framework 4.7.2 (IoT Hub SDKs only) -- .NET Framework 4.5.1 (IoT Hub SDKs only) - -For details on .NET support see the [.NET Standard documentation](https://docs.microsoft.com/dotnet/standard/net-standard). -For details on OS support see the following resources: +For an official list of all the operating systems and .NET platforms that we support, please see [this document](./supported_platforms.md) -- [.NET Core Runtime ID Catalog](https://docs.microsoft.com/dotnet/core/rid-catalog) -- [.NET Framework System Requirements](https://docs.microsoft.com/dotnet/framework/get-started/system-requirements) -- [Configure TLS Protocol Version and Ciphers](./configure_tls_protocol_version_and_ciphers.md) +Note that you can configure your TLS protocol version and ciphers by following [this document](./configure_tls_protocol_version_and_ciphers.md) ## Key features and roadmap @@ -193,6 +189,7 @@ Below is a table showing the mapping of the LTS branches to the packages release | Release | Github Branch | LTS Status | LTS Start Date | Maintenance End Date | LTS End Date | | :-------------------------------------------------------------------------------------------: | :-----------: | :--------: | :------------: | :------------------: | :----------: | +| [2021-6-23](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/lts_2021-3-18_patch1) | lts_2021_03 | Active | 2020-03-18 | 2022-03-18 | 2024-03-17 | | [2021-3-18](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/lts_2021-3-18) | lts_2021_03 | Active | 2020-03-18 | 2022-03-18 | 2024-03-17 | | [2020-9-23](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/lts_2020-8-19_patch1) | lts_2020_08 | Active | 2020-08-19 | 2021-08-19 | 2023-08-19 | | [2020-8-19](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/lts_2020-8-19) | lts_2020_08 | Active | 2020-08-19 | 2021-08-19 | 2023-08-19 | diff --git a/supported_platforms.md b/supported_platforms.md new file mode 100644 index 0000000000..0944a25974 --- /dev/null +++ b/supported_platforms.md @@ -0,0 +1,57 @@ +# Microsoft Azure IoT SDKs for .NET + +This SDK is tested nightly on a mix of .NET implementations on both Windows 10 and on Ubuntu 1604. For additional details +for each tested platform, see the respective sections below. + +## Supported .NET versions + +The NuGet packages provide support for the following .NET versions: +- .NET Standard 2.1 +- .NET Standard 2.0 +- .NET Framework 4.7.2 (IoT Hub SDKs only) +- .NET Framework 4.5.1 (IoT Hub SDKs only) + +This SDK _may_ work with newer versions of .NET, but there are no guarantees that they will _always_ work for those until we officially add support for them. +versions nor are there guarantees that we will fix bugs that are only present on those versions. + +Note that applications will resolve the dll that is being referenced based on the framework precedence rules. This means that .NET Framework targeting applications will look for the closet .NET Framework dll. In the absence of that, it will pick up the closest .NET Standard dll. Similarly for netcoreapp applications will look for the closest netcoreapp dll and in the absence of one will pick the closest .NET Standard dll. Since we publish the above list of dlls, you should target the appropriate net target to ensure you get the desired .NET API coverage + +## Windows 10 + +Note that, while we only directly test on Windows 10, we do support other Windows versions officially supported by Microsoft. + +Nightly test platform details: + +.NET versions tested on +- .NET Core 3.1 +- .NET Core 2.1.18 +- .NET Framework 4.7.2 (only IoT Hub SDKs tested) +- .NET Framework 4.5.1 (only IoT Hub SDKs tested) + + +Default locale: en_US, platform encoding: Cp1252 + +OS name: "windows server 2016", version: "10.0", arch: "amd64", family: "windows" + +## Ubuntu 1604 + +Note that, while we only directly test on Ubuntu 1604, we do generally support other [Linux distributions supported by .NET core](https://docs.microsoft.com/en-us/dotnet/core/install/linux). + +Nightly test platform details: + +.NET versions tested on: +- .NET Core 3.1 +- .NET Core 2.1.18 + +Default locale: en_US, platform encoding: UTF-8 + +OS name: "linux", version: "4.15.0-1113-azure", arch: "amd64", family: "unix" + +## Miscellaneous support notes + +- This library has a [preview version](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/preview_2021-6-8) that supports .NET 5.0, but we don't officially support it in our main releases yet. +- This library does not officially support being run on MacOS. +- This library does not officially support being run in Xamarin applications. +- .NET Standard 1.3 (IoT Hub SDKs only) is last supported in the [2020-02-27](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/2020-2-27) and in the [2020-1-31 LTS](https://github.com/Azure/azure-iot-sdk-csharp/releases/tag/lts_2020-1-31) releases. +- [.NET Core Runtime ID Catalog](https://docs.microsoft.com/dotnet/core/rid-catalog) +- In order to run this SDK your device will need to meet the [.NET Framework System Requirements](https://docs.microsoft.com/dotnet/framework/get-started/system-requirements) diff --git a/vsts/vsts.yaml b/vsts/vsts.yaml index 99ecc9a4f2..c6415d2d18 100644 --- a/vsts/vsts.yaml +++ b/vsts/vsts.yaml @@ -32,6 +32,7 @@ jobs: condition: succeeded() pool: + # If this is changed, don't forget to update supported_platforms.md in the root directory. That document outlines what OS we test on and should stay up to date. name: Hosted Ubuntu 1604 steps: - task: Docker@1 @@ -141,6 +142,7 @@ jobs: condition: succeeded() pool: + # If this is changed, don't forget to update supported_platforms.md in the root directory. That document outlines what OS we test on and should stay up to date. name: Hosted VS2017 steps: - script: |