diff --git a/common/src/Logging.Common.cs b/common/src/Logging.Common.cs
index 5854203881..953a824062 100644
--- a/common/src/Logging.Common.cs
+++ b/common/src/Logging.Common.cs
@@ -399,7 +399,6 @@ public static void DumpBuffer(object thisOrContextObject, byte[] buffer, int off
/// The number of bytes to log.
/// The calling member.
[NonEvent]
- [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "Parameters 'thisOrContextObject' and 'memberName' used in NET451; remove when no longer supported.")]
public static unsafe void DumpBuffer(object thisOrContextObject, IntPtr bufferPtr, int count, [CallerMemberName] string memberName = null)
{
Debug.Assert(bufferPtr != IntPtr.Zero);
diff --git a/common/src/device/provisioning/transport/ProvisioningSasBuilder.cs b/common/src/device/provisioning/transport/ProvisioningSasBuilder.cs
index ddb53688b8..15a502a765 100644
--- a/common/src/device/provisioning/transport/ProvisioningSasBuilder.cs
+++ b/common/src/device/provisioning/transport/ProvisioningSasBuilder.cs
@@ -103,7 +103,7 @@ public static string BuildSasSignature(string keyName, string key, string target
public static string BuildExpiresOn(TimeSpan timeToLive)
{
- DateTime epochTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
+ var epochTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
DateTime expiresOn = DateTime.UtcNow.Add(timeToLive);
TimeSpan secondsFromBaseTime = expiresOn.Subtract(epochTime);
long seconds = Convert.ToInt64(secondsFromBaseTime.TotalSeconds, CultureInfo.InvariantCulture);
diff --git a/common/src/service/HttpClientHelper.cs b/common/src/service/HttpClientHelper.cs
index 5cddb9f422..55563952a8 100644
--- a/common/src/service/HttpClientHelper.cs
+++ b/common/src/service/HttpClientHelper.cs
@@ -882,10 +882,10 @@ internal static HttpMessageHandler CreateDefaultHttpMessageHandler(IWebProxy web
#pragma warning disable CA2000 // Dispose objects before losing scope (object is returned by this method, so the caller is responsible for disposing it)
#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_0 && !NETCOREAPP1_1
// SocketsHttpHandler is only available in netcoreapp2.1 and onwards
- SocketsHttpHandler httpMessageHandler = new SocketsHttpHandler();
+ var httpMessageHandler = new SocketsHttpHandler();
httpMessageHandler.SslOptions.EnabledSslProtocols = TlsVersions.Instance.Preferred;
#else
- HttpClientHandler httpMessageHandler = new HttpClientHandler();
+ var httpMessageHandler = new HttpClientHandler();
#if !NET451
httpMessageHandler.SslProtocols = TlsVersions.Instance.Preferred;
httpMessageHandler.CheckCertificateRevocationList = TlsVersions.Instance.CertificateRevocationCheck;
diff --git a/common/src/service/IAuthorizationHeaderProvider.cs b/common/src/service/IAuthorizationHeaderProvider.cs
index 207526a168..798ce5bfdb 100644
--- a/common/src/service/IAuthorizationHeaderProvider.cs
+++ b/common/src/service/IAuthorizationHeaderProvider.cs
@@ -3,7 +3,10 @@
namespace Microsoft.Azure.Devices
{
- interface IAuthorizationHeaderProvider
+ ///
+ /// Gets the authorization header for authenticated requests, regardless of choice of authentication.
+ ///
+ internal interface IAuthorizationHeaderProvider
{
string GetAuthorizationHeader();
}
diff --git a/common/src/service/StringValidationHelper.cs b/common/src/service/StringValidationHelper.cs
index 3529463e18..09482b20ed 100644
--- a/common/src/service/StringValidationHelper.cs
+++ b/common/src/service/StringValidationHelper.cs
@@ -66,9 +66,9 @@ public static bool IsBase64String(string value)
return false;
}
- var lengthNoPadding = value.Length;
+ int lengthNoPadding = value.Length;
value = value.TrimEnd(Base64Padding);
- var lengthPadding = value.Length;
+ int lengthPadding = value.Length;
if ((lengthNoPadding - lengthPadding) > 2)
{
diff --git a/e2e/test/GlobalSuppressions.cs b/e2e/test/GlobalSuppressions.cs
new file mode 100644
index 0000000000..2a5b12c82b
--- /dev/null
+++ b/e2e/test/GlobalSuppressions.cs
@@ -0,0 +1,17 @@
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+
+using System.Diagnostics.CodeAnalysis;
+
+[assembly: SuppressMessage(
+ "Style",
+ "IDE1006:Naming Styles",
+ Justification = "Missing Async suffix on test method names. Test method names may be misleading when they have the Async suffix. Additionally, not changing test names help to maintain ADO history.",
+ Scope = "module")]
+[assembly: SuppressMessage(
+ "CodeQuality",
+ "IDE0079:Remove unnecessary suppression",
+ Justification = "Each frameworks consider certain suppressions required by other frameworks unnecessary.",
+ Scope = "module")]
diff --git a/e2e/test/config/TestConfiguration.IoTHub.cs b/e2e/test/config/TestConfiguration.IoTHub.cs
index 2e2a9264ec..a94b6f093b 100644
--- a/e2e/test/config/TestConfiguration.IoTHub.cs
+++ b/e2e/test/config/TestConfiguration.IoTHub.cs
@@ -59,7 +59,7 @@ public static string GetIotHubSharedAccessSignature(TimeSpan timeToLive)
public static X509Certificate2 GetCertificateWithPrivateKey()
{
const string hubPfxCert = "IOTHUB_X509_PFX_CERTIFICATE";
- var cert = GetBase64EncodedCertificate(hubPfxCert, defaultValue: string.Empty);
+ X509Certificate2 cert = GetBase64EncodedCertificate(hubPfxCert, defaultValue: string.Empty);
Assert.IsTrue(cert.NotAfter > DateTime.UtcNow, $"The X509 cert from {hubPfxCert} has expired.");
return cert;
}
@@ -67,7 +67,7 @@ public static X509Certificate2 GetCertificateWithPrivateKey()
public static X509Certificate2 GetChainDeviceCertificateWithPrivateKey()
{
const string hubPfxCert = "HUB_CHAIN_DEVICE_PFX_CERTIFICATE";
- var cert = GetBase64EncodedCertificate(hubPfxCert, defaultValue: string.Empty);
+ X509Certificate2 cert = GetBase64EncodedCertificate(hubPfxCert, defaultValue: string.Empty);
Assert.IsTrue(cert.NotAfter > DateTime.UtcNow, $"The X509 cert from {hubPfxCert} has expired.");
return cert;
}
@@ -75,7 +75,7 @@ public static X509Certificate2 GetChainDeviceCertificateWithPrivateKey()
public static X509Certificate2 GetRootCACertificate()
{
const string hubCert = "HUB_CHAIN_ROOT_CA_CERTIFICATE";
- var cert = GetBase64EncodedCertificate(hubCert);
+ X509Certificate2 cert = GetBase64EncodedCertificate(hubCert);
Assert.IsTrue(cert.NotAfter > DateTime.UtcNow, $"The X509 cert from {hubCert} has expired.");
return cert;
}
@@ -83,7 +83,7 @@ public static X509Certificate2 GetRootCACertificate()
public static X509Certificate2 GetIntermediate1Certificate()
{
const string hubCert = "HUB_CHAIN_INTERMEDIATE1_CERTIFICATE";
- var cert = GetBase64EncodedCertificate(hubCert);
+ X509Certificate2 cert = GetBase64EncodedCertificate(hubCert);
Assert.IsTrue(cert.NotAfter > DateTime.UtcNow, $"The X509 cert from {hubCert} has expired.");
return cert;
}
@@ -91,7 +91,7 @@ public static X509Certificate2 GetIntermediate1Certificate()
public static X509Certificate2 GetIntermediate2Certificate()
{
const string hubCert = "HUB_CHAIN_INTERMEDIATE2_CERTIFICATE";
- var cert = GetBase64EncodedCertificate(hubCert);
+ X509Certificate2 cert = GetBase64EncodedCertificate(hubCert);
Assert.IsTrue(cert.NotAfter > DateTime.UtcNow, $"The X509 cert from {hubCert} has expired.");
return cert;
}
@@ -111,7 +111,7 @@ public static X509Certificate2 GetIntermediate2Certificate()
private static string GenerateSasToken(string resourceUri, string sharedAccessKey, TimeSpan timeToLive, string policyName = default)
{
- DateTime epochTime = new DateTime(1970, 1, 1);
+ var epochTime = new DateTime(1970, 1, 1);
DateTime expiresOn = DateTime.UtcNow.Add(timeToLive);
TimeSpan secondsFromEpochTime = expiresOn.Subtract(epochTime);
long seconds = Convert.ToInt64(secondsFromEpochTime.TotalSeconds, CultureInfo.InvariantCulture);
diff --git a/e2e/test/helpers/ImportExportDevicesHelpers.cs b/e2e/test/helpers/ImportExportDevicesHelpers.cs
deleted file mode 100644
index 7e753b4455..0000000000
--- a/e2e/test/helpers/ImportExportDevicesHelpers.cs
+++ /dev/null
@@ -1,29 +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.Collections.Generic;
-using System.IO;
-using System.Text;
-using Newtonsoft.Json;
-
-namespace Microsoft.Azure.Devices.E2ETests.Helpers
-{
- internal static class ImportExportDevicesHelpers
- {
- ///
- /// Makes a stream compatible for writing to a storage blob of serialized, newline-delimited rows of the specified devices
- ///
- /// The devices to serialize
- public static Stream BuildDevicesStream(IReadOnlyList devices)
- {
- var devicesFileSb = new StringBuilder();
-
- foreach (ExportImportDevice device in devices)
- {
- devicesFileSb.AppendLine(JsonConvert.SerializeObject(device));
- }
-
- byte[] devicesFileInBytes = Encoding.Default.GetBytes(devicesFileSb.ToString());
- return new MemoryStream(devicesFileInBytes);
- }
- }
-}
diff --git a/e2e/test/helpers/ImportExportHelpers.cs b/e2e/test/helpers/ImportExportHelpers.cs
new file mode 100644
index 0000000000..d762ede683
--- /dev/null
+++ b/e2e/test/helpers/ImportExportHelpers.cs
@@ -0,0 +1,30 @@
+// 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 System.IO;
+using System.Text;
+using Newtonsoft.Json;
+
+namespace Microsoft.Azure.Devices.E2ETests.Helpers
+{
+ internal static class ImportExportHelpers
+ {
+ ///
+ /// Makes a stream compatible for writing to a storage blob of serialized, newline-delimited rows of the specified objects.
+ ///
+ /// The objects to serialize.
+ public static Stream BuildImportStream(IReadOnlyList items)
+ {
+ var itemsFileSb = new StringBuilder();
+
+ foreach (T item in items)
+ {
+ itemsFileSb.AppendLine(JsonConvert.SerializeObject(item));
+ }
+
+ byte[] itemsFileInBytes = Encoding.Default.GetBytes(itemsFileSb.ToString());
+ return new MemoryStream(itemsFileInBytes);
+ }
+ }
+}
diff --git a/e2e/test/helpers/StorageContainer.cs b/e2e/test/helpers/StorageContainer.cs
index d763128d2f..28b7b24330 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(TestConfiguration.Storage.ConnectionString);
+ var 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 659e5fd770..ef3be3a394 100644
--- a/e2e/test/helpers/TestDevice.cs
+++ b/e2e/test/helpers/TestDevice.cs
@@ -75,7 +75,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 RegistryManager rm = RegistryManager.CreateFromConnectionString(TestConfiguration.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;
diff --git a/e2e/test/helpers/TestDeviceCallbackHandler.cs b/e2e/test/helpers/TestDeviceCallbackHandler.cs
index 02d2fbb24f..071f613804 100644
--- a/e2e/test/helpers/TestDeviceCallbackHandler.cs
+++ b/e2e/test/helpers/TestDeviceCallbackHandler.cs
@@ -177,13 +177,11 @@ public async Task WaitForReceiveMessageCallbackAsync(CancellationToken ct)
public async Task SetClientPropertyUpdateCallbackHandlerAsync(string expectedPropName, string componentName = default)
{
- string userContext = "myContext";
-
await _deviceClient
.SubscribeToWritablePropertyUpdateRequestsAsync(
- (patch, context) =>
+ patch =>
{
- _logger.Trace($"{nameof(SetClientPropertyUpdateCallbackHandlerAsync)}: DeviceClient {_testDevice.Id} callback property: WritableProperty: {patch}, {context}");
+ _logger.Trace($"{nameof(SetClientPropertyUpdateCallbackHandlerAsync)}: DeviceClient {_testDevice.Id} callback property: WritableProperty: {patch}.");
try
{
@@ -193,7 +191,6 @@ await _deviceClient
isPropertyPresent.Should().BeTrue();
propertyFromCollection.Should().BeEquivalentTo((T)ExpectedClientPropertyValue);
- context.Should().Be(userContext);
}
catch (Exception ex)
{
@@ -206,8 +203,7 @@ await _deviceClient
}
return Task.FromResult(true);
- },
- userContext)
+ })
.ConfigureAwait(false);
}
diff --git a/e2e/test/iothub/AuthenticationWithTokenRefreshDisposalTests.cs b/e2e/test/iothub/AuthenticationWithTokenRefreshDisposalTests.cs
index 9554bf001c..b133b8c474 100644
--- a/e2e/test/iothub/AuthenticationWithTokenRefreshDisposalTests.cs
+++ b/e2e/test/iothub/AuthenticationWithTokenRefreshDisposalTests.cs
@@ -101,69 +101,53 @@ public async Task DeviceClient_AuthenticationMethodDisposesTokenRefresher_MqttWs
private async Task AuthenticationMethodDisposesTokenRefresher(Client.TransportType transport)
{
- AuthenticationWithTokenRefresh authenticationMethod = null;
- DeviceClient testClient = null;
- try
- {
- TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);
- authenticationMethod = new DeviceAuthenticationSasToken(testDevice.ConnectionString, disposeWithClient: true);
-
- // Create an instance of the device client, send a test message and then close and dispose it.
- testClient = DeviceClient.Create(testDevice.IoTHubHostName, authenticationMethod, transport);
- using var message1 = new Client.Message();
- await testClient.SendEventAsync(message1).ConfigureAwait(false);
- await testClient.CloseAsync();
- testClient.Dispose();
- testClient = null;
- Logger.Trace("Test with instance 1 completed");
-
- // Perform the same steps again, reusing the previously created authentication method instance.
- // Since the default behavior is to dispose AuthenticationWithTokenRefresh authentication method on DeviceClient disposal,
- // this should now throw an ObjectDisposedException.
- testClient = DeviceClient.Create(testDevice.IoTHubHostName, authenticationMethod, transport);
- using var message2 = new Client.Message();
-
- Func act = async () => await testClient.SendEventAsync(message2).ConfigureAwait(false);
- await act.Should().ThrowAsync();
- }
- finally
- {
- testClient?.Dispose();
- authenticationMethod?.Dispose();
- }
+ TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);
+ var authenticationMethod = new DeviceAuthenticationSasToken(testDevice.ConnectionString, disposeWithClient: true);
+
+ // Create an instance of the device client, send a test message and then close and dispose it.
+ var deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, authenticationMethod, transport);
+ using var message1 = new Client.Message();
+ await deviceClient.SendEventAsync(message1).ConfigureAwait(false);
+ await deviceClient.CloseAsync();
+ deviceClient.Dispose();
+ Logger.Trace("Test with instance 1 completed");
+
+ // Perform the same steps again, reusing the previously created authentication method instance.
+ // Since the default behavior is to dispose AuthenticationWithTokenRefresh authentication method on DeviceClient disposal,
+ // this should now throw an ObjectDisposedException.
+ var deviceClient2 = DeviceClient.Create(testDevice.IoTHubHostName, authenticationMethod, transport);
+ using var message2 = new Client.Message();
+
+ Func act = async () => await deviceClient2.SendEventAsync(message2).ConfigureAwait(false);
+ await act.Should().ThrowAsync();
+
+ authenticationMethod.Dispose();
+ deviceClient2.Dispose();
}
private async Task ReuseAuthenticationMethod_SingleDevice(Client.TransportType transport)
{
- AuthenticationWithTokenRefresh authenticationMethod = null;
- DeviceClient testClient = null;
- try
- {
- TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);
- authenticationMethod = new DeviceAuthenticationSasToken(testDevice.ConnectionString, disposeWithClient: false);
-
- // Create an instance of the device client, send a test message and then close and dispose it.
- testClient = DeviceClient.Create(testDevice.IoTHubHostName, authenticationMethod, transport);
- using var message1 = new Client.Message();
- await testClient.SendEventAsync(message1).ConfigureAwait(false);
- await testClient.CloseAsync();
- testClient.Dispose();
- testClient = null;
- Logger.Trace("Test with instance 1 completed");
-
- // Perform the same steps again, reusing the previously created authentication method instance to ensure
- // that the sdk did not dispose the user supplied authentication method instance.
- testClient = DeviceClient.Create(testDevice.IoTHubHostName, authenticationMethod, transport);
- using var message2 = new Client.Message();
- await testClient.SendEventAsync(message2).ConfigureAwait(false);
- await testClient.CloseAsync();
- Logger.Trace("Test with instance 2 completed, reused the previously created authentication method instance for the device client.");
- }
- finally
- {
- authenticationMethod?.Dispose();
- testClient?.Dispose();
- }
+ TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);
+ var authenticationMethod = new DeviceAuthenticationSasToken(testDevice.ConnectionString, disposeWithClient: false);
+
+ // Create an instance of the device client, send a test message and then close and dispose it.
+ var deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, authenticationMethod, transport);
+ using var message1 = new Client.Message();
+ await deviceClient.SendEventAsync(message1).ConfigureAwait(false);
+ await deviceClient.CloseAsync();
+ deviceClient.Dispose();
+ Logger.Trace("Test with instance 1 completed");
+
+ // Perform the same steps again, reusing the previously created authentication method instance to ensure
+ // that the SDK did not dispose the user supplied authentication method instance.
+ var deviceClient2 = DeviceClient.Create(testDevice.IoTHubHostName, authenticationMethod, transport);
+ using var message2 = new Client.Message();
+ await deviceClient2.SendEventAsync(message2).ConfigureAwait(false);
+ await deviceClient2.CloseAsync();
+ deviceClient2.Dispose();
+ Logger.Trace("Test with instance 2 completed, reused the previously created authentication method instance for the device client.");
+
+ authenticationMethod.Dispose();
}
private async Task ReuseAuthenticationMethod_MuxedDevices(Client.TransportType transport, int devicesCount)
@@ -198,7 +182,7 @@ private async Task ReuseAuthenticationMethod_MuxedDevices(Client.TransportType t
for (int i = 0; i < devicesCount; i++)
{
#pragma warning disable CA2000 // Dispose objects before losing scope - the client instance is disposed during the course of the test.
- DeviceClient deviceClient = DeviceClient.Create(testDevices[i].IoTHubHostName, authenticationMethods[i], new ITransportSettings[] { amqpTransportSettings });
+ var deviceClient = DeviceClient.Create(testDevices[i].IoTHubHostName, authenticationMethods[i], new ITransportSettings[] { amqpTransportSettings });
#pragma warning restore CA2000 // Dispose objects before losing scope
var amqpConnectionStatusChange = new AmqpConnectionStatusChange(testDevices[i].Id, Logger);
@@ -262,7 +246,13 @@ private async Task ReuseAuthenticationMethod_MuxedDevices(Client.TransportType t
for (int i = 0; i < devicesCount; i++)
{
#pragma warning disable CA2000 // Dispose objects before losing scope - the client instance is disposed at the end of the test.
- DeviceClient deviceClient = DeviceClient.Create(testDevices[i].IoTHubHostName, authenticationMethods[i], new ITransportSettings[] { amqpTransportSettings });
+ var deviceClient = DeviceClient.Create(
+ testDevices[i].IoTHubHostName,
+ authenticationMethods[i],
+ new ITransportSettings[]
+ {
+ amqpTransportSettings
+ });
#pragma warning restore CA2000 // Dispose objects before losing scope
var amqpConnectionStatusChange = new AmqpConnectionStatusChange(testDevices[i].Id, Logger);
diff --git a/e2e/test/iothub/ConnectionStatusChangeHandlerTests.cs b/e2e/test/iothub/ConnectionStatusChangeHandlerTests.cs
index 92e1cca9ae..b044d2356f 100644
--- a/e2e/test/iothub/ConnectionStatusChangeHandlerTests.cs
+++ b/e2e/test/iothub/ConnectionStatusChangeHandlerTests.cs
@@ -116,7 +116,7 @@ public async Task ModuleClient_DeviceDisabled_Gives_ConnectionStatus_DeviceDisab
ConnectionStatusChangeReason? statusChangeReason = null;
int deviceDisabledReceivedCount = 0;
- using (DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(deviceConnectionString, protocol))
+ using (var deviceClient = DeviceClient.CreateFromConnectionString(deviceConnectionString, protocol))
{
ConnectionStatusChangesHandler statusChangeHandler = (s, r) =>
{
@@ -135,11 +135,11 @@ public async Task ModuleClient_DeviceDisabled_Gives_ConnectionStatus_DeviceDisab
// Receiving the module twin should succeed right now.
Logger.Trace($"{nameof(DeviceClient_Gives_ConnectionStatus_DeviceDisabled_Base)}: DeviceClient GetTwinAsync.");
- var twin = await deviceClient.GetTwinAsync().ConfigureAwait(false);
+ Shared.Twin twin = await deviceClient.GetTwinAsync().ConfigureAwait(false);
Assert.IsNotNull(twin);
// Delete/disable the device in IoT Hub. This should trigger the ConnectionStatusChangesHandler.
- using (RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString))
+ using (var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString))
{
await registryManagerOperation(registryManager, deviceId).ConfigureAwait(false);
}
@@ -168,8 +168,8 @@ public async Task ModuleClient_DeviceDisabled_Gives_ConnectionStatus_DeviceDisab
private async Task ModuleClient_Gives_ConnectionStatus_DeviceDisabled_Base(
Client.TransportType protocol, Func registryManagerOperation)
{
- AmqpTransportSettings amqpTransportSettings = new AmqpTransportSettings(protocol);
- ITransportSettings[] transportSettings = new ITransportSettings[] { amqpTransportSettings };
+ var amqpTransportSettings = new AmqpTransportSettings(protocol);
+ var transportSettings = new ITransportSettings[] { amqpTransportSettings };
TestModule testModule = await TestModule.GetTestModuleAsync(DevicePrefix + $"_{Guid.NewGuid()}", ModulePrefix, Logger).ConfigureAwait(false);
ConnectionStatus? status = null;
@@ -185,7 +185,7 @@ public async Task ModuleClient_DeviceDisabled_Gives_ConnectionStatus_DeviceDisab
}
};
- using (ModuleClient moduleClient = ModuleClient.CreateFromConnectionString(testModule.ConnectionString, transportSettings))
+ using (var moduleClient = ModuleClient.CreateFromConnectionString(testModule.ConnectionString, transportSettings))
{
moduleClient.SetConnectionStatusChangesHandler(statusChangeHandler);
Logger.Trace($"{nameof(ModuleClient_Gives_ConnectionStatus_DeviceDisabled_Base)}: Created {nameof(ModuleClient)} with moduleId={testModule.Id}");
@@ -194,11 +194,11 @@ public async Task ModuleClient_DeviceDisabled_Gives_ConnectionStatus_DeviceDisab
// Receiving the module twin should succeed right now.
Logger.Trace($"{nameof(ModuleClient_Gives_ConnectionStatus_DeviceDisabled_Base)}: ModuleClient GetTwinAsync.");
- var twin = await moduleClient.GetTwinAsync().ConfigureAwait(false);
+ Shared.Twin twin = await moduleClient.GetTwinAsync().ConfigureAwait(false);
Assert.IsNotNull(twin);
// Delete/disable the device in IoT Hub.
- using (RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString))
+ using (var 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 9f367eded3..fc7d5de7fe 100644
--- a/e2e/test/iothub/DeviceClientX509AuthenticationE2ETests.cs
+++ b/e2e/test/iothub/DeviceClientX509AuthenticationE2ETests.cs
@@ -159,7 +159,7 @@ public async Task X509_Cert_Chain_Install_Test_MQTT_TCP()
TestConfiguration.IoTHub.X509ChainDeviceName,
s_chainCertificateWithPrivateKey,
chainCerts);
- using DeviceClient deviceClient = DeviceClient.Create(
+ using var deviceClient = DeviceClient.Create(
_hostName,
auth,
DeviceTransportType.Mqtt_Tcp_Only);
@@ -186,7 +186,7 @@ public async Task X509_Cert_Chain_Install_Test_AMQP_TCP()
TestConfiguration.IoTHub.X509ChainDeviceName,
s_chainCertificateWithPrivateKey,
chainCerts);
- using DeviceClient deviceClient = DeviceClient.Create(
+ using var deviceClient = DeviceClient.Create(
_hostName,
auth,
DeviceTransportType.Amqp_Tcp_Only);
@@ -253,7 +253,7 @@ private async Task X509InvalidDeviceIdOpenAsyncTest(Client.TransportType transpo
{
string deviceName = $"DEVICE_NOT_EXIST_{Guid.NewGuid()}";
using var auth = new DeviceAuthenticationWithX509Certificate(deviceName, s_selfSignedCertificateWithPrivateKey);
- using DeviceClient deviceClient = DeviceClient.Create(_hostName, auth, transportType);
+ using var deviceClient = DeviceClient.Create(_hostName, auth, transportType);
try
{
@@ -274,7 +274,7 @@ private async Task X509InvalidDeviceIdOpenAsyncTwiceTest(Client.TransportType tr
{
string deviceName = $"DEVICE_NOT_EXIST_{Guid.NewGuid()}";
using var auth = new DeviceAuthenticationWithX509Certificate(deviceName, s_selfSignedCertificateWithPrivateKey);
- using DeviceClient deviceClient = DeviceClient.Create(_hostName, auth, transportType);
+ using var deviceClient = DeviceClient.Create(_hostName, auth, transportType);
for (int i = 0; i < 2; i++)
{
diff --git a/e2e/test/iothub/DeviceTokenRefreshE2ETests.cs b/e2e/test/iothub/DeviceTokenRefreshE2ETests.cs
index 96f308eacc..601228c2d3 100644
--- a/e2e/test/iothub/DeviceTokenRefreshE2ETests.cs
+++ b/e2e/test/iothub/DeviceTokenRefreshE2ETests.cs
@@ -31,7 +31,7 @@ public async Task DeviceClient_Not_Exist_AMQP()
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false);
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))
+ using (var deviceClient = DeviceClient.CreateFromConnectionString($"HostName={config.IotHubHostName};DeviceId=device_id_not_exist;SharedAccessKey={config.SharedAccessKey}", Client.TransportType.Amqp_Tcp_Only))
{
await deviceClient.OpenAsync().ConfigureAwait(false);
}
@@ -45,7 +45,7 @@ public async Task DeviceClient_Bad_Credentials_AMQP()
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))
+ using (var deviceClient = DeviceClient.CreateFromConnectionString($"HostName={config.IotHubHostName};DeviceId={config.DeviceID};SharedAccessKey={invalidKey}", Client.TransportType.Amqp_Tcp_Only))
{
await deviceClient.OpenAsync().ConfigureAwait(false);
}
@@ -96,7 +96,7 @@ public async Task DeviceClient_TokenConnectionDoubleRelease_Ok()
var auth = new DeviceAuthenticationWithToken(deviceId, builder.ToSignature());
- using DeviceClient deviceClient = DeviceClient.Create(iotHub, auth, Client.TransportType.Amqp_Tcp_Only);
+ using var deviceClient = DeviceClient.Create(iotHub, auth, Client.TransportType.Amqp_Tcp_Only);
Logger.Trace($"{deviceId}: Created {nameof(DeviceClient)} ID={TestLogger.IdOf(deviceClient)}");
Logger.Trace($"{deviceId}: DeviceClient OpenAsync.");
@@ -183,7 +183,7 @@ private async Task DeviceClient_TokenIsRefreshed_Internal(Client.TransportType t
transport,
Logger);
- using DeviceClient deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, refresher, transport);
+ using var deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, refresher, transport);
Logger.Trace($"Created {nameof(DeviceClient)} ID={TestLogger.IdOf(deviceClient)}");
if (transport == Client.TransportType.Mqtt)
diff --git a/e2e/test/iothub/FileUploadFaultInjectionTests.cs b/e2e/test/iothub/FileUploadFaultInjectionTests.cs
index 8e261f4312..35a20bfaf0 100644
--- a/e2e/test/iothub/FileUploadFaultInjectionTests.cs
+++ b/e2e/test/iothub/FileUploadFaultInjectionTests.cs
@@ -87,7 +87,7 @@ public async Task FileUploadSuccess_QuotaExceed_Amqp()
{
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false);
- using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
+ using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
TimeSpan operationTimeout = retryDurationInMilliSec == TimeSpan.Zero ? FaultInjection.RecoveryTime : retryDurationInMilliSec;
deviceClient.OperationTimeoutInMilliseconds = (uint)operationTimeout.TotalMilliseconds;
diff --git a/e2e/test/iothub/SasCredentialAuthenticationTests.cs b/e2e/test/iothub/SasCredentialAuthenticationTests.cs
index 827f05ec2b..decc7947ef 100644
--- a/e2e/test/iothub/SasCredentialAuthenticationTests.cs
+++ b/e2e/test/iothub/SasCredentialAuthenticationTests.cs
@@ -101,7 +101,7 @@ public async Task JobClient_Http_SasCredentialAuth_Success()
string jobId = "JOBSAMPLE" + Guid.NewGuid().ToString();
string jobDeviceId = "JobsSample_Device";
string query = $"DeviceId IN ['{jobDeviceId}']";
- Twin twin = new Twin(jobDeviceId);
+ var twin = new Twin(jobDeviceId);
try
{
diff --git a/e2e/test/iothub/TokenCredentialAuthenticationTests.cs b/e2e/test/iothub/TokenCredentialAuthenticationTests.cs
index cbbcc0633c..6c1e687b76 100644
--- a/e2e/test/iothub/TokenCredentialAuthenticationTests.cs
+++ b/e2e/test/iothub/TokenCredentialAuthenticationTests.cs
@@ -66,7 +66,7 @@ public async Task JobClient_Http_TokenCredentialAuth_Success()
string jobId = "JOBSAMPLE" + Guid.NewGuid().ToString();
string jobDeviceId = "JobsSample_Device";
string query = $"DeviceId IN ['{jobDeviceId}']";
- Twin twin = new Twin(jobDeviceId);
+ var twin = new Twin(jobDeviceId);
try
{
@@ -124,22 +124,19 @@ public async Task DigitalTwinClient_Http_TokenCredentialAuth_Success()
public async Task Service_Amqp_TokenCredentialAuth_Success()
{
// arrange
- TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);
- using DeviceClient deviceClient = testDevice.CreateDeviceClient(Client.TransportType.Mqtt);
- await deviceClient.OpenAsync().ConfigureAwait(false);
-
+ string ghostDevice = $"{nameof(Service_Amqp_TokenCredentialAuth_Success)}_{Guid.NewGuid()}";
using var serviceClient = ServiceClient.Create(
TestConfiguration.IoTHub.GetIotHubHostName(),
TestConfiguration.IoTHub.GetClientSecretCredential(),
TransportType.Amqp);
-
- // act
await serviceClient.OpenAsync().ConfigureAwait(false);
using var message = new Message(Encoding.ASCII.GetBytes("Hello, Cloud!"));
- await serviceClient.SendAsync(testDevice.Id, message);
- // cleanup
- await testDevice.RemoveDeviceAsync().ConfigureAwait(false);
+ // act
+ Func act = async () => await serviceClient.SendAsync(ghostDevice, message).ConfigureAwait(false);
+
+ // assert
+ await act.Should().ThrowAsync();
}
#endif
diff --git a/e2e/test/iothub/command/CommandE2ETests.cs b/e2e/test/iothub/command/CommandE2ETests.cs
index 8be5c30240..a160831709 100644
--- a/e2e/test/iothub/command/CommandE2ETests.cs
+++ b/e2e/test/iothub/command/CommandE2ETests.cs
@@ -3,6 +3,7 @@
using System;
using System.Threading.Tasks;
+using FluentAssertions;
using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.E2ETests.Helpers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -120,44 +121,45 @@ public static async Task DigitalTwinsSendCommandAndVerifyResponseAsync(string de
digitalTwinClient.Dispose();
#endif
logger.Trace($"{nameof(DigitalTwinsSendCommandAndVerifyResponseAsync)}: Command status: {statusCode}.");
- Assert.AreEqual(200, statusCode, $"The expected response status should be 200 but was {statusCode}");
- Assert.AreEqual(responseExpected, payloadReceived, $"The expected response payload should be {responseExpected} but was {payloadReceived}");
+ statusCode.Should().Be(200, "The expected response status should be 200.");
+ payloadReceived.Should().Be(responseExpected);
}
public static async Task SetDeviceReceiveCommandAsync(DeviceClient deviceClient, string componentName, string commandName, MsTestLogger logger)
{
var commandCallReceived = new TaskCompletionSource();
- await deviceClient.SubscribeToCommandsAsync(
- (request, context) =>
- {
- logger.Trace($"{nameof(SetDeviceReceiveCommandAsync)}: DeviceClient command: {request.CommandName}.");
-
- try
+ await deviceClient
+ .SubscribeToCommandsAsync(
+ request =>
{
- var valueToTest = request.GetData();
- if (string.IsNullOrEmpty(componentName))
+ logger.Trace($"{nameof(SetDeviceReceiveCommandAsync)}: DeviceClient command: {request.CommandName}.");
+
+ try
{
- Assert.AreEqual(null, request.ComponentName, $"The expected component name should be null but was {request.ComponentName}");
+ var valueToTest = request.GetPayload();
+ if (string.IsNullOrEmpty(componentName))
+ {
+ request.ComponentName.Should().BeNull();
+ }
+ else
+ {
+ request.ComponentName.Should().Be(componentName);
+ }
+ var assertionObject = new ServiceCommandRequestAssertion();
+ string responseExpected = JsonConvert.SerializeObject(assertionObject);
+ request.GetPayloadAsString().Should().Be(responseExpected);
+ valueToTest.A.Should().Be(assertionObject.A, "The expected response object should decode properly.");
+ commandCallReceived.SetResult(true);
}
- else
+ catch (Exception ex)
{
- Assert.AreEqual(componentName, request.ComponentName, $"The expected component name should be {componentName} but was {request.ComponentName}");
+ commandCallReceived.SetException(ex);
}
- var assertionObject = new ServiceCommandRequestAssertion();
- string responseExpected = JsonConvert.SerializeObject(assertionObject);
- Assert.AreEqual(responseExpected, request.DataAsJson, $"The expected response payload should be {responseExpected} but was {request.DataAsJson}");
- Assert.AreEqual(assertionObject.A, valueToTest.A, $"The expected response object did not decode properly. Value a should be {assertionObject.A} but was {valueToTest?.A ?? int.MinValue}");
- commandCallReceived.SetResult(true);
- }
- catch (Exception ex)
- {
- commandCallReceived.SetException(ex);
- }
- return Task.FromResult(new CommandResponse(new DeviceCommandResponse(), 200));
- },
- null).ConfigureAwait(false);
+ return Task.FromResult(new CommandResponse(new DeviceCommandResponse(), 200));
+ })
+ .ConfigureAwait(false);
// Return the task that tells us we have received the callback.
return commandCallReceived.Task;
diff --git a/e2e/test/iothub/messaging/AzureSecurityCenterForIoTSecurityMessageE2ETests.cs b/e2e/test/iothub/messaging/AzureSecurityCenterForIoTSecurityMessageE2ETests.cs
index a1927d5160..608ff56129 100644
--- a/e2e/test/iothub/messaging/AzureSecurityCenterForIoTSecurityMessageE2ETests.cs
+++ b/e2e/test/iothub/messaging/AzureSecurityCenterForIoTSecurityMessageE2ETests.cs
@@ -92,7 +92,7 @@ private Client.Message ComposeD2CSecurityTestMessage()
private JObject ComposeAzureSecurityCenterForIoTSecurityMessagePayload(string eventId)
{
- var now = DateTime.UtcNow;
+ DateTime now = DateTime.UtcNow;
return new JObject
{
{ "AgentVersion", "0.0.1" },
diff --git a/e2e/test/iothub/messaging/FaultInjectionPoolAmqpTests.MessageReceiveFaultInjectionPoolAmqpTests.cs b/e2e/test/iothub/messaging/FaultInjectionPoolAmqpTests.MessageReceiveFaultInjectionPoolAmqpTests.cs
index e23297a804..9247448d96 100644
--- a/e2e/test/iothub/messaging/FaultInjectionPoolAmqpTests.MessageReceiveFaultInjectionPoolAmqpTests.cs
+++ b/e2e/test/iothub/messaging/FaultInjectionPoolAmqpTests.MessageReceiveFaultInjectionPoolAmqpTests.cs
@@ -953,7 +953,7 @@ await FaultInjectionPoolingOverAmqp
string proxyAddress = null)
{
// Initialize the service client
- ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.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 8f0ab42de0..239f3aad9c 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
{
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(logger, s_devicePrefix, type).ConfigureAwait(false);
using (DeviceClient deviceClient = testDevice.CreateDeviceClient(transport))
- using (ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString))
+ using (var serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString))
{
await deviceClient.OpenAsync().ConfigureAwait(false);
@@ -61,7 +61,7 @@ private static async Task CompleteMessageMixOrder(TestDeviceType type, Client.Tr
for (int i = 0; i < MESSAGE_COUNT; i++)
{
- Stopwatch stopwatch = new Stopwatch();
+ var stopwatch = new Stopwatch();
stopwatch.Start();
await deviceClient.CompleteAsync(messages[MESSAGE_COUNT - 1 - i]).ConfigureAwait(false);
stopwatch.Stop();
diff --git a/e2e/test/iothub/messaging/MessageReceiveE2ETests.cs b/e2e/test/iothub/messaging/MessageReceiveE2ETests.cs
index e3e58f40f1..98762ff820 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
{
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false);
using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport);
- using ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.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
{
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false);
using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport);
- using ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.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 ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.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 ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.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
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false);
using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport);
- using ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.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 ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.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 ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.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/MessageSendE2ETests.cs b/e2e/test/iothub/messaging/MessageSendE2ETests.cs
index 5872b277e7..4ff3f6024c 100644
--- a/e2e/test/iothub/messaging/MessageSendE2ETests.cs
+++ b/e2e/test/iothub/messaging/MessageSendE2ETests.cs
@@ -68,18 +68,18 @@ public async Task Message_DeviceSendSingleMessage_Http()
[LoggedTestMethod]
public async Task Message_DeviceSendSingleMessage_Amqp_WithHeartbeats()
{
- Client.AmqpTransportSettings amqpTransportSettings = new Client.AmqpTransportSettings(Client.TransportType.Amqp_Tcp_Only);
+ var amqpTransportSettings = new Client.AmqpTransportSettings(Client.TransportType.Amqp_Tcp_Only);
amqpTransportSettings.IdleTimeout = TimeSpan.FromMinutes(2);
- ITransportSettings[] transportSettings = new ITransportSettings[] { amqpTransportSettings };
+ var transportSettings = new ITransportSettings[] { amqpTransportSettings };
await SendSingleMessage(TestDeviceType.Sasl, transportSettings).ConfigureAwait(false);
}
[LoggedTestMethod]
public async Task Message_DeviceSendSingleMessage_AmqpWs_WithHeartbeats()
{
- Client.AmqpTransportSettings amqpTransportSettings = new Client.AmqpTransportSettings(Client.TransportType.Amqp_WebSocket_Only);
+ var amqpTransportSettings = new Client.AmqpTransportSettings(Client.TransportType.Amqp_WebSocket_Only);
amqpTransportSettings.IdleTimeout = TimeSpan.FromMinutes(2);
- ITransportSettings[] transportSettings = new ITransportSettings[] { amqpTransportSettings };
+ var transportSettings = new ITransportSettings[] { amqpTransportSettings };
await SendSingleMessage(TestDeviceType.Sasl, transportSettings).ConfigureAwait(false);
}
@@ -89,9 +89,9 @@ public async Task Message_DeviceSendSingleMessage_AmqpWs_WithHeartbeats()
[TestCategory("LongRunning")]
public async Task Message_DeviceSendSingleMessage_Http_WithProxy()
{
- Client.Http1TransportSettings httpTransportSettings = new Client.Http1TransportSettings();
+ var httpTransportSettings = new Client.Http1TransportSettings();
httpTransportSettings.Proxy = new WebProxy(s_proxyServerAddress);
- ITransportSettings[] transportSettings = new ITransportSettings[] { httpTransportSettings };
+ var transportSettings = new ITransportSettings[] { httpTransportSettings };
await SendSingleMessage(TestDeviceType.Sasl, transportSettings).ConfigureAwait(false);
}
@@ -100,10 +100,10 @@ public async Task Message_DeviceSendSingleMessage_Http_WithProxy()
[TestCategory("Proxy")]
public async Task Message_DeviceSendSingleMessage_Http_WithCustomProxy()
{
- Http1TransportSettings httpTransportSettings = new Http1TransportSettings();
- CustomWebProxy proxy = new CustomWebProxy(Logger);
+ var httpTransportSettings = new Http1TransportSettings();
+ var proxy = new CustomWebProxy(Logger);
httpTransportSettings.Proxy = proxy;
- ITransportSettings[] transportSettings = new ITransportSettings[] { httpTransportSettings };
+ var transportSettings = new ITransportSettings[] { httpTransportSettings };
await SendSingleMessage(TestDeviceType.Sasl, transportSettings).ConfigureAwait(false);
Assert.AreNotEqual(proxy.Counter, 0);
@@ -114,9 +114,9 @@ public async Task Message_DeviceSendSingleMessage_Http_WithCustomProxy()
[TestCategory("LongRunning")]
public async Task Message_DeviceSendSingleMessage_AmqpWs_WithProxy()
{
- Client.AmqpTransportSettings amqpTransportSettings = new Client.AmqpTransportSettings(Client.TransportType.Amqp_WebSocket_Only);
+ var amqpTransportSettings = new Client.AmqpTransportSettings(Client.TransportType.Amqp_WebSocket_Only);
amqpTransportSettings.Proxy = new WebProxy(s_proxyServerAddress);
- ITransportSettings[] transportSettings = new ITransportSettings[] { amqpTransportSettings };
+ var transportSettings = new ITransportSettings[] { amqpTransportSettings };
await SendSingleMessage(TestDeviceType.Sasl, transportSettings).ConfigureAwait(false);
}
@@ -125,10 +125,10 @@ public async Task Message_DeviceSendSingleMessage_AmqpWs_WithProxy()
[TestCategory("Proxy")]
public async Task Message_DeviceSendSingleMessage_MqttWs_WithProxy()
{
- Client.Transport.Mqtt.MqttTransportSettings mqttTransportSettings =
+ var mqttTransportSettings =
new Client.Transport.Mqtt.MqttTransportSettings(Client.TransportType.Mqtt_WebSocket_Only);
mqttTransportSettings.Proxy = new WebProxy(s_proxyServerAddress);
- ITransportSettings[] transportSettings = new ITransportSettings[] { mqttTransportSettings };
+ var transportSettings = new ITransportSettings[] { mqttTransportSettings };
await SendSingleMessage(TestDeviceType.Sasl, transportSettings).ConfigureAwait(false);
}
@@ -137,9 +137,9 @@ public async Task Message_DeviceSendSingleMessage_MqttWs_WithProxy()
[TestCategory("Proxy")]
public async Task Message_ModuleSendSingleMessage_AmqpWs_WithProxy()
{
- Client.AmqpTransportSettings amqpTransportSettings = new Client.AmqpTransportSettings(Client.TransportType.Amqp_WebSocket_Only);
+ var amqpTransportSettings = new Client.AmqpTransportSettings(Client.TransportType.Amqp_WebSocket_Only);
amqpTransportSettings.Proxy = new WebProxy(s_proxyServerAddress);
- ITransportSettings[] transportSettings = new ITransportSettings[] { amqpTransportSettings };
+ var transportSettings = new ITransportSettings[] { amqpTransportSettings };
await SendSingleMessageModule(transportSettings).ConfigureAwait(false);
}
@@ -148,10 +148,10 @@ public async Task Message_ModuleSendSingleMessage_AmqpWs_WithProxy()
[TestCategory("Proxy")]
public async Task Message_ModuleSendSingleMessage_MqttWs_WithProxy()
{
- Client.Transport.Mqtt.MqttTransportSettings mqttTransportSettings =
+ var mqttTransportSettings =
new Client.Transport.Mqtt.MqttTransportSettings(Client.TransportType.Mqtt_WebSocket_Only);
mqttTransportSettings.Proxy = new WebProxy(s_proxyServerAddress);
- ITransportSettings[] transportSettings = new ITransportSettings[] { mqttTransportSettings };
+ var transportSettings = new ITransportSettings[] { mqttTransportSettings };
await SendSingleMessageModule(transportSettings).ConfigureAwait(false);
}
diff --git a/e2e/test/iothub/method/MethodE2ETests.cs b/e2e/test/iothub/method/MethodE2ETests.cs
index 973b2dcfbb..5717254ff6 100644
--- a/e2e/test/iothub/method/MethodE2ETests.cs
+++ b/e2e/test/iothub/method/MethodE2ETests.cs
@@ -159,7 +159,7 @@ public async Task Method_ServiceSendsMethodThroughProxyWithCustomTimeout()
public async Task Method_ServiceInvokeDeviceMethodWithUnknownDeviceThrows()
{
// setup
- using ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.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
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, "ModuleNotFoundTest").ConfigureAwait(false);
- using ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ using var serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
var methodInvocation = new CloudToDeviceMethod("SetTelemetryInterval");
methodInvocation.SetPayloadJson("10");
@@ -283,7 +283,7 @@ await deviceClient
.ConfigureAwait(false);
using var serviceClient = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
- var c2dMethod = new CloudToDeviceMethod(commandName, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1)).SetPayloadJson(null);
+ CloudToDeviceMethod c2dMethod = new CloudToDeviceMethod(commandName, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1)).SetPayloadJson(null);
// act
@@ -572,7 +572,7 @@ public static async Task SetModuleReceiveMethodDefaultHandlerAsync(ModuleC
ServiceClientTransportSettings serviceClientTransportSettings = default)
{
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);
- using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
+ using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
await subscribeAndUnsubscribeMethod(deviceClient, MethodName, Logger).ConfigureAwait(false);
@@ -588,7 +588,7 @@ public static async Task SetModuleReceiveMethodDefaultHandlerAsync(ModuleC
ServiceClientTransportSettings serviceClientTransportSettings = default)
{
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);
- using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
+ using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
Task methodReceivedTask = await setDeviceReceiveMethod(deviceClient, MethodName, Logger).ConfigureAwait(false);
Task serviceSendTask = ServiceSendMethodAndVerifyResponseAsync(
@@ -608,7 +608,7 @@ public static async Task SetModuleReceiveMethodDefaultHandlerAsync(ModuleC
private async Task SendMethodAndRespondAsync(Client.TransportType transport, Func> setDeviceReceiveMethod, TimeSpan responseTimeout = default, ServiceClientTransportSettings serviceClientTransportSettings = default)
{
TestModule testModule = await TestModule.GetTestModuleAsync(_devicePrefix, _modulePrefix, Logger).ConfigureAwait(false);
- using ModuleClient moduleClient = ModuleClient.CreateFromConnectionString(testModule.ConnectionString, transport);
+ using var moduleClient = ModuleClient.CreateFromConnectionString(testModule.ConnectionString, transport);
Task methodReceivedTask = await setDeviceReceiveMethod(moduleClient, MethodName, Logger).ConfigureAwait(false);
diff --git a/e2e/test/iothub/method/MethodFaultInjectionTests.cs b/e2e/test/iothub/method/MethodFaultInjectionTests.cs
index 4b33787d59..1f08a07cfd 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(TestConfiguration.IoTHub.ConnectionString);
+ using var 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 6d68028541..580a394e4c 100644
--- a/e2e/test/iothub/properties/PropertiesE2ETests.cs
+++ b/e2e/test/iothub/properties/PropertiesE2ETests.cs
@@ -206,19 +206,18 @@ private async Task Properties_ServiceSetsWritablePropertyAndDeviceUnsubscribes(C
// Set a callback
await deviceClient.
SubscribeToWritablePropertyUpdateRequestsAsync(
- (patch, context) =>
+ patch =>
{
Assert.Fail("After having unsubscribed from receiving client property update notifications " +
"this callback should not have been invoked.");
return Task.FromResult(true);
- },
- null)
+ })
.ConfigureAwait(false);
// Unsubscribe
await deviceClient
- .SubscribeToWritablePropertyUpdateRequestsAsync(null, null)
+ .SubscribeToWritablePropertyUpdateRequestsAsync(null)
.ConfigureAwait(false);
await RegistryManagerUpdateWritablePropertyAsync(testDevice.Id, propName, propValue)
@@ -261,7 +260,7 @@ await Task
string serializedActualPropertyValue = JsonConvert.SerializeObject(actualProp);
serializedActualPropertyValue.Should().Be(JsonConvert.SerializeObject(propValue));
- await deviceClient.SubscribeToWritablePropertyUpdateRequestsAsync(null, null).ConfigureAwait(false);
+ await deviceClient.SubscribeToWritablePropertyUpdateRequestsAsync(null).ConfigureAwait(false);
await deviceClient.CloseAsync().ConfigureAwait(false);
}
@@ -278,7 +277,7 @@ private async Task Properties_ServiceSetsWritablePropertyAndDeviceReceivesEventA
using var writablePropertyCallbackSemaphore = new SemaphoreSlim(0, 1);
await deviceClient
.SubscribeToWritablePropertyUpdateRequestsAsync(
- async (writableProperties, userContext) =>
+ async (writableProperties) =>
{
try
{
@@ -286,7 +285,6 @@ await deviceClient
isPropertyPresent.Should().BeTrue();
propertyFromCollection.Should().BeEquivalentTo(propValue);
- userContext.Should().BeNull();
var writablePropertyAcks = new ClientPropertyCollection();
foreach (KeyValuePair writableProperty in writableProperties)
@@ -304,7 +302,6 @@ await deviceClient
writablePropertyCallbackSemaphore.Release();
}
},
- null,
cts.Token)
.ConfigureAwait(false);
diff --git a/e2e/test/iothub/properties/PropertiesWithComponentsE2ETests.cs b/e2e/test/iothub/properties/PropertiesWithComponentsE2ETests.cs
index 31db30de03..a970dc28c8 100644
--- a/e2e/test/iothub/properties/PropertiesWithComponentsE2ETests.cs
+++ b/e2e/test/iothub/properties/PropertiesWithComponentsE2ETests.cs
@@ -215,19 +215,18 @@ private async Task PropertiesWithComponents_ServiceSetsWritablePropertyAndDevice
// Set a callback
await deviceClient.
SubscribeToWritablePropertyUpdateRequestsAsync(
- (patch, context) =>
+ patch =>
{
Assert.Fail("After having unsubscribed from receiving client property update notifications " +
"this callback should not have been invoked.");
return Task.FromResult(true);
- },
- null)
+ })
.ConfigureAwait(false);
// Unsubscribe
await deviceClient
- .SubscribeToWritablePropertyUpdateRequestsAsync(null, null)
+ .SubscribeToWritablePropertyUpdateRequestsAsync(null)
.ConfigureAwait(false);
await RegistryManagerUpdateWritablePropertyAsync(testDevice.Id, ComponentName, propName, propValue)
@@ -270,7 +269,7 @@ await Task
string serializedActualPropertyValue = JsonConvert.SerializeObject(actualProp);
serializedActualPropertyValue.Should().Be(JsonConvert.SerializeObject(propValue));
- await deviceClient.SubscribeToWritablePropertyUpdateRequestsAsync(null, null).ConfigureAwait(false);
+ await deviceClient.SubscribeToWritablePropertyUpdateRequestsAsync(null).ConfigureAwait(false);
await deviceClient.CloseAsync().ConfigureAwait(false);
}
@@ -287,7 +286,7 @@ private async Task PropertiesWithComponents_ServiceSetsWritablePropertyAndDevice
using var writablePropertyCallbackSemaphore = new SemaphoreSlim(0, 1);
await deviceClient
.SubscribeToWritablePropertyUpdateRequestsAsync(
- async (writableProperties, userContext) =>
+ async (writableProperties) =>
{
try
{
@@ -295,7 +294,6 @@ await deviceClient
isPropertyPresent.Should().BeTrue();
propertyFromCollection.Should().BeEquivalentTo(propValue);
- userContext.Should().BeNull();
var writablePropertyAcks = new ClientPropertyCollection();
foreach (KeyValuePair writableProperty in writableProperties)
@@ -319,7 +317,6 @@ await deviceClient
writablePropertyCallbackSemaphore.Release();
}
},
- null,
cts.Token)
.ConfigureAwait(false);
diff --git a/e2e/test/iothub/service/BulkOperationsE2ETests.cs b/e2e/test/iothub/service/BulkOperationsE2ETests.cs
index 53ebc5c813..bf686384f0 100644
--- a/e2e/test/iothub/service/BulkOperationsE2ETests.cs
+++ b/e2e/test/iothub/service/BulkOperationsE2ETests.cs
@@ -21,18 +21,18 @@ public class BulkOperationsE2ETests : E2EMsTestBase
[LoggedTestMethod]
public async Task BulkOperations_UpdateTwins2Device_Ok()
{
- var tagName = Guid.NewGuid().ToString();
- var tagValue = Guid.NewGuid().ToString();
+ string tagName = Guid.NewGuid().ToString();
+ string tagValue = Guid.NewGuid().ToString();
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false);
- using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
Twin twin = await registryManager.GetTwinAsync(testDevice.Id).ConfigureAwait(false);
twin.Tags = new TwinCollection();
twin.Tags[tagName] = tagValue;
- var result = await registryManager.UpdateTwins2Async(new List { twin }, true).ConfigureAwait(false);
+ BulkRegistryOperationResult result = await registryManager.UpdateTwins2Async(new List { twin }, true).ConfigureAwait(false);
Assert.IsTrue(result.IsSuccessful, $"UpdateTwins2Async error:\n{ResultErrorsToString(result)}");
Twin twinUpd = await registryManager.GetTwinAsync(testDevice.Id).ConfigureAwait(false);
@@ -48,18 +48,18 @@ public async Task BulkOperations_UpdateTwins2Device_Ok()
[LoggedTestMethod]
public async Task BulkOperations_UpdateTwins2DevicePatch_Ok()
{
- var tagName = Guid.NewGuid().ToString();
- var tagValue = Guid.NewGuid().ToString();
+ string tagName = Guid.NewGuid().ToString();
+ string tagValue = Guid.NewGuid().ToString();
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false);
- using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
- Twin twin = new Twin();
+ var twin = new Twin();
twin.DeviceId = testDevice.Id;
twin.Tags = new TwinCollection();
twin.Tags[tagName] = tagValue;
- var result = await registryManager.UpdateTwins2Async(new List { twin }, true).ConfigureAwait(false);
+ BulkRegistryOperationResult result = await registryManager.UpdateTwins2Async(new List { twin }, true).ConfigureAwait(false);
Assert.IsTrue(result.IsSuccessful, $"UpdateTwins2Async error:\n{ResultErrorsToString(result)}");
Twin twinUpd = await registryManager.GetTwinAsync(testDevice.Id).ConfigureAwait(false);
@@ -75,18 +75,18 @@ public async Task BulkOperations_UpdateTwins2DevicePatch_Ok()
[LoggedTestMethod]
public async Task BulkOperations_UpdateTwins2Module_Ok()
{
- var tagName = Guid.NewGuid().ToString();
- var tagValue = Guid.NewGuid().ToString();
+ string tagName = Guid.NewGuid().ToString();
+ string tagValue = Guid.NewGuid().ToString();
TestModule testModule = await TestModule.GetTestModuleAsync(DevicePrefix, ModulePrefix, Logger).ConfigureAwait(false);
- using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
Twin twin = await registryManager.GetTwinAsync(testModule.DeviceId, testModule.Id).ConfigureAwait(false);
twin.Tags = new TwinCollection();
twin.Tags[tagName] = tagValue;
- var result = await registryManager.UpdateTwins2Async(new List { twin }, true).ConfigureAwait(false);
+ BulkRegistryOperationResult result = await registryManager.UpdateTwins2Async(new List { twin }, true).ConfigureAwait(false);
Assert.IsTrue(result.IsSuccessful, $"UpdateTwins2Async error:\n{ResultErrorsToString(result)}");
Twin twinUpd = await registryManager.GetTwinAsync(testModule.DeviceId, testModule.Id).ConfigureAwait(false);
@@ -103,19 +103,19 @@ public async Task BulkOperations_UpdateTwins2Module_Ok()
[LoggedTestMethod]
public async Task BulkOperations_UpdateTwins2ModulePatch_Ok()
{
- var tagName = Guid.NewGuid().ToString();
- var tagValue = Guid.NewGuid().ToString();
+ string tagName = Guid.NewGuid().ToString();
+ string tagValue = Guid.NewGuid().ToString();
TestModule testModule = await TestModule.GetTestModuleAsync(DevicePrefix, ModulePrefix, Logger).ConfigureAwait(false);
- using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
var twin = new Twin();
twin.DeviceId = testModule.DeviceId;
twin.ModuleId = testModule.Id;
twin.Tags = new TwinCollection();
twin.Tags[tagName] = tagValue;
- var result = await registryManager.UpdateTwins2Async(new List { twin }, true).ConfigureAwait(false);
+ BulkRegistryOperationResult result = await registryManager.UpdateTwins2Async(new List { twin }, true).ConfigureAwait(false);
Assert.IsTrue(result.IsSuccessful, $"UpdateTwins2Async error:\n{ResultErrorsToString(result)}");
Twin twinUpd = await registryManager.GetTwinAsync(testModule.DeviceId, testModule.Id).ConfigureAwait(false);
@@ -131,9 +131,9 @@ public async Task BulkOperations_UpdateTwins2ModulePatch_Ok()
private string ResultErrorsToString(BulkRegistryOperationResult result)
{
- var errorString = "";
+ string errorString = "";
- foreach (var error in result.Errors)
+ foreach (DeviceRegistryOperationError error in result.Errors)
{
errorString += $"\t{error.ErrorCode} : {error.ErrorStatus}\n";
}
diff --git a/e2e/test/iothub/service/IoTHubCertificateValidationE2ETest.cs b/e2e/test/iothub/service/IoTHubCertificateValidationE2ETest.cs
index 0047b1bc78..932020154a 100644
--- a/e2e/test/iothub/service/IoTHubCertificateValidationE2ETest.cs
+++ b/e2e/test/iothub/service/IoTHubCertificateValidationE2ETest.cs
@@ -19,7 +19,7 @@ public class IoTHubCertificateValidationE2ETest : E2EMsTestBase
[LoggedTestMethod]
public async Task RegistryManager_QueryDevicesInvalidServiceCertificateHttp_Fails()
{
- using RegistryManager rm = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionStringInvalidServiceCertificate);
+ using var rm = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionStringInvalidServiceCertificate);
IQuery query = rm.CreateQuery("select * from devices");
IotHubCommunicationException exception = await Assert.ThrowsExceptionAsync(
() => query.GetNextAsTwinAsync()).ConfigureAwait(false);
@@ -34,7 +34,7 @@ public async Task RegistryManager_QueryDevicesInvalidServiceCertificateHttp_Fail
[LoggedTestMethod]
public async Task ServiceClient_SendMessageToDeviceInvalidServiceCertificateAmqpTcp_Fails()
{
- var transport = TransportType.Amqp;
+ TransportType transport = TransportType.Amqp;
await Assert.ThrowsExceptionAsync(
() => TestServiceClientInvalidServiceCertificate(transport)).ConfigureAwait(false);
}
@@ -42,8 +42,8 @@ public async Task ServiceClient_SendMessageToDeviceInvalidServiceCertificateAmqp
[LoggedTestMethod]
public async Task ServiceClient_SendMessageToDeviceInvalidServiceCertificateAmqpWs_Fails()
{
- var transport = TransportType.Amqp_WebSocket_Only;
- var exception = await Assert.ThrowsExceptionAsync(
+ TransportType transport = TransportType.Amqp_WebSocket_Only;
+ WebSocketException exception = await Assert.ThrowsExceptionAsync(
() => TestServiceClientInvalidServiceCertificate(transport)).ConfigureAwait(false);
Assert.IsInstanceOfType(exception.InnerException.InnerException, typeof(AuthenticationException));
@@ -51,7 +51,7 @@ public async Task ServiceClient_SendMessageToDeviceInvalidServiceCertificateAmqp
private static async Task TestServiceClientInvalidServiceCertificate(TransportType transport)
{
- using ServiceClient service = ServiceClient.CreateFromConnectionString(
+ using var service = ServiceClient.CreateFromConnectionString(
TestConfiguration.IoTHub.ConnectionStringInvalidServiceCertificate,
transport);
using var testMessage = new Message();
@@ -61,8 +61,8 @@ private static async Task TestServiceClientInvalidServiceCertificate(TransportTy
[LoggedTestMethod]
public async Task JobClient_ScheduleTwinUpdateInvalidServiceCertificateHttp_Fails()
{
- using JobClient jobClient = JobClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionStringInvalidServiceCertificate);
- var exception = await Assert.ThrowsExceptionAsync(
+ using var jobClient = JobClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionStringInvalidServiceCertificate);
+ IotHubCommunicationException exception = await Assert.ThrowsExceptionAsync(
() => jobClient.ScheduleTwinUpdateAsync(
"testDevice",
"DeviceId IN ['testDevice']",
@@ -80,7 +80,7 @@ public async Task JobClient_ScheduleTwinUpdateInvalidServiceCertificateHttp_Fail
[LoggedTestMethod]
public async Task DeviceClient_SendAsyncInvalidServiceCertificateAmqpTcp_Fails()
{
- var transport = Client.TransportType.Amqp_Tcp_Only;
+ Client.TransportType transport = Client.TransportType.Amqp_Tcp_Only;
await Assert.ThrowsExceptionAsync(
() => TestDeviceClientInvalidServiceCertificate(transport)).ConfigureAwait(false);
}
@@ -88,7 +88,7 @@ public async Task DeviceClient_SendAsyncInvalidServiceCertificateAmqpTcp_Fails()
[LoggedTestMethod]
public async Task DeviceClient_SendAsyncInvalidServiceCertificateMqttTcp_Fails()
{
- var transport = Client.TransportType.Mqtt_Tcp_Only;
+ Client.TransportType transport = Client.TransportType.Mqtt_Tcp_Only;
await Assert.ThrowsExceptionAsync(
() => TestDeviceClientInvalidServiceCertificate(transport)).ConfigureAwait(false);
}
@@ -96,8 +96,8 @@ public async Task DeviceClient_SendAsyncInvalidServiceCertificateMqttTcp_Fails()
[LoggedTestMethod]
public async Task DeviceClient_SendAsyncInvalidServiceCertificateHttp_Fails()
{
- var transport = Client.TransportType.Http1;
- var exception = await Assert.ThrowsExceptionAsync(
+ Client.TransportType transport = Client.TransportType.Http1;
+ AuthenticationException exception = await Assert.ThrowsExceptionAsync(
() => TestDeviceClientInvalidServiceCertificate(transport)).ConfigureAwait(false);
#if NET451 || NET472
@@ -110,8 +110,8 @@ public async Task DeviceClient_SendAsyncInvalidServiceCertificateHttp_Fails()
[LoggedTestMethod]
public async Task DeviceClient_SendAsyncInvalidServiceCertificateAmqpWs_Fails()
{
- var transport = Client.TransportType.Amqp_WebSocket_Only;
- var exception = await Assert.ThrowsExceptionAsync(
+ Client.TransportType transport = Client.TransportType.Amqp_WebSocket_Only;
+ AuthenticationException exception = await Assert.ThrowsExceptionAsync(
() => TestDeviceClientInvalidServiceCertificate(transport)).ConfigureAwait(false);
Assert.IsInstanceOfType(exception.InnerException.InnerException.InnerException, typeof(AuthenticationException));
@@ -120,8 +120,8 @@ public async Task DeviceClient_SendAsyncInvalidServiceCertificateAmqpWs_Fails()
[LoggedTestMethod]
public async Task DeviceClient_SendAsyncInvalidServiceCertificateMqttWs_Fails()
{
- var transport = Client.TransportType.Mqtt_WebSocket_Only;
- var exception = await Assert.ThrowsExceptionAsync(
+ Client.TransportType transport = Client.TransportType.Mqtt_WebSocket_Only;
+ AuthenticationException exception = await Assert.ThrowsExceptionAsync(
() => TestDeviceClientInvalidServiceCertificate(transport)).ConfigureAwait(false);
Assert.IsInstanceOfType(exception.InnerException.InnerException.InnerException, typeof(AuthenticationException));
@@ -129,15 +129,13 @@ public async Task DeviceClient_SendAsyncInvalidServiceCertificateMqttWs_Fails()
private static async Task TestDeviceClientInvalidServiceCertificate(Client.TransportType transport)
{
- using (DeviceClient deviceClient =
+ using var deviceClient =
DeviceClient.CreateFromConnectionString(
TestConfiguration.IoTHub.DeviceConnectionStringInvalidServiceCertificate,
- transport))
- {
- using var testMessage = new Client.Message();
- await deviceClient.SendEventAsync(testMessage).ConfigureAwait(false);
- await deviceClient.CloseAsync().ConfigureAwait(false);
- }
+ transport);
+ using var testMessage = new Client.Message();
+ await deviceClient.SendEventAsync(testMessage).ConfigureAwait(false);
+ await deviceClient.CloseAsync().ConfigureAwait(false);
}
}
}
diff --git a/e2e/test/iothub/service/IoTHubServiceProxyE2ETests.cs b/e2e/test/iothub/service/IoTHubServiceProxyE2ETests.cs
index 0cf3a69c07..24a2d778e6 100644
--- a/e2e/test/iothub/service/IoTHubServiceProxyE2ETests.cs
+++ b/e2e/test/iothub/service/IoTHubServiceProxyE2ETests.cs
@@ -30,7 +30,7 @@ public class IoTHubServiceProxyE2ETests : E2EMsTestBase
[LoggedTestMethod]
public async Task ServiceClient_Message_SendSingleMessage_WithProxy()
{
- ServiceClientTransportSettings transportSettings = new ServiceClientTransportSettings();
+ var transportSettings = new ServiceClientTransportSettings();
transportSettings.AmqpProxy = new WebProxy(s_proxyServerAddress);
transportSettings.HttpProxy = new WebProxy(s_proxyServerAddress);
@@ -40,7 +40,7 @@ public async Task ServiceClient_Message_SendSingleMessage_WithProxy()
[LoggedTestMethod]
public async Task RegistryManager_AddAndRemoveDevice_WithProxy()
{
- HttpTransportSettings httpTransportSettings = new HttpTransportSettings();
+ var httpTransportSettings = new HttpTransportSettings();
httpTransportSettings.Proxy = new WebProxy(s_proxyServerAddress);
await RegistryManager_AddDevice(httpTransportSettings).ConfigureAwait(false);
@@ -49,7 +49,7 @@ public async Task RegistryManager_AddAndRemoveDevice_WithProxy()
[LoggedTestMethod]
public async Task JobClient_ScheduleAndRunTwinJob_WithProxy()
{
- HttpTransportSettings httpTransportSettings = new HttpTransportSettings();
+ var httpTransportSettings = new HttpTransportSettings();
httpTransportSettings.Proxy = new WebProxy(s_proxyServerAddress);
await JobClient_ScheduleAndRunTwinJob(httpTransportSettings).ConfigureAwait(false);
@@ -58,8 +58,8 @@ public async Task JobClient_ScheduleAndRunTwinJob_WithProxy()
private async Task SendSingleMessageService(ServiceClientTransportSettings transportSettings)
{
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false);
- using (DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString))
- using (ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(s_connectionString, TransportType.Amqp, transportSettings))
+ using (var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString))
+ using (var serviceClient = ServiceClient.CreateFromConnectionString(s_connectionString, TransportType.Amqp, transportSettings))
{
(Message testMessage, string messageId, string payload, string p1Value) = ComposeD2CTestMessage();
await serviceClient.SendAsync(testDevice.Id, testMessage).ConfigureAwait(false);
@@ -73,7 +73,7 @@ private async Task RegistryManager_AddDevice(HttpTransportSettings httpTransport
{
string deviceName = DevicePrefix + Guid.NewGuid();
- using (RegistryManager registryManager = RegistryManager.CreateFromConnectionString(s_connectionString, httpTransportSettings))
+ using (var registryManager = RegistryManager.CreateFromConnectionString(s_connectionString, httpTransportSettings))
{
await registryManager.AddDeviceAsync(new Device(deviceName)).ConfigureAwait(false);
await registryManager.RemoveDeviceAsync(deviceName).ConfigureAwait(false);
@@ -82,11 +82,11 @@ private async Task RegistryManager_AddDevice(HttpTransportSettings httpTransport
private async Task JobClient_ScheduleAndRunTwinJob(HttpTransportSettings httpTransportSettings)
{
- Twin twin = new Twin(JobDeviceId);
+ var twin = new Twin(JobDeviceId);
twin.Tags = new TwinCollection();
twin.Tags[JobTestTagName] = JobDeviceId;
- using (JobClient jobClient = JobClient.CreateFromConnectionString(s_connectionString, httpTransportSettings))
+ using (var jobClient = JobClient.CreateFromConnectionString(s_connectionString, httpTransportSettings))
{
int tryCount = 0;
while (true)
@@ -111,9 +111,9 @@ private async Task JobClient_ScheduleAndRunTwinJob(HttpTransportSettings httpTra
private (Message message, string messageId, string payload, string p1Value) ComposeD2CTestMessage()
{
- var messageId = Guid.NewGuid().ToString();
- var payload = Guid.NewGuid().ToString();
- var p1Value = Guid.NewGuid().ToString();
+ string messageId = Guid.NewGuid().ToString();
+ string payload = Guid.NewGuid().ToString();
+ string p1Value = Guid.NewGuid().ToString();
Logger.Trace($"{nameof(ComposeD2CTestMessage)}: messageId='{messageId}' payload='{payload}' p1Value='{p1Value}'");
var message = new Message(Encoding.UTF8.GetBytes(payload))
diff --git a/e2e/test/iothub/service/PnpServiceTests.cs b/e2e/test/iothub/service/PnpServiceTests.cs
index 631309c795..bd8f9c918f 100644
--- a/e2e/test/iothub/service/PnpServiceTests.cs
+++ b/e2e/test/iothub/service/PnpServiceTests.cs
@@ -38,13 +38,13 @@ public async Task DeviceTwin_Contains_ModelId()
{
ModelId = TestModelId,
};
- using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, Client.TransportType.Mqtt_Tcp_Only, options);
+ using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, Client.TransportType.Mqtt_Tcp_Only, options);
await deviceClient.OpenAsync().ConfigureAwait(false);
// Act
// Get device twin.
- using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
Twin twin = await registryManager.GetTwinAsync(testDevice.Device.Id).ConfigureAwait(false);
// Assert
@@ -69,13 +69,13 @@ public async Task DeviceTwin_Contains_ModelId_X509()
string hostName = HostNameHelper.GetHostName(TestConfiguration.IoTHub.ConnectionString);
X509Certificate2 authCertificate = TestConfiguration.IoTHub.GetCertificateWithPrivateKey();
using var auth = new DeviceAuthenticationWithX509Certificate(testDevice.Id, authCertificate);
- using DeviceClient deviceClient = DeviceClient.Create(hostName, auth, Client.TransportType.Mqtt_Tcp_Only, options);
+ using var deviceClient = DeviceClient.Create(hostName, auth, Client.TransportType.Mqtt_Tcp_Only, options);
await deviceClient.OpenAsync().ConfigureAwait(false);
// Act
// Get device twin.
- using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
Twin twin = await registryManager.GetTwinAsync(testDevice.Device.Id).ConfigureAwait(false);
// Assert
@@ -104,13 +104,13 @@ public async Task ModuleTwin_Contains_ModelId()
{
ModelId = TestModelId,
};
- using ModuleClient moduleClient = ModuleClient.CreateFromConnectionString(testModule.ConnectionString, Client.TransportType.Mqtt_Tcp_Only, options);
+ using var moduleClient = ModuleClient.CreateFromConnectionString(testModule.ConnectionString, Client.TransportType.Mqtt_Tcp_Only, options);
await moduleClient.OpenAsync().ConfigureAwait(false);
// Act
// Get module twin.
- using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.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 5729f9b7b4..e67c6ca723 100644
--- a/e2e/test/iothub/service/RegistryManagerE2ETests.cs
+++ b/e2e/test/iothub/service/RegistryManagerE2ETests.cs
@@ -26,7 +26,7 @@ public class RegistryManagerE2ETests : E2EMsTestBase
public async Task RegistryManager_BadProxy_ThrowsException()
{
// arrange
- using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(
+ using var registryManager = RegistryManager.CreateFromConnectionString(
TestConfiguration.IoTHub.ConnectionString,
new HttpTransportSettings
{
@@ -94,7 +94,7 @@ public async Task RegistryManager_AddDeviceWithTwinWithDeviceCapabilities()
{
string deviceId = _idPrefix + Guid.NewGuid();
- using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
var twin = new Twin
{
Tags = new TwinCollection(@"{ companyId: 1234 }"),
@@ -114,63 +114,195 @@ public async Task RegistryManager_AddDeviceWithTwinWithDeviceCapabilities()
}
[LoggedTestMethod]
- public async Task RegistryManager_BulkLifecycle()
+ public async Task RegistryManager_AddDevices2Async_Works()
{
- int bulkCount = 50;
- var devices = new List();
- for (int i = 0; i < bulkCount; i++)
+ // arrange
+
+ var edge = new Device(_idPrefix + Guid.NewGuid())
{
- var device = new Device(_idPrefix + Guid.NewGuid());
- device.Scope = "someScope" + Guid.NewGuid();
- device.ParentScopes.Add("someParentScope" + Guid.NewGuid());
- devices.Add(device);
- }
+ Scope = "someScope" + Guid.NewGuid(),
+ };
+ var device = new Device(_idPrefix + Guid.NewGuid())
+ {
+ Scope = edge.Scope,
+ };
- using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
- // Test that you can create devices in bulk
- BulkRegistryOperationResult bulkAddResult = await registryManager.AddDevices2Async(devices).ConfigureAwait(false);
- Assert.IsTrue(bulkAddResult.IsSuccessful);
+ try
+ {
+ // act
+ BulkRegistryOperationResult bulkAddResult = await registryManager
+ .AddDevices2Async(new List { edge, device })
+ .ConfigureAwait(false);
+
+ // assert
- foreach (Device device in devices)
+ bulkAddResult.IsSuccessful.Should().BeTrue();
+
+ Device actualEdge = await registryManager.GetDeviceAsync(edge.Id).ConfigureAwait(false);
+ actualEdge.Id.Should().Be(edge.Id);
+ actualEdge.Scope.Should().Be(edge.Scope);
+
+ Device actualDevice = await registryManager.GetDeviceAsync(device.Id).ConfigureAwait(false);
+ actualDevice.Id.Should().Be(device.Id);
+ actualDevice.Scope.Should().Be(device.Scope);
+ actualDevice.ParentScopes.Count.Should().Be(1);
+ actualDevice.ParentScopes.First().Should().Be(edge.Scope);
+ }
+ finally
{
- // After a bulk add, every device should be able to be retrieved
- Device retrievedDevice = await registryManager.GetDeviceAsync(device.Id).ConfigureAwait(false);
- Assert.IsNotNull(retrievedDevice.Id);
- Assert.AreEqual(device.Scope, retrievedDevice.Scope);
- Assert.AreEqual(1, retrievedDevice.ParentScopes.Count);
- Assert.AreEqual(device.ParentScopes.ElementAt(0), retrievedDevice.ParentScopes.ElementAt(0));
+ try
+ {
+ await registryManager.RemoveDeviceAsync(device.Id).ConfigureAwait(false);
+ await registryManager.RemoveDeviceAsync(edge.Id).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ Logger.Trace($"Failed to clean up devices due to {ex}");
+ }
}
+ }
+
+ [LoggedTestMethod]
+ public async Task RegistryManager_UpdateDevices2Async_Works()
+ {
+ // arrange
- var twins = new List();
- string expectedProperty = "someNewProperty";
- string expectedPropertyValue = "someNewPropertyValue";
- foreach (Device device in devices)
+ var device1 = new Device(_idPrefix + Guid.NewGuid());
+ var device2 = new Device(_idPrefix + Guid.NewGuid());
+ var edge = new Device(_idPrefix + Guid.NewGuid());
+ using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+
+ try
{
- Twin twin = await registryManager.GetTwinAsync(device.Id).ConfigureAwait(false);
- twin.Properties.Desired[expectedProperty] = expectedPropertyValue;
- twins.Add(twin);
+ Device addedDevice1 = await registryManager.AddDeviceAsync(device1).ConfigureAwait(false);
+ Device addedDevice2 = await registryManager.AddDeviceAsync(device2).ConfigureAwait(false);
+ Device addedEdge = await registryManager.AddDeviceAsync(edge).ConfigureAwait(false);
+
+ // act
+
+ addedDevice1.Scope = addedEdge.Scope;
+ addedDevice2.Scope = addedEdge.Scope;
+ BulkRegistryOperationResult result = await registryManager
+ .UpdateDevices2Async(new[] { addedDevice1, addedDevice2 })
+ .ConfigureAwait(false);
+
+ // assert
+
+ result.IsSuccessful.Should().BeTrue();
+
+ Device actualDevice1 = await registryManager.GetDeviceAsync(device1.Id).ConfigureAwait(false);
+ actualDevice1.Scope.Should().Be(addedEdge.Scope);
+
+ Device actualDevice2 = await registryManager.GetDeviceAsync(device2.Id).ConfigureAwait(false);
+ actualDevice2.Scope.Should().Be(addedEdge.Scope);
}
+ finally
+ {
+ try
+ {
+ await registryManager.RemoveDeviceAsync(device1.Id).ConfigureAwait(false);
+ await registryManager.RemoveDeviceAsync(device2.Id).ConfigureAwait(false);
+ await registryManager.RemoveDeviceAsync(edge.Id).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ Logger.Trace($"Failed to clean up devices due to {ex}");
+ }
+ }
+ }
- // Test that you can update twins in bulk
- await registryManager.UpdateTwins2Async(twins).ConfigureAwait(false);
+ [LoggedTestMethod]
+ public async Task RegistryManager_UpdateTwins2Async_Works()
+ {
+ // arrange
+
+ var device1 = new Device(_idPrefix + Guid.NewGuid());
+ var device2 = new Device(_idPrefix + Guid.NewGuid());
+ using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
- foreach (Device device in devices)
+ try
{
- Twin twin = await registryManager.GetTwinAsync(device.Id).ConfigureAwait(false);
- Assert.IsNotNull(twin.Properties.Desired[expectedProperty]);
- Assert.AreEqual(expectedPropertyValue, (string)twin.Properties.Desired[expectedProperty]);
+ await registryManager.AddDeviceAsync(device1).ConfigureAwait(false);
+ Twin twin1 = await registryManager.GetTwinAsync(device1.Id).ConfigureAwait(false);
+ await registryManager.AddDeviceAsync(device2).ConfigureAwait(false);
+ Twin twin2 = await registryManager.GetTwinAsync(device2.Id).ConfigureAwait(false);
+
+ // act
+
+ const string expectedProperty = "someNewProperty";
+ const string expectedPropertyValue = "someNewPropertyValue";
+
+ twin1.Properties.Desired[expectedProperty] = expectedPropertyValue;
+ twin2.Properties.Desired[expectedProperty] = expectedPropertyValue;
+
+ BulkRegistryOperationResult result = await registryManager
+ .UpdateTwins2Async(new[] { twin1, twin2 })
+ .ConfigureAwait(false);
+
+ // assert
+
+ result.IsSuccessful.Should().BeTrue();
+
+ var actualTwin1 = await registryManager.GetTwinAsync(device1.Id).ConfigureAwait(false);
+ ((string)actualTwin1.Properties.Desired[expectedProperty]).Should().Be(expectedPropertyValue);
+ var actualTwin2 = await registryManager.GetTwinAsync(device2.Id).ConfigureAwait(false);
+ ((string)(actualTwin2.Properties.Desired[expectedProperty])).Should().Be(expectedPropertyValue);
}
+ finally
+ {
+ try
+ {
+ await registryManager.RemoveDeviceAsync(device1.Id).ConfigureAwait(false);
+ await registryManager.RemoveDeviceAsync(device2.Id).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ Logger.Trace($"Failed to clean up devices due to {ex}");
+ }
+ }
+ }
- // Test that you can delete device identities in bulk
- BulkRegistryOperationResult bulkDeleteResult = await registryManager.RemoveDevices2Async(devices, true, default).ConfigureAwait(false);
+ [LoggedTestMethod]
+ public async Task RegistryManager_RemoveDevices2Async_Works()
+ {
+ // arrange
- Assert.IsTrue(bulkDeleteResult.IsSuccessful);
+ var device1 = new Device(_idPrefix + Guid.NewGuid());
+ var device2 = new Device(_idPrefix + Guid.NewGuid());
+ using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
- foreach (Device device in devices)
+ try
{
- // After a bulk delete, every device should not be found
- Assert.IsNull(await registryManager.GetDeviceAsync(device.Id).ConfigureAwait(false));
+ await registryManager.AddDeviceAsync(device1).ConfigureAwait(false);
+ await registryManager.AddDeviceAsync(device2).ConfigureAwait(false);
+
+ // act
+
+ BulkRegistryOperationResult bulkDeleteResult = await registryManager
+ .RemoveDevices2Async(new[] { device1, device2 }, true, default)
+ .ConfigureAwait(false);
+
+ // assert
+
+ bulkDeleteResult.IsSuccessful.Should().BeTrue();
+ Device actualDevice1 = await registryManager.GetDeviceAsync(device1.Id).ConfigureAwait(false);
+ actualDevice1.Should().BeNull();
+ Device actualDevice2 = await registryManager.GetDeviceAsync(device1.Id).ConfigureAwait(false);
+ actualDevice2.Should().BeNull();
+ }
+ finally
+ {
+ try
+ {
+ await registryManager.RemoveDeviceAsync(device1.Id).ConfigureAwait(false);
+ await registryManager.RemoveDeviceAsync(device2.Id).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ Logger.Trace($"Failed to clean up devices due to {ex}");
+ }
}
}
@@ -183,7 +315,7 @@ public async Task RegistryManager_AddDeviceWithProxy()
Proxy = new WebProxy(TestConfiguration.IoTHub.ProxyServerAddress)
};
- using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString, transportSettings);
+ using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString, transportSettings);
var device = new Device(deviceId);
await registryManager.AddDeviceAsync(device).ConfigureAwait(false);
}
@@ -195,7 +327,7 @@ public async Task RegistryManager_ConfigurationOperations_Work()
bool configCreated = false;
string configurationId = (_idPrefix + Guid.NewGuid()).ToLower(); // Configuration Id characters must be all lower-case.
- using RegistryManager client = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ using var client = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
try
{
@@ -260,50 +392,32 @@ public async Task RegistryManager_ConfigurationOperations_Work()
public async Task RegistryManager_Query_Works()
{
// arrange
- using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
- string deviceId = $"{_idPrefix}{Guid.NewGuid()}";
-
- try
- {
- Device device = await registryManager
- .AddDeviceAsync(new Device(deviceId))
- .ConfigureAwait(false);
- // act
+ using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ string deviceId = TestConfiguration.IoTHub.X509ChainDeviceName;
- IQuery query = null;
- IEnumerable twins = null;
- for (int i = 0; i < 30; ++i)
- {
- string queryText = $"select * from devices where deviceId = '{deviceId}'";
- query = registryManager.CreateQuery(queryText);
+ Device device = await registryManager
+ .GetDeviceAsync(deviceId)
+ .ConfigureAwait(false);
+ device.Should().NotBeNull($"Device {deviceId} should already exist in hub setup for E2E tests");
- twins = await query.GetNextAsTwinAsync().ConfigureAwait(false);
+ // act
- if (twins.Any())
- {
- break;
- }
+ string queryText = $"select * from devices where deviceId = '{deviceId}'";
+ IQuery query = registryManager.CreateQuery(queryText);
+ IEnumerable twins = await query.GetNextAsTwinAsync().ConfigureAwait(false);
- // A new device may not return immediately from a query, so give it some time and some retries to appear
- await Task.Delay(250).ConfigureAwait(false);
- }
+ // assert
- // assert
- twins.Count().Should().Be(1, "only asked for 1 device by its Id");
- twins.First().DeviceId.Should().Be(deviceId, "The Id of the device returned should match");
- query.HasMoreResults.Should().BeFalse("We've processed the single, expected result");
- }
- finally
- {
- await registryManager.RemoveDeviceAsync(deviceId).ConfigureAwait(false);
- }
+ twins.Count().Should().Be(1, "only asked for 1 device by its Id");
+ twins.First().DeviceId.Should().Be(deviceId, "The Id of the device returned should match");
+ query.HasMoreResults.Should().BeFalse("We've processed the single, expected result");
}
[LoggedTestMethod]
public async Task ModulesClient_GetModulesOnDevice()
{
- int moduleCount = 5;
+ const int moduleCount = 2;
string testDeviceId = $"IdentityLifecycleDevice{Guid.NewGuid()}";
string[] testModuleIds = new string[moduleCount];
for (int i = 0; i < moduleCount; i++)
@@ -312,7 +426,7 @@ public async Task ModulesClient_GetModulesOnDevice()
}
Device device = null;
- using RegistryManager client = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ using var client = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
try
{
@@ -326,6 +440,9 @@ public async Task ModulesClient_GetModulesOnDevice()
new Module(testDeviceId, testModuleIds[i])).ConfigureAwait(false);
}
+ // Give the hub a moment
+ await Task.Delay(250).ConfigureAwait(false);
+
// List the modules on the test device
IEnumerable modulesOnDevice = await client.GetModulesOnDeviceAsync(testDeviceId).ConfigureAwait(false);
@@ -336,7 +453,7 @@ public async Task ModulesClient_GetModulesOnDevice()
Assert.AreEqual(moduleCount, moduleIdsOnDevice.Count);
for (int i = 0; i < moduleCount; i++)
{
- Assert.IsTrue(moduleIdsOnDevice.Contains(testModuleIds[i]));
+ moduleIdsOnDevice.Should().Contain(testModuleIds[i]);
}
}
finally
@@ -355,7 +472,7 @@ public async Task ModulesClient_IdentityLifecycle()
string testDeviceId = $"IdentityLifecycleDevice{Guid.NewGuid()}";
string testModuleId = $"IdentityLifecycleModule{Guid.NewGuid()}";
- using RegistryManager client = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ using var client = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
try
{
@@ -398,7 +515,7 @@ public async Task ModulesClient_IdentityLifecycle()
[LoggedTestMethod]
public async Task ModulesClient_DeviceTwinLifecycle()
{
- using RegistryManager client = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ using var client = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
TestModule module = await TestModule.GetTestModuleAsync(_idPrefix, _idPrefix, Logger).ConfigureAwait(false);
try
@@ -427,7 +544,7 @@ public async Task ModulesClient_DeviceTwinLifecycle()
}
}
- private async Task CleanupAsync(RegistryManager client, string deviceId)
+ private static async Task CleanupAsync(RegistryManager client, string deviceId)
{
// cleanup
try
diff --git a/e2e/test/iothub/service/RegistryManagerExportDevicesTests.cs b/e2e/test/iothub/service/RegistryManagerExportDevicesTests.cs
index c779d0099a..de45b2783c 100644
--- a/e2e/test/iothub/service/RegistryManagerExportDevicesTests.cs
+++ b/e2e/test/iothub/service/RegistryManagerExportDevicesTests.cs
@@ -1,8 +1,8 @@
// 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.Diagnostics.Tracing;
using System.Linq;
using System.Threading.Tasks;
using FluentAssertions;
@@ -24,7 +24,7 @@ public class RegistryManagerExportDevicesTests : E2EMsTestBase
// https://github.com/Azure/azure-sdk-for-net/issues/10476
private const string ExportFileNameDefault = "devices.txt";
- private const int MaxIterationWait = 30;
+ private const int MaxIterationWait = 60;
private static readonly TimeSpan s_waitDuration = TimeSpan.FromSeconds(3);
private static readonly char[] s_newlines = new char[]
@@ -53,17 +53,22 @@ public async Task RegistryManager_ExportDevices(StorageAuthenticationType storag
{
// arrange
- string edgeId1 = $"{nameof(RegistryManager_ExportDevices)}-Edge-{StorageContainer.GetRandomSuffix(4)}";
- string edgeId2 = $"{nameof(RegistryManager_ExportDevices)}-Edge-{StorageContainer.GetRandomSuffix(4)}";
- string deviceId = $"{nameof(RegistryManager_ExportDevices)}-{StorageContainer.GetRandomSuffix(4)}";
- string devicesFileName = $"{nameof(RegistryManager_ExportDevices)}-devicesexport-{StorageContainer.GetRandomSuffix(4)}.txt";
- using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ const string idPrefix = nameof(RegistryManager_ExportDevices);
+
+ string edgeId1 = $"{idPrefix}-Edge-{StorageContainer.GetRandomSuffix(4)}";
+ string edgeId2 = $"{idPrefix}-Edge-{StorageContainer.GetRandomSuffix(4)}";
+ string deviceId = $"{idPrefix}-{StorageContainer.GetRandomSuffix(4)}";
+ string configurationId = (idPrefix + Guid.NewGuid()).ToLower(); // Configuration Id characters must be all lower-case.
+ Logger.Trace($"Using Ids {deviceId}, {edgeId1}, {edgeId2}, and {configurationId}");
+
+ string devicesFileName = $"{idPrefix}-devicesexport-{StorageContainer.GetRandomSuffix(4)}.txt";
+ string configsFileName = $"{idPrefix}-configsexport-{StorageContainer.GetRandomSuffix(4)}.txt";
- Logger.Trace($"Using deviceId {deviceId}");
+ using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
try
{
- string containerName = StorageContainer.BuildContainerName(nameof(RegistryManager_ExportDevices));
+ string containerName = StorageContainer.BuildContainerName(idPrefix);
using StorageContainer storageContainer = await StorageContainer
.GetInstanceAsync(containerName)
.ConfigureAwait(false);
@@ -73,7 +78,7 @@ public async Task RegistryManager_ExportDevices(StorageAuthenticationType storag
? storageContainer.SasUri
: storageContainer.Uri;
- var edge1 = await registryManager
+ Device edge1 = await registryManager
.AddDeviceAsync(
new Device(edgeId1)
{
@@ -82,7 +87,7 @@ public async Task RegistryManager_ExportDevices(StorageAuthenticationType storag
})
.ConfigureAwait(false);
- var edge2 = await registryManager
+ Device edge2 = await registryManager
.AddDeviceAsync(
new Device(edgeId2)
{
@@ -92,7 +97,7 @@ public async Task RegistryManager_ExportDevices(StorageAuthenticationType storag
})
.ConfigureAwait(false);
- await registryManager
+ Device device = await registryManager
.AddDeviceAsync(
new Device(deviceId)
{
@@ -101,123 +106,221 @@ await registryManager
})
.ConfigureAwait(false);
+ //Configuration configuration = await registryManager
+ // .AddConfigurationAsync(
+ // new Configuration(configurationId)
+ // {
+ // Priority = 2,
+ // Labels = { { "labelName", "labelValue" } },
+ // TargetCondition = "*",
+ // Content =
+ // {
+ // DeviceContent = { { "properties.desired.x", 4L } },
+ // },
+ // Metrics =
+ // {
+ // Queries = { { "successfullyConfigured", "select deviceId from devices where properties.reported.x = 4" } }
+ // },
+ // })
+ // .ConfigureAwait(false);
+
// act
- JobProperties exportJobResponse = null;
- int tryCount = 0;
- while (true)
+ JobProperties exportJobResponse = await CreateAndWaitForJobAsync(
+ storageAuthenticationType,
+ isUserAssignedMsi,
+ devicesFileName,
+ configsFileName,
+ registryManager,
+ containerUri)
+ .ConfigureAwait(false);
+
+ // assert
+ await ValidateDevicesAsync(
+ devicesFileName,
+ storageContainer,
+ edge1,
+ edge2,
+ device)
+ .ConfigureAwait(false);
+ //await ValidateConfigurationsAsync(
+ // configsFileName,
+ // storageContainer,
+ // configuration)
+ // .ConfigureAwait(false);
+ }
+ finally
+ {
+ await CleanUpDevicesAsync(edgeId1, edgeId2, deviceId, configurationId, registryManager).ConfigureAwait(false);
+ }
+ }
+
+ private async Task CreateAndWaitForJobAsync(
+ StorageAuthenticationType storageAuthenticationType,
+ bool isUserAssignedMsi,
+ string devicesFileName,
+ string configsFileName,
+ RegistryManager registryManager,
+ Uri containerUri)
+ {
+ int tryCount = 0;
+
+ ManagedIdentity identity = isUserAssignedMsi
+ ? new ManagedIdentity
{
- try
- {
- ManagedIdentity identity = null;
- if (isUserAssignedMsi)
- {
- string userAssignedMsiResourceId = TestConfiguration.IoTHub.UserAssignedMsiResourceId;
- identity = new ManagedIdentity
- {
- userAssignedIdentity = userAssignedMsiResourceId
- };
- }
-
- JobProperties jobProperties = JobProperties.CreateForExportJob(
- containerUri.ToString(),
- true,
- devicesFileName,
- storageAuthenticationType,
- identity);
- exportJobResponse = await registryManager.ExportDevicesAsync(jobProperties).ConfigureAwait(false);
- break;
- }
- // Concurrent jobs can be rejected, so implement a retry mechanism to handle conflicts with other tests
- catch (JobQuotaExceededException) when (++tryCount < MaxIterationWait)
- {
- Logger.Trace($"JobQuotaExceededException... waiting.");
- await Task.Delay(s_waitDuration).ConfigureAwait(false);
- continue;
- }
+ UserAssignedIdentity = TestConfiguration.IoTHub.UserAssignedMsiResourceId
}
+ : null;
- // Wait for job to complete
- for (int i = 0; i < MaxIterationWait; ++i)
+ JobProperties exportJobResponse = JobProperties.CreateForExportJob(
+ containerUri.ToString(),
+ true,
+ devicesFileName,
+ storageAuthenticationType,
+ identity);
+ //exportJobResponse.IncludeConfigurations = true;
+ //exportJobResponse.ConfigurationsBlobName = configsFileName;
+
+ while (tryCount < MaxIterationWait)
+ {
+ try
+ {
+ exportJobResponse = await registryManager.ExportDevicesAsync(exportJobResponse).ConfigureAwait(false);
+ break;
+ }
+ // Concurrent jobs can be rejected, so implement a retry mechanism to handle conflicts with other tests
+ catch (JobQuotaExceededException) when (++tryCount < MaxIterationWait)
{
+ Logger.Trace($"JobQuotaExceededException... waiting.");
await Task.Delay(s_waitDuration).ConfigureAwait(false);
- exportJobResponse = await registryManager.GetJobAsync(exportJobResponse.JobId).ConfigureAwait(false);
- Logger.Trace($"Job {exportJobResponse.JobId} is {exportJobResponse.Status} with progress {exportJobResponse.Progress}%");
- if (!s_incompleteJobs.Contains(exportJobResponse.Status))
- {
- break;
- }
+ continue;
+ }
+ }
+
+ for (int i = 0; i < MaxIterationWait; ++i)
+ {
+ await Task.Delay(s_waitDuration).ConfigureAwait(false);
+ exportJobResponse = await registryManager.GetJobAsync(exportJobResponse.JobId).ConfigureAwait(false);
+ Logger.Trace($"Job {exportJobResponse.JobId} is {exportJobResponse.Status} with progress {exportJobResponse.Progress}%");
+ if (!s_incompleteJobs.Contains(exportJobResponse.Status))
+ {
+ break;
}
+ }
- // assert
+ exportJobResponse.Status.Should().Be(JobStatus.Completed, "Otherwise import failed");
+ exportJobResponse.FailureReason.Should().BeNullOrEmpty("Otherwise import failed");
- exportJobResponse.Status.Should().Be(JobStatus.Completed, "Otherwise import failed");
- exportJobResponse.FailureReason.Should().BeNullOrEmpty("Otherwise import failed");
+ return exportJobResponse;
+ }
- string devicesContent = await DownloadFileAsync(storageContainer, devicesFileName).ConfigureAwait(false);
- string[] serializedDevices = devicesContent.Split(s_newlines, StringSplitOptions.RemoveEmptyEntries);
+ private async Task ValidateDevicesAsync(
+ string devicesFileName,
+ StorageContainer storageContainer,
+ Device edge1,
+ Device edge2,
+ Device device)
+ {
+ string devicesContent = await DownloadFileAsync(storageContainer, devicesFileName).ConfigureAwait(false);
+ string[] serializedDevices = devicesContent.Split(s_newlines, StringSplitOptions.RemoveEmptyEntries);
- bool foundDeviceInExport = false;
- bool foundEdgeInExport = false;
- foreach (string serializedDevice in serializedDevices)
+ bool foundEdge1InExport = false;
+ bool foundEdge2InExport = false;
+ bool foundDeviceInExport = false;
+
+ foreach (string serializedDevice in serializedDevices)
+ {
+ // The first line may be a comment to the user, so skip any lines that don't start with a json object initial character: curly brace
+ if (serializedDevice[0] != '{')
{
- // The first line may be a comment to the user, so skip any lines that don't start with a json object initial character: curly brace
- if (serializedDevice[0] != '{')
- {
- continue;
- }
-
- if (foundEdgeInExport && foundDeviceInExport)
- {
- // we're done
- break;
- }
-
- ExportImportDevice exportedDevice = JsonConvert.DeserializeObject(serializedDevice);
- if (StringComparer.Ordinal.Equals(exportedDevice.Id, edgeId2) && exportedDevice.Capabilities.IotEdge)
- {
- Logger.Trace($"Found edge2 in export as [{serializedDevice}]");
- foundEdgeInExport = true;
- exportedDevice.DeviceScope.Should().Be(edge2.Scope, "Edges retain their own scope");
-
- // This is broken. The export doesn't include the ParentScopes property.
- // Disable this assert until it is fixed in the service.
- //exportedDevice.ParentScopes.First().Should().Be(edge1.Scope);
- continue;
- }
-
- if (StringComparer.Ordinal.Equals(exportedDevice.Id, deviceId))
- {
- Logger.Trace($"Found device in export as [{serializedDevice}]");
- foundDeviceInExport = true;
- exportedDevice.DeviceScope.Should().Be(edge1.Scope);
- continue;
- }
+ continue;
}
- foundEdgeInExport.Should().BeTrue("Expected edge did not appear in the export");
- foundDeviceInExport.Should().BeTrue("Expected device did not appear in the export");
- }
- finally
- {
- try
+
+ if (foundEdge1InExport
+ && foundEdge2InExport
+ && foundDeviceInExport)
+ {
+ // we're done
+ break;
+ }
+
+ ExportImportDevice exportedDevice = JsonConvert.DeserializeObject(serializedDevice);
+
+ if (StringComparer.Ordinal.Equals(exportedDevice.Id, edge1.Id) && exportedDevice.Capabilities.IotEdge)
+ {
+ Logger.Trace($"Found edge1 in export as [{serializedDevice}]");
+ foundEdge1InExport = true;
+ exportedDevice.DeviceScope.Should().Be(edge1.Scope, "Edges retain their own scope");
+ continue;
+ }
+
+ if (StringComparer.Ordinal.Equals(exportedDevice.Id, edge2.Id) && exportedDevice.Capabilities.IotEdge)
{
- await registryManager.RemoveDeviceAsync(deviceId).ConfigureAwait(false);
- await registryManager.RemoveDeviceAsync(edgeId2).ConfigureAwait(false);
- await registryManager.RemoveDeviceAsync(edgeId1).ConfigureAwait(false);
+ Logger.Trace($"Found edge2 in export as [{serializedDevice}]");
+ foundEdge2InExport = true;
+ exportedDevice.DeviceScope.Should().Be(edge2.Scope, "Edges retain their own scope");
+ continue;
}
- catch (Exception ex)
+
+ if (StringComparer.Ordinal.Equals(exportedDevice.Id, device.Id))
{
- Logger.Trace($"Failed to remove device during cleanup due to {ex}");
+ Logger.Trace($"Found device in export as [{serializedDevice}]");
+ foundDeviceInExport = true;
+ exportedDevice.DeviceScope.Should().Be(edge1.Scope);
+ continue;
}
}
+ foundEdge1InExport.Should().BeTrue("Expected edge did not appear in the export");
+ foundEdge2InExport.Should().BeTrue("Expected edge did not appear in the export");
+ foundDeviceInExport.Should().BeTrue("Expected device did not appear in the export");
+ }
+
+ private async Task ValidateConfigurationsAsync(
+ string configsFileName,
+ StorageContainer storageContainer,
+ Configuration configuration)
+ {
+ string configsContent = await DownloadFileAsync(storageContainer, configsFileName).ConfigureAwait(false);
+ string[] serializedConfigs = configsContent.Split(s_newlines, StringSplitOptions.RemoveEmptyEntries);
+
+ bool foundConfig = false;
+ foreach (string serializedConfig in serializedConfigs)
+ {
+ Configuration exportedConfig = JsonConvert.DeserializeObject(serializedConfig);
+ if (StringComparer.Ordinal.Equals(exportedConfig.Id, configuration.Id))
+ {
+ Logger.Trace($"Found config in export as [{serializedConfig}]");
+ foundConfig = true;
+ }
+ }
+
+ foundConfig.Should().BeTrue();
}
private static async Task DownloadFileAsync(StorageContainer storageContainer, string fileName)
{
CloudBlockBlob exportFile = storageContainer.CloudBlobContainer.GetBlockBlobReference(fileName);
- string fileContents = await exportFile.DownloadTextAsync().ConfigureAwait(false);
+ return await exportFile.DownloadTextAsync().ConfigureAwait(false);
+ }
- return fileContents;
+ private async Task CleanUpDevicesAsync(
+ string edgeId1,
+ string edgeId2,
+ string deviceId,
+ string configurationId,
+ RegistryManager registryManager)
+ {
+ try
+ {
+ await registryManager.RemoveDeviceAsync(deviceId).ConfigureAwait(false);
+ await registryManager.RemoveDeviceAsync(edgeId2).ConfigureAwait(false);
+ await registryManager.RemoveDeviceAsync(edgeId1).ConfigureAwait(false);
+ //await registryManager.RemoveConfigurationAsync(configurationId).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ Logger.Trace($"Failed to remove device/config during cleanup due to {ex}");
+ }
}
}
}
diff --git a/e2e/test/iothub/service/RegistryManagerImportDevicesTests.cs b/e2e/test/iothub/service/RegistryManagerImportDevicesTests.cs
index 8134adc813..19c7f842c3 100644
--- a/e2e/test/iothub/service/RegistryManagerImportDevicesTests.cs
+++ b/e2e/test/iothub/service/RegistryManagerImportDevicesTests.cs
@@ -1,5 +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;
using System.Collections.Generic;
using System.IO;
@@ -46,23 +47,28 @@ public async Task RegistryManager_ImportDevices(StorageAuthenticationType storag
{
// arrange
- string deviceId = $"{nameof(RegistryManager_ImportDevices)}-device-{StorageContainer.GetRandomSuffix(4)}";
- string devicesFileName = $"{nameof(RegistryManager_ImportDevices)}-{StorageContainer.GetRandomSuffix(4)}.txt";
- using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ const string idPrefix = nameof(RegistryManager_ImportDevices);
+
+ string deviceId = $"{idPrefix}-device-{StorageContainer.GetRandomSuffix(4)}";
+ string configId = $"{idPrefix}-config-{StorageContainer.GetRandomSuffix(4)}".ToLower(); // Configuration Id characters must be all lower-case.
+ Logger.Trace($"Using Ids {deviceId} and {configId}.");
- Logger.Trace($"Using deviceId {deviceId}.");
+ string devicesFileName = $"{idPrefix}-devices-{StorageContainer.GetRandomSuffix(4)}.txt";
+ string configsFileName = $"{idPrefix}-configs-{StorageContainer.GetRandomSuffix(4)}.txt";
+
+ using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
try
{
string containerName = StorageContainer.BuildContainerName(nameof(RegistryManager_ImportDevices));
using StorageContainer storageContainer = await StorageContainer.GetInstanceAsync(containerName).ConfigureAwait(false);
- Logger.Trace($"Using container {storageContainer.Uri}");
+ Logger.Trace($"Using devices container {storageContainer.Uri}");
Uri containerUri = storageAuthenticationType == StorageAuthenticationType.KeyBased
? storageContainer.SasUri
: storageContainer.Uri;
- using Stream devicesStream = ImportExportDevicesHelpers.BuildDevicesStream(
+ using Stream devicesStream = ImportExportHelpers.BuildImportStream(
new List
{
new ExportImportDevice(
@@ -74,54 +80,44 @@ public async Task RegistryManager_ImportDevices(StorageAuthenticationType storag
});
await UploadFileAndConfirmAsync(storageContainer, devicesStream, devicesFileName).ConfigureAwait(false);
- // act
-
- JobProperties importJobResponse = null;
- int tryCount = 0;
- while (true)
- {
- try
+ //using Stream configsStream = ImportExportHelpers.BuildImportStream(
+ // new List
+ // {
+ // new ImportConfiguration(configId)
+ // {
+ // ImportMode = ConfigurationImportMode.CreateOrUpdateIfMatchETag,
+ // Priority = 3,
+ // Labels = { { "labelName", "labelValue" } },
+ // TargetCondition = "*",
+ // Content =
+ // {
+ // DeviceContent = { { "properties.desired.x", 5L } },
+ // },
+ // Metrics =
+ // {
+ // Queries = { { "successfullyConfigured", "select deviceId from devices where properties.reported.x = 5" } }
+ // },
+ // },
+ // });
+ //await UploadFileAndConfirmAsync(storageContainer, configsStream, configsFileName).ConfigureAwait(false);
+
+ ManagedIdentity identity = isUserAssignedMsi
+ ? new ManagedIdentity
{
- ManagedIdentity identity = null;
- if (isUserAssignedMsi)
- {
- string userAssignedMsiResourceId = TestConfiguration.IoTHub.UserAssignedMsiResourceId;
- identity = new ManagedIdentity
- {
- userAssignedIdentity = userAssignedMsiResourceId
- };
- }
-
- importJobResponse = await registryManager
- .ImportDevicesAsync(
- JobProperties.CreateForImportJob(
- containerUri.ToString(),
- containerUri.ToString(),
- devicesFileName,
- storageAuthenticationType))
- .ConfigureAwait(false);
- break;
+ UserAssignedIdentity = TestConfiguration.IoTHub.UserAssignedMsiResourceId
}
- // Concurrent jobs can be rejected, so implement a retry mechanism to handle conflicts with other tests
- catch (JobQuotaExceededException) when (++tryCount < MaxIterationWait)
- {
- Logger.Trace($"JobQuotaExceededException... waiting.");
- await Task.Delay(s_waitDuration).ConfigureAwait(false);
- continue;
- }
- }
+ : null;
- // wait for job to complete
- for (int i = 0; i < MaxIterationWait; ++i)
- {
- await Task.Delay(1000).ConfigureAwait(false);
- importJobResponse = await registryManager.GetJobAsync(importJobResponse.JobId).ConfigureAwait(false);
- Logger.Trace($"Job {importJobResponse.JobId} is {importJobResponse.Status} with progress {importJobResponse.Progress}%");
- if (!s_incompleteJobs.Contains(importJobResponse.Status))
- {
- break;
- }
- }
+ // act
+
+ JobProperties importJobResponse = await CreateAndWaitForJobAsync(
+ storageAuthenticationType,
+ devicesFileName,
+ configsFileName,
+ registryManager,
+ containerUri,
+ identity)
+ .ConfigureAwait(false);
// assert
@@ -130,38 +126,48 @@ public async Task RegistryManager_ImportDevices(StorageAuthenticationType storag
// should not throw due to 404, but device may not immediately appear in registry
Device device = null;
+ //Configuration config = null;
for (int i = 0; i < MaxIterationWait; ++i)
{
await Task.Delay(s_waitDuration).ConfigureAwait(false);
try
{
device = await registryManager.GetDeviceAsync(deviceId).ConfigureAwait(false);
+ //config = await registryManager.GetConfigurationAsync(configId).ConfigureAwait(false);
break;
}
catch (Exception ex)
{
- Logger.Trace($"Could not find device on iteration {i} due to [{ex.Message}]");
+ Logger.Trace($"Could not find device/config on iteration {i} due to [{ex.Message}]");
}
}
if (device == null)
{
Assert.Fail($"Device {deviceId} not found in registry manager");
}
+ //if (config == null)
+ //{
+ // Assert.Fail($"Config {configId} not found in registry manager");
+ //}
}
finally
{
try
{
await registryManager.RemoveDeviceAsync(deviceId).ConfigureAwait(false);
+ //await registryManager.RemoveConfigurationAsync(configId).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ Logger.Trace($"Failed to clean up device/config due to {ex}");
}
- catch { }
}
}
- private static async Task UploadFileAndConfirmAsync(StorageContainer storageContainer, Stream devicesFile, string fileName)
+ private static async Task UploadFileAndConfirmAsync(StorageContainer storageContainer, Stream fileContents, string fileName)
{
CloudBlockBlob cloudBlob = storageContainer.CloudBlobContainer.GetBlockBlobReference(fileName);
- await cloudBlob.UploadFromStreamAsync(devicesFile).ConfigureAwait(false);
+ await cloudBlob.UploadFromStreamAsync(fileContents).ConfigureAwait(false);
// wait for blob to be written
bool foundBlob = false;
@@ -174,7 +180,62 @@ private static async Task UploadFileAndConfirmAsync(StorageContainer storageCont
break;
}
}
- foundBlob.Should().BeTrue($"Failed to find {fileName} in storage container, required for test.");
+ foundBlob.Should().BeTrue($"Failed to find {fileName} in storage container - required for test.");
+ }
+
+ private async Task CreateAndWaitForJobAsync(
+ StorageAuthenticationType storageAuthenticationType,
+ string devicesFileName,
+ string configsFileName,
+ RegistryManager registryManager,
+ Uri containerUri,
+ ManagedIdentity identity)
+ {
+ int tryCount = 0;
+ JobProperties importJobResponse = null;
+
+ JobProperties jobProperties = JobProperties.CreateForImportJob(
+ containerUri.ToString(),
+ containerUri.ToString(),
+ devicesFileName,
+ storageAuthenticationType,
+ identity);
+ //jobProperties.ConfigurationsBlobName = configsFileName;
+ //jobProperties.IncludeConfigurations = true;
+
+ while (tryCount < MaxIterationWait)
+ {
+ try
+ {
+ importJobResponse = await registryManager.ImportDevicesAsync(jobProperties).ConfigureAwait(false);
+ if (!string.IsNullOrWhiteSpace(importJobResponse.FailureReason))
+ {
+ Logger.Trace($"Job failed due to {importJobResponse.FailureReason}");
+ }
+ break;
+ }
+ // Concurrent jobs can be rejected, so implement a retry mechanism to handle conflicts with other tests
+ catch (JobQuotaExceededException) when (++tryCount < MaxIterationWait)
+ {
+ Logger.Trace($"JobQuotaExceededException... waiting.");
+ await Task.Delay(s_waitDuration).ConfigureAwait(false);
+ continue;
+ }
+ }
+
+ // wait for job to complete
+ for (int i = 0; i < MaxIterationWait; ++i)
+ {
+ await Task.Delay(1000).ConfigureAwait(false);
+ importJobResponse = await registryManager.GetJobAsync(importJobResponse?.JobId).ConfigureAwait(false);
+ Logger.Trace($"Job {importJobResponse.JobId} is {importJobResponse.Status} with progress {importJobResponse.Progress}%");
+ if (!s_incompleteJobs.Contains(importJobResponse.Status))
+ {
+ break;
+ }
+ }
+
+ return importJobResponse;
}
}
}
diff --git a/e2e/test/iothub/service/ServiceClientE2ETests.cs b/e2e/test/iothub/service/ServiceClientE2ETests.cs
index ebad2565b7..d18fdda791 100644
--- a/e2e/test/iothub/service/ServiceClientE2ETests.cs
+++ b/e2e/test/iothub/service/ServiceClientE2ETests.cs
@@ -50,7 +50,7 @@ private async Task TestTimeout(TimeSpan? timeout)
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false);
using var sender = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
- Stopwatch sw = new Stopwatch();
+ var sw = new Stopwatch();
sw.Start();
Logger.Trace($"Testing ServiceClient SendAsync() timeout in ticks={timeout?.Ticks}");
@@ -73,7 +73,7 @@ public async Task ServiceClient_SendsMessage(TransportType transportType)
{
// arrange
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false);
- using ServiceClient sender = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString, transportType);
+ using var sender = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString, transportType);
string messageId = Guid.NewGuid().ToString();
// act and expect no exception
@@ -92,7 +92,7 @@ public async Task MessageIdDefaultNotSet_SendEventDoesNotSetMessageId()
{
// arrange
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false);
- using ServiceClient sender = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ using var sender = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
string messageId = Guid.NewGuid().ToString();
// act
@@ -121,7 +121,7 @@ public async Task MessageIdDefaultSetToNull_SendEventDoesNotSetMessageId()
{
SdkAssignsMessageId = Shared.SdkAssignsMessageId.Never,
};
- using ServiceClient sender = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString, options);
+ using var sender = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString, options);
string messageId = Guid.NewGuid().ToString();
// act
@@ -150,7 +150,7 @@ public async Task MessageIdDefaultSetToGuid_SendEventSetMessageIdIfNotSet()
{
SdkAssignsMessageId = Shared.SdkAssignsMessageId.WhenUnset,
};
- using ServiceClient sender = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString, options);
+ using var sender = ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString, options);
string messageId = Guid.NewGuid().ToString();
// act
diff --git a/e2e/test/iothub/telemetry/TelemetrySendE2ETests.cs b/e2e/test/iothub/telemetry/TelemetrySendE2ETests.cs
index fac19320d7..23b1b1ff25 100644
--- a/e2e/test/iothub/telemetry/TelemetrySendE2ETests.cs
+++ b/e2e/test/iothub/telemetry/TelemetrySendE2ETests.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.Net;
using System.Threading.Tasks;
using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.Devices.E2ETests.Helpers;
diff --git a/e2e/test/iothub/twin/FaultInjectionPoolAmqpTests.TwinFaultInjectionPoolAmqpTests.cs b/e2e/test/iothub/twin/FaultInjectionPoolAmqpTests.TwinFaultInjectionPoolAmqpTests.cs
index 53736ec57c..419708e302 100644
--- a/e2e/test/iothub/twin/FaultInjectionPoolAmqpTests.TwinFaultInjectionPoolAmqpTests.cs
+++ b/e2e/test/iothub/twin/FaultInjectionPoolAmqpTests.TwinFaultInjectionPoolAmqpTests.cs
@@ -1481,8 +1481,8 @@ await FaultInjectionPoolingOverAmqp
async Task InitOperationAsync(DeviceClient deviceClient, TestDevice testDevice, TestDeviceCallbackHandler testDeviceCallbackHandler)
{
- var propName = Guid.NewGuid().ToString();
- var propValue = Guid.NewGuid().ToString();
+ string propName = Guid.NewGuid().ToString();
+ string propValue = Guid.NewGuid().ToString();
twinPropertyMap.Add(testDevice.Id, new List { propName, propValue });
Logger.Trace($"{nameof(FaultInjectionPoolAmqpTests)}: Setting desired propery callback for device {testDevice.Id}");
@@ -1495,8 +1495,8 @@ async Task TestOperationAsync(DeviceClient deviceClient, TestDevice testDevice,
using var cts = new CancellationTokenSource(FaultInjection.RecoveryTime);
List twinProperties = twinPropertyMap[testDevice.Id];
- var propName = twinProperties[0];
- var propValue = twinProperties[1];
+ string propName = twinProperties[0];
+ string propValue = twinProperties[1];
testDeviceCallbackHandler.ExpectedTwinPropertyValue = propValue;
Logger.Trace($"{nameof(FaultInjectionPoolAmqpTests)}: Updating the desired properties for device {testDevice.Id}");
diff --git a/e2e/test/iothub/twin/TwinE2ETests.cs b/e2e/test/iothub/twin/TwinE2ETests.cs
index be9d0aecca..27e4915ee3 100644
--- a/e2e/test/iothub/twin/TwinE2ETests.cs
+++ b/e2e/test/iothub/twin/TwinE2ETests.cs
@@ -392,7 +392,7 @@ public async Task Twin_ClientSetsReportedPropertyWithoutDesiredPropertyCallback(
// arrange
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);
- using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transportType);
+ using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transportType);
await Twin_DeviceSetsReportedPropertyAndGetsItBackAsync(deviceClient, testDevice.Id, Guid.NewGuid().ToString(), Logger).ConfigureAwait(false);
@@ -418,7 +418,7 @@ public async Task Twin_ClientSetsReportedPropertyWithoutDesiredPropertyCallback(
private async Task Twin_DeviceSetsReportedPropertyAndGetsItBackSingleDeviceAsync(Client.TransportType transport)
{
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);
- using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
+ using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
await Twin_DeviceSetsReportedPropertyAndGetsItBackAsync(deviceClient, testDevice.Id, Guid.NewGuid().ToString(), Logger).ConfigureAwait(false);
}
@@ -426,14 +426,14 @@ private async Task Twin_DeviceSetsReportedPropertyAndGetsItBackSingleDeviceAsync
private async Task Twin_DeviceSetsReportedPropertyArrayAndGetsItBackSingleDeviceAsync(Client.TransportType transport)
{
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);
- using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
+ using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
await Twin_DeviceSetsReportedPropertyAndGetsItBackAsync(deviceClient, testDevice.Id, s_listOfPropertyValues, Logger).ConfigureAwait(false);
}
public static async Task Twin_DeviceSetsReportedPropertyAndGetsItBackAsync(DeviceClient deviceClient, string deviceId, object propValue, MsTestLogger logger)
{
- var propName = Guid.NewGuid().ToString();
+ string propName = Guid.NewGuid().ToString();
logger.Trace($"{nameof(Twin_DeviceSetsReportedPropertyAndGetsItBackAsync)}: name={propName}, value={propValue}");
@@ -443,12 +443,12 @@ public static async Task Twin_DeviceSetsReportedPropertyAndGetsItBackAsync(Devic
// Validate the updated twin from the device-client
Twin deviceTwin = await deviceClient.GetTwinAsync().ConfigureAwait(false);
- var actual = deviceTwin.Properties.Reported[propName];
+ dynamic actual = deviceTwin.Properties.Reported[propName];
Assert.AreEqual(JsonConvert.SerializeObject(actual), JsonConvert.SerializeObject(propValue));
// Validate the updated twin from the service-client
Twin completeTwin = await _registryManager.GetTwinAsync(deviceId).ConfigureAwait(false);
- var actualProp = completeTwin.Properties.Reported[propName];
+ dynamic actualProp = completeTwin.Properties.Reported[propName];
Assert.AreEqual(JsonConvert.SerializeObject(actualProp), JsonConvert.SerializeObject(propValue));
}
@@ -523,7 +523,7 @@ await deviceClient
public static async Task RegistryManagerUpdateDesiredPropertyAsync(string deviceId, string propName, object propValue)
{
- using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
var twinPatch = new Twin();
twinPatch.Properties.Desired[propName] = propValue;
@@ -534,12 +534,12 @@ public static async Task RegistryManagerUpdateDesiredPropertyAsync(string device
private async Task Twin_ServiceSetsDesiredPropertyAndDeviceUnsubscribes(Client.TransportType transport, object propValue)
{
- var propName = Guid.NewGuid().ToString();
+ string propName = Guid.NewGuid().ToString();
Logger.Trace($"{nameof(Twin_ServiceSetsDesiredPropertyAndDeviceReceivesEventAsync)}: name={propName}, value={propValue}");
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);
- using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
+ using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
// Set a callback
await deviceClient.
@@ -569,12 +569,12 @@ await RegistryManagerUpdateDesiredPropertyAsync(testDevice.Id, propName, propVal
private async Task Twin_ServiceSetsDesiredPropertyAndDeviceReceivesEventAsync(Client.TransportType transport, Func> setTwinPropertyUpdateCallbackAsync, object propValue)
{
- var propName = Guid.NewGuid().ToString();
+ string propName = Guid.NewGuid().ToString();
Logger.Trace($"{nameof(Twin_ServiceSetsDesiredPropertyAndDeviceReceivesEventAsync)}: name={propName}, value={propValue}");
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);
- using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
+ using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
Task updateReceivedTask = await setTwinPropertyUpdateCallbackAsync(deviceClient, propName, propValue, Logger).ConfigureAwait(false);
@@ -584,12 +584,12 @@ private async Task Twin_ServiceSetsDesiredPropertyAndDeviceReceivesEventAsync(Cl
// Validate the updated twin from the device-client
Twin deviceTwin = await deviceClient.GetTwinAsync().ConfigureAwait(false);
- var actual = deviceTwin.Properties.Desired[propName];
+ dynamic actual = deviceTwin.Properties.Desired[propName];
Assert.AreEqual(JsonConvert.SerializeObject(actual), JsonConvert.SerializeObject(propValue));
// Validate the updated twin from the service-client
Twin completeTwin = await _registryManager.GetTwinAsync(testDevice.Id).ConfigureAwait(false);
- var actualProp = completeTwin.Properties.Desired[propName];
+ dynamic actualProp = completeTwin.Properties.Desired[propName];
Assert.AreEqual(JsonConvert.SerializeObject(actualProp), JsonConvert.SerializeObject(propValue));
await deviceClient.SetDesiredPropertyUpdateCallbackAsync(null, null).ConfigureAwait(false);
@@ -598,12 +598,12 @@ private async Task Twin_ServiceSetsDesiredPropertyAndDeviceReceivesEventAsync(Cl
private async Task Twin_ServiceSetsDesiredPropertyAndDeviceReceivesItOnNextGetAsync(Client.TransportType transport)
{
- var propName = Guid.NewGuid().ToString();
- var propValue = Guid.NewGuid().ToString();
+ string propName = Guid.NewGuid().ToString();
+ string propValue = Guid.NewGuid().ToString();
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);
- using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
- using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
+ using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
var twinPatch = new Twin();
twinPatch.Properties.Desired[propName] = propValue;
@@ -618,12 +618,12 @@ private async Task Twin_ServiceSetsDesiredPropertyAndDeviceReceivesItOnNextGetAs
private async Task Twin_DeviceSetsReportedPropertyAndServiceReceivesItAsync(Client.TransportType transport)
{
- var propName = Guid.NewGuid().ToString();
- var propValue = Guid.NewGuid().ToString();
+ string propName = Guid.NewGuid().ToString();
+ string propValue = Guid.NewGuid().ToString();
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);
- using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
- using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
+ using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
var patch = new TwinCollection();
patch[propName] = propValue;
@@ -638,13 +638,13 @@ private async Task Twin_DeviceSetsReportedPropertyAndServiceReceivesItAsync(Clie
private async Task Twin_ServiceDoesNotCreateNullPropertyInCollectionAsync(Client.TransportType transport)
{
- var propName1 = Guid.NewGuid().ToString();
- var propName2 = Guid.NewGuid().ToString();
- var propEmptyValue = "{}";
+ string propName1 = Guid.NewGuid().ToString();
+ string propName2 = Guid.NewGuid().ToString();
+ string propEmptyValue = "{}";
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);
- using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
- using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
+ using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
await deviceClient
.UpdateReportedPropertiesAsync(
@@ -690,14 +690,14 @@ await deviceClient
private async Task Twin_ClientHandlesRejectionInvalidPropertyNameAsync(Client.TransportType transport)
{
- var propName1 = "$" + Guid.NewGuid().ToString();
- var propName2 = Guid.NewGuid().ToString();
+ string propName1 = "$" + Guid.NewGuid().ToString();
+ string propName2 = Guid.NewGuid().ToString();
using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);
- using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
- using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
+ using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
- var exceptionThrown = false;
+ bool exceptionThrown = false;
try
{
await deviceClient
diff --git a/e2e/test/iothub/twin/TwinFaultInjectionTests.cs b/e2e/test/iothub/twin/TwinFaultInjectionTests.cs
index 0d76a46aec..eb94dd3fbc 100644
--- a/e2e/test/iothub/twin/TwinFaultInjectionTests.cs
+++ b/e2e/test/iothub/twin/TwinFaultInjectionTests.cs
@@ -219,12 +219,12 @@ public async Task Twin_DeviceDesiredPropertyUpdateGracefulShutdownRecovery_AmqpW
TimeSpan delayInSec,
string proxyAddress = null)
{
- var propName = Guid.NewGuid().ToString();
+ string propName = Guid.NewGuid().ToString();
var props = new TwinCollection();
Func testOperation = async (deviceClient, testDevice) =>
{
- var propValue = Guid.NewGuid().ToString();
+ string propValue = Guid.NewGuid().ToString();
props[propName] = propValue;
await deviceClient.UpdateReportedPropertiesAsync(props).ConfigureAwait(false);
@@ -256,7 +256,7 @@ await FaultInjection
private async Task RegistryManagerUpdateDesiredPropertyAsync(string deviceId, string propName, string propValue)
{
- using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
var twinPatch = new Twin();
twinPatch.Properties.Desired[propName] = propValue;
@@ -273,10 +273,10 @@ private async Task RegistryManagerUpdateDesiredPropertyAsync(string deviceId, st
string proxyAddress = null)
{
TestDeviceCallbackHandler testDeviceCallbackHandler = null;
- using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
+ using var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString);
using var cts = new CancellationTokenSource(FaultInjection.RecoveryTime);
- var propName = Guid.NewGuid().ToString();
+ string propName = Guid.NewGuid().ToString();
var props = new TwinCollection();
// Configure the callback and start accepting twin changes.
@@ -289,7 +289,7 @@ async Task InitOperationAsync(DeviceClient deviceClient, TestDevice testDevice)
// Change the twin from the service side and verify the device received it.
async Task TestOperationAsync(DeviceClient deviceClient, TestDevice testDevice)
{
- var propValue = Guid.NewGuid().ToString();
+ string propValue = Guid.NewGuid().ToString();
testDeviceCallbackHandler.ExpectedTwinPropertyValue = propValue;
Logger.Trace($"{nameof(Twin_DeviceDesiredPropertyUpdateRecoveryAsync)}: name={propName}, value={propValue}");
diff --git a/e2e/test/prerequisites/E2ETestsSetup/e2eTestsSetup.ps1 b/e2e/test/prerequisites/E2ETestsSetup/e2eTestsSetup.ps1
index a2f83cf513..0ac2a2e319 100644
--- a/e2e/test/prerequisites/E2ETestsSetup/e2eTestsSetup.ps1
+++ b/e2e/test/prerequisites/E2ETestsSetup/e2eTestsSetup.ps1
@@ -144,10 +144,9 @@ $certificateHashAlgorithm = "SHA256"
if ($GenerateResourcesForDevOpsPipeline)
{
- $iothubUnitsToBeCreated = 3;
+ $iothubUnitsToBeCreated = 5;
}
-
#################################################################################################
# Get Function App contents to pass to deployment
#################################################################################################
@@ -208,6 +207,7 @@ $groupCertChainPath = "$PSScriptRoot/GroupCertChain.p7b";
############################################################################################################################
# Cleanup old certs and files that can cause a conflict
############################################################################################################################
+
CleanUp-Certs
# Generate self signed Root and Intermediate CA cert, expiring in 2 years
@@ -434,28 +434,43 @@ $instrumentationKey = az deployment group show -g $ResourceGroup -n $deploymentN
$iotHubName = az deployment group show -g $ResourceGroup -n $deploymentName --query 'properties.outputs.hubName.value' --output tsv
#################################################################################################################################################
-# Configure an AAD app and create self signed certs and get the bytes to generate more content info.
+# Configure an AAD app to authenticate Log Analytics Workspace, if specified
#################################################################################################################################################
-Write-Host "`nCreating app registration $logAnalyticsAppRegnName"
-$logAnalyticsAppRegUrl = "http://$logAnalyticsAppRegnName"
-$logAnalyticsAppId = az ad sp create-for-rbac -n $logAnalyticsAppRegUrl --role "Reader" --scope $resourceGroupId --query "appId" --output tsv
-Write-Host "`nCreated application $logAnalyticsAppRegnName with Id $logAnalyticsAppId."
+
+if ($EnableIotHubSecuritySolution)
+{
+ Write-Host "`nCreating app registration $logAnalyticsAppRegnName"
+ $logAnalyticsAppRegUrl = "http://$logAnalyticsAppRegnName"
+ $logAnalyticsAppId = az ad sp create-for-rbac -n $logAnalyticsAppRegUrl --role "Reader" --scope $resourceGroupId --query "appId" --output tsv
+ Write-Host "`nCreated application $logAnalyticsAppRegnName with Id $logAnalyticsAppId."
+}
#################################################################################################################################################
# Configure an AAD app to perform IoT hub data actions.
#################################################################################################################################################
+
Write-Host "`nCreating app registration $iotHubAadTestAppRegName for IoT hub data actions"
-$iotHubAadTestAppRegUrl = "http://$iotHubAadTestAppRegName"
$iotHubDataContributorRoleId = "4fc6c259987e4a07842ec321cc9d413f"
$iotHubScope = "/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroup/providers/Microsoft.Devices/IotHubs/$iotHubName"
-$iotHubAadTestAppInfo = az ad sp create-for-rbac -n $iotHubAadTestAppRegUrl --role $iotHubDataContributorRoleId --scope $iotHubScope --query '{appId:appId, password:password}' | ConvertFrom-Json
-$iotHubAadTestAppPassword = $iotHubAadTestAppInfo.password
+$iotHubAadTestAppInfo = az ad sp create-for-rbac -n $iotHubAadTestAppRegName --role $iotHubDataContributorRoleId --scope $iotHubScope --query '{appId:appId, password:password}' | ConvertFrom-Json
+
$iotHubAadTestAppId = $iotHubAadTestAppInfo.appId
+$iotHubAadTestAppPassword = $iotHubAadTestAppInfo.password
Write-Host "`nCreated application $iotHubAadTestAppRegName with Id $iotHubAadTestAppId."
+#################################################################################################################################################
+# Configure AAD app to perform DPS data actions.
+#################################################################################################################################################
+
+Write-Host "`nGiving app registration $iotHubAadTestAppRegName data contributor permission on DPS instance $dpsName"
+$dpsContributorId = "dfce44e4-17b7-4bd1-a6d1-04996ec95633"
+$dpsScope = "/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroup/providers/Microsoft.Devices/ProvisioningServices/$dpsName"
+az role assignment create --role $dpsContributorId --assignee $iotHubAadTestAppId --scope $dpsScope
+
#################################################################################################################################################
# Add role assignement for User assinged managed identity to be able to perform import and export jobs on the IoT hub.
#################################################################################################################################################
+
Write-Host "`nGranting the user assigned managed identity $managedIdentityName Storage Blob Data Contributor permissions on resource group: $ResourceGroup."
$msiPrincipalId = az identity show -n $managedIdentityName -g $ResourceGroup --query principalId --output tsv
$msiResourceId = "/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/$managedIdentityName"
@@ -464,6 +479,7 @@ az role assignment create --assignee $msiPrincipalId --role 'Storage Blob Data C
##################################################################################################################################
# Granting the IoT hub system identity storage blob contributor access on the resoruce group
##################################################################################################################################
+
Write-Host "`nGranting the system identity on the hub $iotHubName Storage Blob Data Contributor permissions on resource group: $ResourceGroup."
$systemIdentityPrincipal = az resource list -n $iotHubName --query [0].identity.principalId --out tsv
az role assignment create --assignee $systemIdentityPrincipal --role "Storage Blob Data Contributor" --scope $resourceGroupId --output none
@@ -472,8 +488,8 @@ az role assignment create --assignee $systemIdentityPrincipal --role "Storage Bl
# Uploading root CA certificate to IoT hub and verifying
##################################################################################################################################
-$certExits = az iot hub certificate list -g $ResourceGroup --hub-name $iotHubName --query "value[?name=='$hubUploadCertificateName']" --output tsv
-if ($certExits)
+$certExists = az iot hub certificate list -g $ResourceGroup --hub-name $iotHubName --query "value[?name=='$hubUploadCertificateName']" --output tsv
+if ($certExists)
{
Write-Host "`nDeleting existing certificate from IoT hub."
$etag = az iot hub certificate show -g $ResourceGroup --hub-name $iotHubName --name $hubUploadCertificateName --query 'etag'
@@ -505,6 +521,7 @@ if ($isVerified -eq 'false')
##################################################################################################################################
# Fetch the iothubowner policy details
##################################################################################################################################
+
$iothubownerSasPolicy = "iothubowner"
$iothubownerSasPrimaryKey = az iot hub policy show --hub-name $iotHubName --name $iothubownerSasPolicy --query 'primaryKey'
@@ -523,6 +540,7 @@ if (-not $iotHubCertChainDevice)
##################################################################################################################################
# Create the IoT devices and modules that are used by the .NET samples
##################################################################################################################################
+
$iotHubSasBasedDeviceId = "DoNotDeleteDevice1"
$iotHubSasBasedDevice = az iot hub device-identity list -g $ResourceGroup --hub-name $iotHubName --query "[?deviceId=='$iotHubSasBasedDeviceId'].deviceId" --output tsv
@@ -584,8 +602,8 @@ $symmetricKeySampleEnrollmentPrimaryKey = az iot dps enrollment show -g $Resourc
##################################################################################################################################
$dpsIdScope = az iot dps show -g $ResourceGroup --name $dpsName --query 'properties.idScope' --output tsv
-$certExits = az iot dps certificate list -g $ResourceGroup --dps-name $dpsName --query "value[?name=='$uploadCertificateName']" --output tsv
-if ($certExits)
+$certExists = az iot dps certificate list -g $ResourceGroup --dps-name $dpsName --query "value[?name=='$uploadCertificateName']" --output tsv
+if ($certExists)
{
Write-Host "`nDeleting existing certificate from DPS."
$etag = az iot dps certificate show -g $ResourceGroup --dps-name $dpsName --certificate-name $uploadCertificateName --query 'etag'
@@ -642,90 +660,109 @@ az iot dps enrollment create `
--certificate-path $individualDeviceCertPath `
--output none
-Write-Host "`nCreating a self-signed certificate and placing it in $ResourceGroup."
-az ad app credential reset --id $logAnalyticsAppId --create-cert --keyvault $keyVaultName --cert $ResourceGroup --output none
-Write-Host "`nSuccessfully created a self signed certificate for your application $logAnalyticsAppRegnName in $keyVaultName key vault with cert name $ResourceGroup."
-
-Write-Host "`nFetching the certificate binary."
-$selfSignedCerts = "$PSScriptRoot\selfSignedCerts"
-if (Test-Path $selfSignedCerts -PathType Leaf)
+if ($EnableIotHubSecuritySolution)
{
- Remove-Item -r $selfSignedCerts
-}
+ Write-Host "`nCreating a self-signed certificate for LA and placing it in $ResourceGroup."
+ az ad app credential reset --id $logAnalyticsAppId --create-cert --keyvault $keyVaultName --cert $ResourceGroup --output none
+ Write-Host "`nSuccessfully created a self signed certificate for your application $logAnalyticsAppRegnName in $keyVaultName key vault with cert name $ResourceGroup."
-az keyvault secret download --file $selfSignedCerts --vault-name $keyVaultName -n $ResourceGroup --encoding base64
-$fileContent = Get-Content $selfSignedCerts -AsByteStream
-$fileContentB64String = [System.Convert]::ToBase64String($fileContent);
+ Write-Host "`nFetching the certificate binary for LA."
+ $selfSignedCerts = "$PSScriptRoot\selfSignedCerts"
+ if (Test-Path $selfSignedCerts -PathType Leaf)
+ {
+ Remove-Item -r $selfSignedCerts
+ }
+
+ az keyvault secret download --file $selfSignedCerts --vault-name $keyVaultName -n $ResourceGroup --encoding base64
+ $fileContent = Get-Content $selfSignedCerts -AsByteStream
+ $fileContentB64String = [System.Convert]::ToBase64String($fileContent);
-Write-Host "`nSuccessfully fetched the certificate bytes. Removing the cert file from the disk."
-Remove-Item -r $selfSignedCerts
+ Write-Host "`nSuccessfully fetched the certificate bytes for LA. Removing the cert file from the disk."
+ Remove-Item -r $selfSignedCerts
+}
###################################################################################################################################
# Store all secrets in a KeyVault - Values will be pulled down from here to configure environment variables
###################################################################################################################################
-Write-Host "`nWriting secrets to KeyVault $keyVaultName."
-az keyvault set-policy -g $ResourceGroup --name $keyVaultName --object-id $userObjectId --secret-permissions delete get list set --output none
-az keyvault secret set --vault-name $keyVaultName --name "IOTHUB-CONNECTION-STRING" --value $iotHubConnectionString --output none
-az keyvault secret set --vault-name $keyVaultName --name "IOTHUB-PFX-X509-THUMBPRINT" --value $iotHubThumbprint --output none
-az keyvault secret set --vault-name $keyVaultName --name "IOTHUB-PROXY-SERVER-ADDRESS" --value $proxyServerAddress --output none
-az keyvault secret set --vault-name $keyVaultName --name "FAR-AWAY-IOTHUB-HOSTNAME" --value $farHubHostName --output none
-az keyvault secret set --vault-name $keyVaultName --name "DPS-IDSCOPE" --value $dpsIdScope --output none
-az keyvault secret set --vault-name $keyVaultName --name "PROVISIONING-CONNECTION-STRING" --value $dpsConnectionString --output none
-az keyvault secret set --vault-name $keyVaultName --name "CUSTOM-ALLOCATION-POLICY-WEBHOOK" --value $customAllocationPolicyWebhook --output none
-
$dpsEndpoint = "global.azure-devices-provisioning.net"
if ($Region.EndsWith('euap', 'CurrentCultureIgnoreCase'))
{
$dpsEndpoint = "global-canary.azure-devices-provisioning.net"
}
-az keyvault secret set --vault-name $keyVaultName --name "DPS-GLOBALDEVICEENDPOINT" --value $dpsEndpoint --output none
-
-az keyvault secret set --vault-name $keyVaultName --name "DPS-X509-PFX-CERTIFICATE-PASSWORD" --value $dpsX509PfxCertificatePassword --output none
-az keyvault secret set --vault-name $keyVaultName --name "IOTHUB-X509-PFX-CERTIFICATE" --value $iothubX509PfxCertificate --output none
-az keyvault secret set --vault-name $keyVaultName --name "DPS-INDIVIDUALX509-PFX-CERTIFICATE" --value $dpsIndividualX509PfxCertificate --output none
-az keyvault secret set --vault-name $keyVaultName --name "DPS-GROUPX509-PFX-CERTIFICATE" --value $dpsGroupX509PfxCertificate --output none
-az keyvault secret set --vault-name $keyVaultName --name "DPS-GROUPX509-CERTIFICATE-CHAIN" --value $dpsGroupX509CertificateChain --output none
-az keyvault secret set --vault-name $keyVaultName --name "STORAGE-ACCOUNT-CONNECTION-STRING" --value $storageAccountConnectionString --output none
-az keyvault secret set --vault-name $keyVaultName --name "LA-WORKSPACE-ID" --value $workspaceId --output none
-az keyvault secret set --vault-name $keyVaultName --name "MSFT-TENANT-ID" --value "72f988bf-86f1-41af-91ab-2d7cd011db47" --output none
-az keyvault secret set --vault-name $keyVaultName --name "LA-AAD-APP-ID" --value $logAnalyticsAppId --output none
-az keyvault secret set --vault-name $keyVaultName --name "IOTHUB-CLIENT-ID" --value $iotHubAadTestAppId --output none
-az keyvault secret set --vault-name $keyVaultName --name "IOTHUB-CLIENT-SECRET" --value $iotHubAadTestAppPassword --output none
-az keyvault secret set --vault-name $keyVaultName --name "LA-AAD-APP-CERT-BASE64" --value $fileContentB64String --output none
-az keyvault secret set --vault-name $keyVaultName --name "DPS-GLOBALDEVICEENDPOINT-INVALIDCERT" --value "invalidcertgde1.westus.cloudapp.azure.com" --output none
-az keyvault secret set --vault-name $keyVaultName --name "PIPELINE-ENVIRONMENT" --value "prod" --output none
-az keyvault secret set --vault-name $keyVaultName --name "HUB-CHAIN-DEVICE-PFX-CERTIFICATE" --value $iothubX509ChainDevicePfxCertificate --output none
-az keyvault secret set --vault-name $keyVaultName --name "HUB-CHAIN-ROOT-CA-CERTIFICATE" --value $iothubX509RootCACertificate --output none
-az keyvault secret set --vault-name $keyVaultName --name "HUB-CHAIN-INTERMEDIATE1-CERTIFICATE" --value $iothubX509Intermediate1Certificate --output none
-az keyvault secret set --vault-name $keyVaultName --name "HUB-CHAIN-INTERMEDIATE2-CERTIFICATE" --value $iothubX509Intermediate2Certificate --output none
-az keyvault secret set --vault-name $keyVaultName --name "IOTHUB-X509-CHAIN-DEVICE-NAME" --value $iotHubCertChainDeviceCommonName --output none
-az keyvault secret set --vault-name $keyVaultName --name "IOTHUB-USER-ASSIGNED-MSI-RESOURCE-ID" --value $msiResourceId --output none
-
-# These environment variables are only used in Java
-az keyvault secret set --vault-name $keyVaultName --name "IOT-DPS-CONNECTION-STRING" --value $dpsConnectionString --output none # DPS Connection string Environment variable for Java
-az keyvault secret set --vault-name $keyVaultName --name "IOT-DPS-ID-SCOPE" --value $dpsIdScope --output none # DPS ID Scope Environment variable for Java
-az keyvault secret set --vault-name $keyVaultName --name "FAR-AWAY-IOTHUB-CONNECTION-STRING" --value $farHubConnectionString --output none
-az keyvault secret set --vault-name $keyVaultName --name "IS-BASIC-TIER-HUB" --value "false" --output none
-
-<#[SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="fake shared access token")]#>
-az keyvault secret set --vault-name $keyVaultName --name "IOTHUB-DEVICE-CONN-STRING-INVALIDCERT" --value "HostName=invalidcertiothub1.westus.cloudapp.azure.com;DeviceId=DoNotDelete1;SharedAccessKey=zWmeTGWmjcgDG1dpuSCVjc5ZY4TqVnKso5+g1wt/K3E=" --output none
-<#[SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="fake shared access token")]#>
-az keyvault secret set --vault-name $keyVaultName --name "IOTHUB-CONN-STRING-INVALIDCERT" --value "HostName=invalidcertiothub1.westus.cloudapp.azure.com;SharedAccessKeyName=iothubowner;SharedAccessKey=Fk1H0asPeeAwlRkUMTybJasksTYTd13cgI7SsteB05U=" --output none
-<#[SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="fake shared access token")]#>
-az keyvault secret set --vault-name $keyVaultName --name "PROVISIONING-CONNECTION-STRING-INVALIDCERT" --value "HostName=invalidcertdps1.westus.cloudapp.azure.com;SharedAccessKeyName=provisioningserviceowner;SharedAccessKey=lGO7OlXNhXlFyYV1rh9F/lUCQC1Owuh5f/1P0I1AFSY=" --output none
-
-az keyvault secret set --vault-name $keyVaultName --name "E2E-IKEY" --value $instrumentationKey --output none
-
-# These environment variables are used by .NET samples
-az keyvault secret set --vault-name $keyVaultName --name "IOTHUB-DEVICE-CONN-STRING" --value $iotHubSasBasedDeviceConnectionString --output none
-az keyvault secret set --vault-name $keyVaultName --name "IOTHUB-MODULE-CONN-STRING" --value $iotHubSasBasedModuleConnectionString --output none
-az keyvault secret set --vault-name $keyVaultName --name "PNP-TC-DEVICE-CONN-STRING" --value $temperatureControllerSampleDeviceConnectionString --output none
-az keyvault secret set --vault-name $keyVaultName --name "PNP-THERMOSTAT-DEVICE-CONN-STRING" --value $thermostatSampleDeviceConnectionString --output none
-az keyvault secret set --vault-name $keyVaultName --name "IOTHUB-SAS-KEY" --value $iothubownerSasPrimaryKey --output none
-az keyvault secret set --vault-name $keyVaultName --name "IOTHUB-SAS-KEY-NAME" --value $iothubownerSasPolicy --output none
-az keyvault secret set --vault-name $keyVaultName --name "DPS-SYMMETRIC-KEY-INDIVIDUAL-ENROLLMENT-REGISTRATION-ID" --value $symmetricKeySampleEnrollmentRegistrationId --output none
-az keyvault secret set --vault-name $keyVaultName --name "DPS-SYMMETRIC-KEY-INDIVIDUAL-ENROLLEMNT-PRIMARY-KEY" --value $symmetricKeySampleEnrollmentPrimaryKey --output none
+
+$keyvaultKvps = @{
+ "IOTHUB-CONNECTION-STRING" = $iotHubConnectionString;
+ "IOTHUB-PFX-X509-THUMBPRINT" = $iotHubThumbprint;
+ "IOTHUB-PROXY-SERVER-ADDRESS" = $proxyServerAddress;
+ "FAR-AWAY-IOTHUB-HOSTNAME" = $farHubHostName;
+ "DPS-IDSCOPE" = $dpsIdScope;
+ "PROVISIONING-CONNECTION-STRING" = $dpsConnectionString;
+ "CUSTOM-ALLOCATION-POLICY-WEBHOOK" = $customAllocationPolicyWebhook;
+ "DPS-GLOBALDEVICEENDPOINT" = $dpsEndpoint;
+ "DPS-X509-PFX-CERTIFICATE-PASSWORD" = $dpsX509PfxCertificatePassword;
+ "IOTHUB-X509-PFX-CERTIFICATE" = $iothubX509PfxCertificate;
+ "DPS-INDIVIDUALX509-PFX-CERTIFICATE" = $dpsIndividualX509PfxCertificate;
+ "DPS-GROUPX509-PFX-CERTIFICATE" = $dpsGroupX509PfxCertificate;
+ "DPS-GROUPX509-CERTIFICATE-CHAIN" = $dpsGroupX509CertificateChain;
+ "STORAGE-ACCOUNT-CONNECTION-STRING" = $storageAccountConnectionString;
+ "MSFT-TENANT-ID" = "72f988bf-86f1-41af-91ab-2d7cd011db47";
+ "IOTHUB-CLIENT-ID" = $iotHubAadTestAppId;
+ "IOTHUB-CLIENT-SECRET" = $iotHubAadTestAppPassword;
+ "DPS-GLOBALDEVICEENDPOINT-INVALIDCERT" = "invalidcertgde1.westus.cloudapp.azure.com";
+ "PIPELINE-ENVIRONMENT" = "prod";
+ "HUB-CHAIN-DEVICE-PFX-CERTIFICATE" = $iothubX509ChainDevicePfxCertificate;
+ "HUB-CHAIN-ROOT-CA-CERTIFICATE" = $iothubX509RootCACertificate;
+ "HUB-CHAIN-INTERMEDIATE1-CERTIFICATE" = $iothubX509Intermediate1Certificate;
+ "HUB-CHAIN-INTERMEDIATE2-CERTIFICATE" = $iothubX509Intermediate2Certificate;
+ "IOTHUB-X509-CHAIN-DEVICE-NAME" = $iotHubCertChainDeviceCommonName;
+ "IOTHUB-USER-ASSIGNED-MSI-RESOURCE-ID" = $msiResourceId;
+ "E2E-IKEY" = $instrumentationKey;
+
+ <#[SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="fake shared access token")]#>
+ "IOTHUB-DEVICE-CONN-STRING-INVALIDCERT" = "HostName=invalidcertiothub1.westus.cloudapp.azure.com;DeviceId=DoNotDelete1;SharedAccessKey=zWmeTGWmjcgDG1dpuSCVjc5ZY4TqVnKso5+g1wt/K3E=";
+ <#[SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="fake shared access token")]#>
+ "IOTHUB-CONN-STRING-INVALIDCERT" = "HostName=invalidcertiothub1.westus.cloudapp.azure.com;SharedAccessKeyName=iothubowner;SharedAccessKey=Fk1H0asPeeAwlRkUMTybJasksTYTd13cgI7SsteB05U=";
+ <#[SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="fake shared access token")]#>
+ "PROVISIONING-CONNECTION-STRING-INVALIDCERT" = "HostName=invalidcertdps1.westus.cloudapp.azure.com;SharedAccessKeyName=provisioningserviceowner;SharedAccessKey=lGO7OlXNhXlFyYV1rh9F/lUCQC1Owuh5f/1P0I1AFSY=";
+
+ # These environment variables are only used in Java
+
+ "IOT-DPS-CONNECTION-STRING" = $dpsConnectionString; # DPS Connection string Environment variable for Java
+ "IOT-DPS-ID-SCOPE" = $dpsIdScope; # DPS ID Scope Environment variable for Java
+ "FAR-AWAY-IOTHUB-CONNECTION-STRING" = $farHubConnectionString;
+ "IS-BASIC-TIER-HUB" = "false";
+
+ # These environment variables are used by .NET samples
+
+ "IOTHUB-DEVICE-CONN-STRING" = $iotHubSasBasedDeviceConnectionString;
+ "IOTHUB-MODULE-CONN-STRING" = $iotHubSasBasedModuleConnectionString;
+ "PNP-TC-DEVICE-CONN-STRING" = $temperatureControllerSampleDeviceConnectionString;
+ "PNP-THERMOSTAT-DEVICE-CONN-STRING" = $thermostatSampleDeviceConnectionString;
+ "IOTHUB-SAS-KEY" = $iothubownerSasPrimaryKey;
+ "IOTHUB-SAS-KEY-NAME" = $iothubownerSasPolicy;
+ "DPS-SYMMETRIC-KEY-INDIVIDUAL-ENROLLMENT-REGISTRATION-ID" = $symmetricKeySampleEnrollmentRegistrationId;
+ "DPS-SYMMETRIC-KEY-INDIVIDUAL-ENROLLEMNT-PRIMARY-KEY" = $symmetricKeySampleEnrollmentPrimaryKey;
+}
+
+if ($EnableIotHubSecuritySolution)
+{
+ $keyvaultKvps.Add("LA-WORKSPACE-ID", $workspaceId)
+ $keyvaultKvps.Add("LA-AAD-APP-CERT-BASE64", $fileContentB64String)
+ $keyvaultKvps.Add("LA-AAD-APP-ID", $logAnalyticsAppId)
+}
+
+Write-Host "`nWriting secrets to KeyVault $keyVaultName."
+az keyvault set-policy -g $ResourceGroup --name $keyVaultName --object-id "$userObjectId" --output none --show-only-errors --secret-permissions delete get list set;
+foreach ($kvp in $keyvaultKvps.GetEnumerator())
+{
+ Write-Host "`tWriting $($kvp.Name)."
+ if ($null -eq $kvp.Value)
+ {
+ Write-Warning "`t`tValue is unexpectedly null!";
+ }
+ az keyvault secret set --vault-name $keyVaultName --name $kvp.Name --value "$($kvp.Value)" --output none --only-show-errors
+}
###################################################################################################################################
# Run docker containers for TPM simulators and proxy
@@ -746,6 +783,7 @@ if (-not (docker images -q aziotbld/testproxy))
############################################################################################################################
# Clean up certs and files created by the script
############################################################################################################################
+
CleanUp-Certs
# Creating a file to run to load environment variables
@@ -758,6 +796,7 @@ Add-Content -Path $file.PSPath -Value "$PSScriptRoot\LoadEnvironmentVariablesFro
############################################################################################################################
# Configure environment variables
############################################################################################################################
+
Invoke-Expression "$loadScriptDir\$loadScriptName"
$endTime = (Get-Date)
diff --git a/e2e/test/provisioning/ProvisioningCertificateValidationE2ETest.cs b/e2e/test/provisioning/ProvisioningCertificateValidationE2ETest.cs
index 31d790610c..ca3afe1125 100644
--- a/e2e/test/provisioning/ProvisioningCertificateValidationE2ETest.cs
+++ b/e2e/test/provisioning/ProvisioningCertificateValidationE2ETest.cs
@@ -20,12 +20,12 @@ public class ProvisioningCertificateValidationE2ETest : E2EMsTestBase
[LoggedTestMethod]
public async Task ProvisioningServiceClient_QueryInvalidServiceCertificateHttp_Fails()
{
- using ProvisioningServiceClient provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(
+ using var provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(
TestConfiguration.Provisioning.ConnectionStringInvalidServiceCertificate);
Query q = provisioningServiceClient.CreateEnrollmentGroupQuery(
new QuerySpecification("SELECT * FROM enrollmentGroups"));
- var exception = await Assert.ThrowsExceptionAsync(
+ ProvisioningServiceClientTransportException exception = await Assert.ThrowsExceptionAsync(
() => q.NextAsync()).ConfigureAwait(false);
#if NET472 || NET451
@@ -39,7 +39,7 @@ public async Task ProvisioningServiceClient_QueryInvalidServiceCertificateHttp_F
public async Task ProvisioningDeviceClient_RegisterAsyncInvalidServiceCertificateAmqpTcp_Fails()
{
using var transport = new ProvisioningTransportHandlerAmqp(TransportFallbackType.TcpOnly);
- var exception = await Assert.ThrowsExceptionAsync(
+ ProvisioningTransportException exception = await Assert.ThrowsExceptionAsync(
() => TestInvalidServiceCertificate(transport)).ConfigureAwait(false);
Assert.IsInstanceOfType(exception.InnerException, typeof(AuthenticationException));
@@ -49,7 +49,7 @@ public async Task ProvisioningDeviceClient_RegisterAsyncInvalidServiceCertificat
public async Task ProvisioningDeviceClient_RegisterAsyncInvalidServiceCertificateMqttTcp_Fails()
{
using var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.TcpOnly);
- var exception = await Assert.ThrowsExceptionAsync(
+ ProvisioningTransportException exception = await Assert.ThrowsExceptionAsync(
() => TestInvalidServiceCertificate(transport)).ConfigureAwait(false);
if (exception.InnerException == null)
@@ -66,7 +66,7 @@ public async Task ProvisioningDeviceClient_RegisterAsyncInvalidServiceCertificat
public async Task ProvisioningDeviceClient_RegisterAsyncInvalidServiceCertificateHttp_Fails()
{
using var transport = new ProvisioningTransportHandlerHttp();
- var exception = await Assert.ThrowsExceptionAsync(
+ ProvisioningTransportException exception = await Assert.ThrowsExceptionAsync(
() => TestInvalidServiceCertificate(transport)).ConfigureAwait(false);
#if NET472 || NET451
@@ -80,7 +80,7 @@ public async Task ProvisioningDeviceClient_RegisterAsyncInvalidServiceCertificat
public async Task ProvisioningDeviceClient_RegisterAsyncInvalidServiceCertificateAmqpWs_Fails()
{
using var transport = new ProvisioningTransportHandlerAmqp(TransportFallbackType.WebSocketOnly);
- var exception = await Assert.ThrowsExceptionAsync(
+ ProvisioningTransportException exception = await Assert.ThrowsExceptionAsync(
() => TestInvalidServiceCertificate(transport)).ConfigureAwait(false);
Assert.IsInstanceOfType(exception.InnerException.InnerException.InnerException, typeof(AuthenticationException));
@@ -90,7 +90,7 @@ public async Task ProvisioningDeviceClient_RegisterAsyncInvalidServiceCertificat
public async Task ProvisioningDeviceClient_RegisterAsyncInvalidServiceCertificateMqttWs_Fails()
{
using var transport = new ProvisioningTransportHandlerMqtt(TransportFallbackType.WebSocketOnly);
- var exception = await Assert.ThrowsExceptionAsync(
+ ProvisioningTransportException exception = await Assert.ThrowsExceptionAsync(
() => TestInvalidServiceCertificate(transport)).ConfigureAwait(false);
Assert.IsInstanceOfType(exception.InnerException.InnerException.InnerException, typeof(AuthenticationException));
@@ -100,7 +100,7 @@ private static async Task TestInvalidServiceCertificate(ProvisioningTransportHan
{
using X509Certificate2 cert = TestConfiguration.Provisioning.GetIndividualEnrollmentCertificate();
using var security = new SecurityProviderX509Certificate(cert);
- ProvisioningDeviceClient provisioningDeviceClient = ProvisioningDeviceClient.Create(
+ var provisioningDeviceClient = ProvisioningDeviceClient.Create(
TestConfiguration.Provisioning.GlobalDeviceEndpointInvalidServiceCertificate,
"0ne00000001",
security,
diff --git a/e2e/test/provisioning/ProvisioningE2ETests.cs b/e2e/test/provisioning/ProvisioningE2ETests.cs
index 5f56f48c22..61c73f1698 100644
--- a/e2e/test/provisioning/ProvisioningE2ETests.cs
+++ b/e2e/test/provisioning/ProvisioningE2ETests.cs
@@ -4,14 +4,12 @@
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;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.Devices.Client;
-using Microsoft.Azure.Devices.E2ETests.Helpers;
using Microsoft.Azure.Devices.Provisioning.Client;
using Microsoft.Azure.Devices.Provisioning.Client.Transport;
using Microsoft.Azure.Devices.Provisioning.Security.Samples;
@@ -559,7 +557,7 @@ public async Task ProvisioningDeviceClient_ValidRegistrationId_TimeSpanTimeoutRe
transport.Proxy = (proxyServerAddress != null) ? new WebProxy(s_proxyServerAddress) : null;
}
- ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create(
+ var provClient = ProvisioningDeviceClient.Create(
s_globalDeviceEndpoint,
TestConfiguration.Provisioning.IdScope,
security,
@@ -577,14 +575,9 @@ public async Task ProvisioningDeviceClient_ValidRegistrationId_TimeSpanTimeoutRe
{
try
{
- if (timeout != TimeSpan.MaxValue)
- {
- result = await provClient.RegisterAsync(timeout).ConfigureAwait(false);
- }
- else
- {
- result = await provClient.RegisterAsync(cts.Token).ConfigureAwait(false);
- }
+ result = timeout != TimeSpan.MaxValue
+ ? await provClient.RegisterAsync(timeout).ConfigureAwait(false)
+ : await provClient.RegisterAsync(cts.Token).ConfigureAwait(false);
break;
}
// Catching all ProvisioningTransportException as the status code is not the same for Mqtt, Amqp and Http.
@@ -653,7 +646,7 @@ public async Task ProvisioningDeviceClient_ValidRegistrationId_TimeSpanTimeoutRe
transport.Proxy = (proxyServerAddress != null) ? new WebProxy(s_proxyServerAddress) : null;
}
- ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create(
+ var provClient = ProvisioningDeviceClient.Create(
s_globalDeviceEndpoint,
TestConfiguration.Provisioning.IdScope,
security,
@@ -720,7 +713,7 @@ public async Task ProvisioningDeviceClient_InvalidRegistrationId_TpmRegister_Fai
{
using ProvisioningTransportHandler transport = CreateTransportHandlerFromName(transportProtocol);
using SecurityProvider security = new SecurityProviderTpmSimulator("invalidregistrationid");
- ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create(
+ var provClient = ProvisioningDeviceClient.Create(
s_globalDeviceEndpoint,
TestConfiguration.Provisioning.IdScope,
security,
@@ -829,7 +822,7 @@ public async Task ProvisioningDeviceClient_InvalidIdScope_Register_MqttWs_X509Gr
{
using ProvisioningTransportHandler transport = CreateTransportHandlerFromName(transportProtocol);
using SecurityProvider security = await CreateSecurityProviderFromNameAsync(attestationType, enrollmentType, groupId, null, AllocationPolicy.Hashed, null, null).ConfigureAwait(false);
- ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create(
+ var provClient = ProvisioningDeviceClient.Create(
s_globalDeviceEndpoint,
InvalidIdScope,
security,
@@ -837,7 +830,7 @@ public async Task ProvisioningDeviceClient_InvalidIdScope_Register_MqttWs_X509Gr
using var cts = new CancellationTokenSource(FailingTimeoutMiliseconds);
- var exception = await Assert.ThrowsExceptionAsync(
+ ProvisioningTransportException exception = await Assert.ThrowsExceptionAsync(
() => provClient.RegisterAsync(cts.Token)).ConfigureAwait(false);
Logger.Trace($"Exception: {exception}");
@@ -887,7 +880,7 @@ public async Task ProvisioningDeviceClient_InvalidGlobalAddress_Register_MqttWs_
using ProvisioningTransportHandler transport = CreateTransportHandlerFromName(transportProtocol);
using SecurityProvider security = await CreateSecurityProviderFromNameAsync(attestationType, enrollmentType, groupId, null, AllocationPolicy.Hashed, null, null).ConfigureAwait(false);
- ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create(
+ var provClient = ProvisioningDeviceClient.Create(
InvalidGlobalAddress,
TestConfiguration.Provisioning.IdScope,
security,
@@ -936,7 +929,7 @@ public static ProvisioningTransportHandler CreateTransportHandlerFromName(Client
/// CreateSecurityProviderFromNameAsync(Attesta
{
_verboseLog.WriteLine($"{nameof(CreateSecurityProviderFromNameAsync)}({attestationType})");
- using ProvisioningServiceClient provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(TestConfiguration.Provisioning.ConnectionString);
+ using var provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(TestConfiguration.Provisioning.ConnectionString);
switch (attestationType)
{
@@ -1016,7 +1009,7 @@ private async Task CreateSecurityProviderFromNameAsync(Attesta
case EnrollmentType.Group:
EnrollmentGroup symmetricKeyEnrollmentGroup = await CreateEnrollmentGroup(provisioningServiceClient, AttestationMechanismType.SymmetricKey, groupId, reprovisionPolicy, allocationPolicy, customAllocationDefinition, iothubs, capabilities).ConfigureAwait(false);
Assert.IsTrue(symmetricKeyEnrollmentGroup.Attestation is SymmetricKeyAttestation);
- SymmetricKeyAttestation symmetricKeyAttestation = (SymmetricKeyAttestation)symmetricKeyEnrollmentGroup.Attestation;
+ var symmetricKeyAttestation = (SymmetricKeyAttestation)symmetricKeyEnrollmentGroup.Attestation;
string registrationIdSymmetricKey = _idPrefix + Guid.NewGuid();
string primaryKeyEnrollmentGroup = symmetricKeyAttestation.PrimaryKey;
string secondaryKeyEnrollmentGroup = symmetricKeyAttestation.SecondaryKey;
diff --git a/e2e/test/provisioning/ProvisioningServiceClientE2ETests.cs b/e2e/test/provisioning/ProvisioningServiceClientE2ETests.cs
index 3757ae6825..1ada9be022 100644
--- a/e2e/test/provisioning/ProvisioningServiceClientE2ETests.cs
+++ b/e2e/test/provisioning/ProvisioningServiceClientE2ETests.cs
@@ -76,7 +76,7 @@ public async Task ProvisioningServiceClient_SymmetricKey_GroupEnrollments_Create
//This webhook won't actually work for reprovisioning, but this test is only testing that the field is accepted by the service
var customAllocationDefinition = new CustomAllocationDefinition { ApiVersion = "2019-03-31", WebhookUrl = "https://www.microsoft.com" };
var reprovisionPolicy = new ReprovisionPolicy { MigrateDeviceData = false, UpdateHubAssignment = true };
- var allocationPolicy = AllocationPolicy.GeoLatency;
+ AllocationPolicy allocationPolicy = AllocationPolicy.GeoLatency;
await ProvisioningServiceClient_GroupEnrollments_Create_Ok("", AttestationMechanismType.SymmetricKey, reprovisionPolicy, allocationPolicy, customAllocationDefinition, null).ConfigureAwait(false);
}
@@ -112,7 +112,7 @@ public async Task ProvisioningServiceClient_GetEnrollmentGroupAttestation_Symmet
public async Task ProvisioningServiceClient_GetIndividualEnrollmentAttestation(AttestationMechanismType attestationType)
{
- using ProvisioningServiceClient provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(TestConfiguration.Provisioning.ConnectionString);
+ using var 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);
@@ -120,21 +120,21 @@ public async Task ProvisioningServiceClient_GetIndividualEnrollmentAttestation(A
if (attestationType == AttestationMechanismType.SymmetricKey)
{
Assert.AreEqual(AttestationMechanismType.SymmetricKey, attestationMechanism.Type);
- SymmetricKeyAttestation symmetricKeyAttestation = (SymmetricKeyAttestation)attestationMechanism.GetAttestation();
+ var symmetricKeyAttestation = (SymmetricKeyAttestation)attestationMechanism.GetAttestation();
Assert.AreEqual(((SymmetricKeyAttestation)individualEnrollment.Attestation).PrimaryKey, symmetricKeyAttestation.PrimaryKey);
Assert.AreEqual(((SymmetricKeyAttestation)individualEnrollment.Attestation).SecondaryKey, symmetricKeyAttestation.SecondaryKey);
}
else if (attestationType == AttestationMechanismType.X509)
{
Assert.AreEqual(AttestationMechanismType.X509, attestationMechanism.Type);
- X509Attestation x509Attestation = (X509Attestation)attestationMechanism.GetAttestation();
+ var x509Attestation = (X509Attestation)attestationMechanism.GetAttestation();
Assert.AreEqual(((X509Attestation)individualEnrollment.Attestation).GetPrimaryX509CertificateInfo().SHA1Thumbprint, x509Attestation.GetPrimaryX509CertificateInfo().SHA1Thumbprint);
Assert.AreEqual(((X509Attestation)individualEnrollment.Attestation).GetSecondaryX509CertificateInfo().SHA1Thumbprint, x509Attestation.GetSecondaryX509CertificateInfo().SHA1Thumbprint);
}
else
{
Assert.AreEqual(AttestationMechanismType.Tpm, attestationMechanism.Type);
- TpmAttestation tpmAttestation = (TpmAttestation)attestationMechanism.GetAttestation();
+ var tpmAttestation = (TpmAttestation)attestationMechanism.GetAttestation();
Assert.AreEqual(((TpmAttestation)individualEnrollment.Attestation).EndorsementKey, tpmAttestation.EndorsementKey);
Assert.AreEqual(((TpmAttestation)individualEnrollment.Attestation).StorageRootKey, tpmAttestation.StorageRootKey);
}
@@ -142,7 +142,7 @@ public async Task ProvisioningServiceClient_GetIndividualEnrollmentAttestation(A
public async Task ProvisioningServiceClient_GetEnrollmentGroupAttestation(AttestationMechanismType attestationType)
{
- using ProvisioningServiceClient provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(TestConfiguration.Provisioning.ConnectionString);
+ using var 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);
@@ -152,14 +152,14 @@ public async Task ProvisioningServiceClient_GetEnrollmentGroupAttestation(Attest
if (attestationType == AttestationMechanismType.SymmetricKey)
{
Assert.AreEqual(AttestationMechanismType.SymmetricKey, attestationMechanism.Type);
- SymmetricKeyAttestation symmetricKeyAttestation = (SymmetricKeyAttestation)attestationMechanism.GetAttestation();
+ var symmetricKeyAttestation = (SymmetricKeyAttestation)attestationMechanism.GetAttestation();
Assert.AreEqual(((SymmetricKeyAttestation)enrollmentGroup.Attestation).PrimaryKey, symmetricKeyAttestation.PrimaryKey);
Assert.AreEqual(((SymmetricKeyAttestation)enrollmentGroup.Attestation).SecondaryKey, symmetricKeyAttestation.SecondaryKey);
}
else if (attestationType == AttestationMechanismType.X509)
{
Assert.AreEqual(AttestationMechanismType.X509, attestationMechanism.Type);
- X509Attestation x509Attestation = (X509Attestation)attestationMechanism.GetAttestation();
+ var x509Attestation = (X509Attestation)attestationMechanism.GetAttestation();
Assert.AreEqual(((X509Attestation)enrollmentGroup.Attestation).GetPrimaryX509CertificateInfo().SHA1Thumbprint, x509Attestation.GetPrimaryX509CertificateInfo().SHA1Thumbprint);
Assert.AreEqual(((X509Attestation)enrollmentGroup.Attestation).GetSecondaryX509CertificateInfo().SHA1Thumbprint, x509Attestation.GetSecondaryX509CertificateInfo().SHA1Thumbprint);
}
@@ -266,7 +266,7 @@ public static async Task CreateIndividualEnrollment(Provis
using (var tpmSim = new SecurityProviderTpmSimulator(registrationId))
{
string base64Ek = Convert.ToBase64String(tpmSim.GetEndorsementKey());
- using ProvisioningServiceClient provisioningService = ProvisioningServiceClient.CreateFromConnectionString(TestConfiguration.Provisioning.ConnectionString);
+ using var provisioningService = ProvisioningServiceClient.CreateFromConnectionString(TestConfiguration.Provisioning.ConnectionString);
individualEnrollment = new IndividualEnrollment(registrationId, new TpmAttestation(base64Ek))
{
Capabilities = capabilities,
diff --git a/e2e/test/provisioning/ReprovisioningE2ETests.cs b/e2e/test/provisioning/ReprovisioningE2ETests.cs
index f647a52d02..d80d2170ef 100644
--- a/e2e/test/provisioning/ReprovisioningE2ETests.cs
+++ b/e2e/test/provisioning/ReprovisioningE2ETests.cs
@@ -211,7 +211,7 @@ 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)
{
- IotHubConnectionStringBuilder connectionString = IotHubConnectionStringBuilder.Create(TestConfiguration.IoTHub.ConnectionString);
+ 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,7 +223,7 @@ 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)
{
- IotHubConnectionStringBuilder connectionString = IotHubConnectionStringBuilder.Create(TestConfiguration.IoTHub.ConnectionString);
+ 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,7 +234,7 @@ 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)
{
- IotHubConnectionStringBuilder connectionString = IotHubConnectionStringBuilder.Create(TestConfiguration.IoTHub.ConnectionString);
+ 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);
@@ -281,7 +281,7 @@ private async Task ProvisioningDeviceClient_ReprovisioningFlow_DoNotReprovision(
transport.Proxy = (proxyServerAddress != null) ? new WebProxy(s_proxyServerAddress) : null;
}
- ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create(
+ var provClient = ProvisioningDeviceClient.Create(
s_globalDeviceEndpoint,
TestConfiguration.Provisioning.IdScope,
security,
@@ -320,7 +320,7 @@ private async Task ProvisioningDeviceClient_ReprovisioningFlow_DoNotReprovision(
///
private async Task ConfirmRegisteredDeviceWorks(DeviceRegistrationResult result, Client.IAuthenticationMethod auth, Client.TransportType transportProtocol, bool sendReportedPropertiesUpdate)
{
- using (DeviceClient iotClient = DeviceClient.Create(result.AssignedHub, auth, transportProtocol))
+ using (var iotClient = DeviceClient.Create(result.AssignedHub, auth, transportProtocol))
{
Logger.Trace("DeviceClient OpenAsync.");
await iotClient.OpenAsync().ConfigureAwait(false);
@@ -346,7 +346,7 @@ private async Task ConfirmExpectedDeviceCapabilities(DeviceRegistrationResult re
if (capabilities != null)
{
//hardcoding amqp since http does not support twin, but tests that call into this may use http
- using (DeviceClient iotClient = DeviceClient.Create(result.AssignedHub, auth, Client.TransportType.Amqp))
+ using (var iotClient = DeviceClient.Create(result.AssignedHub, auth, Client.TransportType.Amqp))
{
//Confirm that the device twin reflects what the enrollment dictated
Twin twin = await iotClient.GetTwinAsync().ConfigureAwait(false);
@@ -369,7 +369,7 @@ private async Task CreateSecurityProviderFromName(AttestationM
string base64Ek = Convert.ToBase64String(tpmSim.GetEndorsementKey());
- using (ProvisioningServiceClient provisioningService = ProvisioningServiceClient.CreateFromConnectionString(TestConfiguration.Provisioning.ConnectionString))
+ using (var provisioningService = ProvisioningServiceClient.CreateFromConnectionString(TestConfiguration.Provisioning.ConnectionString))
{
Logger.Trace($"Getting enrollment: RegistrationID = {registrationId}");
var individualEnrollment = new IndividualEnrollment(registrationId, new TpmAttestation(base64Ek)) { AllocationPolicy = allocationPolicy, ReprovisionPolicy = reprovisionPolicy, IotHubs = iothubs, CustomAllocationDefinition = customAllocationDefinition, Capabilities = capabilities };
@@ -409,7 +409,7 @@ private async Task CreateSecurityProviderFromName(AttestationM
case EnrollmentType.Group:
EnrollmentGroup symmetricKeyEnrollmentGroup = await CreateEnrollmentGroup(provisioningServiceClient, AttestationMechanismType.SymmetricKey, groupId, reprovisionPolicy, allocationPolicy, customAllocationDefinition, iothubs, capabilities).ConfigureAwait(false);
Assert.IsTrue(symmetricKeyEnrollmentGroup.Attestation is SymmetricKeyAttestation);
- SymmetricKeyAttestation symmetricKeyAttestation = (SymmetricKeyAttestation)symmetricKeyEnrollmentGroup.Attestation;
+ var symmetricKeyAttestation = (SymmetricKeyAttestation)symmetricKeyEnrollmentGroup.Attestation;
string registrationIdSymmetricKey = _devicePrefix + Guid.NewGuid();
string primaryKeyEnrollmentGroup = symmetricKeyAttestation.PrimaryKey;
string secondaryKeyEnrollmentGroup = symmetricKeyAttestation.SecondaryKey;
@@ -525,7 +525,7 @@ private void ConfirmDeviceInExpectedHub(DeviceRegistrationResult result, Reprovi
private async Task ConfirmDeviceWorksAfterReprovisioning(DeviceRegistrationResult result, Client.IAuthenticationMethod auth, Client.TransportType transportProtocol, ReprovisionPolicy reprovisionPolicy, bool twinOperationsAllowed)
{
- using (DeviceClient iotClient = DeviceClient.Create(result.AssignedHub, auth, transportProtocol))
+ using (var iotClient = DeviceClient.Create(result.AssignedHub, auth, transportProtocol))
{
Logger.Trace("DeviceClient OpenAsync.");
await iotClient.OpenAsync().ConfigureAwait(false);
diff --git a/iothub/device/devdoc/Convention-based operations.md b/iothub/device/devdoc/Convention-based operations.md
index 49216ecc89..43321f4828 100644
--- a/iothub/device/devdoc/Convention-based operations.md
+++ b/iothub/device/devdoc/Convention-based operations.md
@@ -43,23 +43,40 @@ public abstract class PayloadSerializer {
}
public sealed class DefaultPayloadConvention : PayloadConvention {
+<<<<<<< HEAD
public static readonly DefaultPayloadConvention Instance;
public DefaultPayloadConvention();
+=======
+ public DefaultPayloadConvention();
+ public static DefaultPayloadConvention Instance { get; }
+>>>>>>> previews/pnpApi
public override PayloadEncoder PayloadEncoder { get; }
public override PayloadSerializer PayloadSerializer { get; }
}
public class Utf8PayloadEncoder : PayloadEncoder {
+<<<<<<< HEAD
public static readonly Utf8PayloadEncoder Instance;
public Utf8PayloadEncoder();
public override Encoding ContentEncoding { get; }
+=======
+ public Utf8PayloadEncoder();
+ public override Encoding ContentEncoding { get; }
+ public static Utf8PayloadEncoder Instance { get; }
+>>>>>>> previews/pnpApi
public override byte[] EncodeStringToByteArray(string contentPayload);
}
public class NewtonsoftJsonPayloadSerializer : PayloadSerializer {
+<<<<<<< HEAD
public static readonly NewtonsoftJsonPayloadSerializer Instance;
public NewtonsoftJsonPayloadSerializer();
public override string ContentType { get; }
+=======
+ public NewtonsoftJsonPayloadSerializer();
+ public override string ContentType { get; }
+ public static NewtonsoftJsonPayloadSerializer Instance { get; }
+>>>>>>> previews/pnpApi
public override T ConvertFromObject(object objectToConvert);
public override IWritablePropertyResponse CreateWritablePropertyResponse(object value, int statusCode, long version, string description = null);
public override T DeserializeToType(string stringToDeserialize);
@@ -69,7 +86,10 @@ public class NewtonsoftJsonPayloadSerializer : PayloadSerializer {
public abstract class PayloadCollection : IEnumerable, IEnumerable> {
protected PayloadCollection();
+<<<<<<< HEAD
public IDictionary Collection { get; private set; }
+=======
+>>>>>>> previews/pnpApi
public PayloadConvention Convention { get; internal set; }
public virtual object this[string key] { get; set; }
public virtual void Add(string key, object value);
@@ -121,12 +141,11 @@ public Task GetClientPropertiesAsync(CancellationToken cancell
public Task UpdateClientPropertiesAsync(ClientPropertyCollection propertyCollection, CancellationToken cancellationToken = default);
///
-/// Sets the global listener for Writable properties
+/// Sets the listener for writable property update events.
///
-/// The global call back to handle all writable property updates.
-/// Generic parameter to be interpreted by the client code.
+/// The callback to handle all writable property updates for the client.
/// A cancellation token to cancel the operation.
-public Task SubscribeToWritablePropertyUpdateRequestsAsync(Func callback, object userContext, CancellationToken cancellationToken = default);
+public Task SubscribeToWritablePropertyUpdateRequestsAsync(Func callback, CancellationToken cancellationToken = default);
```
#### All related types
@@ -134,8 +153,8 @@ public Task SubscribeToWritablePropertyUpdateRequestsAsync(Func telemetryValues);
public override void Add(string telemetryName, object telemetryValue);
+ public void AddOrUpdate(IDictionary telemetryValues);
public override void AddOrUpdate(string telemetryName, object telemetryValue);
}
@@ -214,28 +235,29 @@ public sealed class TelemetryMessage : MessageBase {
```csharp
///
-/// Set the global command callback handler.
+/// Sets the listener for command invocation requests.
///
-/// A method implementation that will handle the incoming command.
-/// Generic parameter to be interpreted by the client code.
+/// The callback to handle all incoming commands for the client.
/// A cancellation token to cancel the operation.
-public Task SubscribeToCommandsAsync(Func> callback, object userContext, CancellationToken cancellationToken = default);
+public Task SubscribeToCommandsAsync(Func> callback, CancellationToken cancellationToken = default);
```
#### All related types
```csharp
public sealed class CommandRequest {
- public string CommandName { get; private set; }
- public string ComponentName { get; private set; }
- public string DataAsJson { get; }
- public T GetData();
- public byte[] GetDataAsBytes();
+ public CommandRequest();
+ public string CommandName { get; }
+ public string ComponentName { get; }
+ public T GetPayload();
+ public ReadOnlyCollection GetPayloadAsBytes();
+ public string GetPayloadAsString();
}
public sealed class CommandResponse {
+ public CommandResponse();
public CommandResponse(int status);
- public CommandResponse(object result, int status);
- public string ResultAsJson { get; }
- public int Status { get; private set; }
+ public CommandResponse(object payload, int status);
+ public object Payload { get; }
+ public int Status { get; }
}
```
diff --git a/iothub/device/src/AmqpTransportSettings.cs b/iothub/device/src/AmqpTransportSettings.cs
index 59b56192bf..84a427e4eb 100644
--- a/iothub/device/src/AmqpTransportSettings.cs
+++ b/iothub/device/src/AmqpTransportSettings.cs
@@ -156,9 +156,7 @@ public TimeSpan OpenTimeout
///
public X509Certificate2 ClientCertificate { get; set; }
- ///
- /// The proxy
- ///
+ ///
public IWebProxy Proxy { get; set; }
///
diff --git a/iothub/device/src/AuthenticationMethodFactory.cs b/iothub/device/src/AuthenticationMethodFactory.cs
index 85f68a908d..c371040a20 100644
--- a/iothub/device/src/AuthenticationMethodFactory.cs
+++ b/iothub/device/src/AuthenticationMethodFactory.cs
@@ -33,16 +33,14 @@ internal static IAuthenticationMethod GetAuthenticationMethod(IotHubConnectionSt
}
else if (iotHubConnectionStringBuilder.SharedAccessSignature != null)
{
- if (iotHubConnectionStringBuilder.ModuleId != null)
- {
- return new ModuleAuthenticationWithToken(
- iotHubConnectionStringBuilder.DeviceId, iotHubConnectionStringBuilder.ModuleId, iotHubConnectionStringBuilder.SharedAccessSignature);
- }
- else
- {
- return new DeviceAuthenticationWithToken(
- iotHubConnectionStringBuilder.DeviceId, iotHubConnectionStringBuilder.SharedAccessSignature);
- }
+ return iotHubConnectionStringBuilder.ModuleId != null
+ ? new ModuleAuthenticationWithToken(
+ iotHubConnectionStringBuilder.DeviceId,
+ iotHubConnectionStringBuilder.ModuleId,
+ iotHubConnectionStringBuilder.SharedAccessSignature)
+ : (IAuthenticationMethod)new DeviceAuthenticationWithToken(
+ iotHubConnectionStringBuilder.DeviceId,
+ iotHubConnectionStringBuilder.SharedAccessSignature);
}
else if (iotHubConnectionStringBuilder.UsingX509Cert)
{
diff --git a/iothub/device/src/ClientFactory.cs b/iothub/device/src/ClientFactory.cs
index 3532c5516c..3ab6d9b710 100644
--- a/iothub/device/src/ClientFactory.cs
+++ b/iothub/device/src/ClientFactory.cs
@@ -122,12 +122,11 @@ internal static InternalClient Create(string hostname, IAuthenticationMethod aut
throw new ArgumentException("No certificate was found. To use certificate authentication certificate must be present.");
}
-#pragma warning disable CA2000 // This is returned to client so cannot be disposed here.
InternalClient dc = CreateFromConnectionString(
connectionStringBuilder.ToString(),
PopulateCertificateInTransportSettings(connectionStringBuilder, transportType),
options);
-#pragma warning restore CA2000
+
dc.Certificate = connectionStringBuilder.Certificate;
// Install all the intermediate certificates in the chain if specified.
@@ -438,7 +437,7 @@ internal static ITransportSettings[] GetTransportSettings(TransportType transpor
builder.SasTokenRenewalBuffer = options?.SasTokenRenewalBuffer ?? default;
}
- IotHubConnectionString iotHubConnectionString = builder.ToIotHubConnectionString();
+ var iotHubConnectionString = builder.ToIotHubConnectionString();
foreach (ITransportSettings transportSetting in transportSettings)
{
@@ -612,7 +611,7 @@ private static IDeviceClientPipelineBuilder BuildPipeline()
private static ITransportSettings[] PopulateCertificateInTransportSettings(IotHubConnectionStringBuilder connectionStringBuilder, ITransportSettings[] transportSettings)
{
- foreach (var transportSetting in transportSettings)
+ foreach (ITransportSettings transportSetting in transportSettings)
{
switch (transportSetting.GetTransportType())
{
diff --git a/iothub/device/src/ClientProperties.cs b/iothub/device/src/ClientProperties.cs
index 31c8fe4966..8a3247fbb4 100644
--- a/iothub/device/src/ClientProperties.cs
+++ b/iothub/device/src/ClientProperties.cs
@@ -40,7 +40,7 @@ internal ClientProperties(ClientPropertyCollection writablePropertyRequestCollec
///
/// See the Writable properties documentation for more information.
///
- public ClientPropertyCollection WritablePropertyRequests { get; private set; }
+ public ClientPropertyCollection WritablePropertyRequests { get; }
///
/// The collection of properties reported by the client.
@@ -49,6 +49,6 @@ internal ClientProperties(ClientPropertyCollection writablePropertyRequestCollec
/// Client reported properties can either be Read-only properties
/// or they can be Writable properties.
///
- public ClientPropertyCollection ReportedFromClient { get; private set; }
+ public ClientPropertyCollection ReportedFromClient { get; }
}
}
diff --git a/iothub/device/src/CommandRequest.cs b/iothub/device/src/CommandRequest.cs
index 9b434f34a6..3c14956010 100644
--- a/iothub/device/src/CommandRequest.cs
+++ b/iothub/device/src/CommandRequest.cs
@@ -1,7 +1,8 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-using System.Text;
+using System.Collections.ObjectModel;
+using System.Linq;
using Microsoft.Azure.Devices.Shared;
namespace Microsoft.Azure.Devices.Client
@@ -11,35 +12,42 @@ namespace Microsoft.Azure.Devices.Client
///
public sealed class CommandRequest
{
- private readonly byte[] _data;
+ private readonly ReadOnlyCollection _payload;
private readonly PayloadConvention _payloadConvention;
+ ///
+ /// Public constructor provided only for mocking purposes.
+ ///
+ public CommandRequest()
+ {
+ }
+
internal CommandRequest(PayloadConvention payloadConvention, string commandName, string componentName = default, byte[] data = default)
{
CommandName = commandName;
ComponentName = componentName;
- _data = data;
+ _payload = new ReadOnlyCollection(data);
_payloadConvention = payloadConvention;
}
///
/// The name of the component that is command is invoked on.
///
- public string ComponentName { get; private set; }
+ public string ComponentName { get; }
///
/// The command name.
///
- public string CommandName { get; private set; }
+ public string CommandName { get; }
///
/// The command request data.
///
/// The type to cast the command request data to.
/// The command request data.
- public T GetData()
+ public T GetPayload()
{
- string dataAsJson = DataAsJson;
+ string dataAsJson = GetPayloadAsString();
return dataAsJson == null
? default
@@ -52,16 +60,21 @@ public T GetData()
///
/// The command request data bytes.
///
- public byte[] GetDataAsBytes()
+ public ReadOnlyCollection GetPayloadAsBytes()
{
// Need to return a clone of the array so that consumers
// of this library cannot change its contents.
- return (byte[])_data.Clone();
+ return _payload;
}
///
- /// The command data in Json format.
+ /// The command data as a string.
///
- public string DataAsJson => (_data == null || _data.Length == 0) ? null : Encoding.UTF8.GetString(_data);
+ public string GetPayloadAsString()
+ {
+ return _payload.Count == 0
+ ? null
+ : _payloadConvention.PayloadEncoder.ContentEncoding.GetString(GetPayloadAsBytes().ToArray());
+ }
}
}
diff --git a/iothub/device/src/CommandResponse.cs b/iothub/device/src/CommandResponse.cs
index 465cecc78e..ec41a62fee 100644
--- a/iothub/device/src/CommandResponse.cs
+++ b/iothub/device/src/CommandResponse.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.Text;
using Microsoft.Azure.Devices.Shared;
namespace Microsoft.Azure.Devices.Client
@@ -11,18 +10,25 @@ namespace Microsoft.Azure.Devices.Client
///
public sealed class CommandResponse
{
- private readonly object _result;
+ private readonly object _payload;
internal PayloadConvention PayloadConvention { get; set; }
+ ///
+ /// Public constructor provided only for mocking purposes.
+ ///
+ public CommandResponse()
+ {
+ }
+
///
/// Creates a new instance of the class with the associated command response data and a status code.
///
- /// The command response data.
+ /// The command response payload.
/// A status code indicating success or failure.
- public CommandResponse(object result, int status)
+ public CommandResponse(object payload, int status)
{
- _result = result;
+ _payload = payload;
Status = status;
}
@@ -38,13 +44,28 @@ public CommandResponse(int status)
///
/// The command response status code indicating success or failure.
///
- public int Status { get; private set; }
+ public int Status { get; }
+
+ ///
+ /// The command response payload.
+ ///
+ public object Payload { get; }
///
/// The serialized command response data.
///
- public string ResultAsJson => _result == null ? null : PayloadConvention.PayloadSerializer.SerializeToString(_result);
+ internal string GetPayloadAsString()
+ {
+ return _payload == null
+ ? null
+ : PayloadConvention.PayloadSerializer.SerializeToString(_payload);
+ }
- internal byte[] ResultAsBytes => _result == null ? null : Encoding.UTF8.GetBytes(ResultAsJson);
+ internal byte[] GetPayloadAsBytes()
+ {
+ return _payload == null
+ ? null
+ : PayloadConvention.PayloadEncoder.ContentEncoding.GetBytes(GetPayloadAsString());
+ }
}
}
diff --git a/iothub/device/src/Common/Amqp/ClientWebSocketTransport.cs b/iothub/device/src/Common/Amqp/ClientWebSocketTransport.cs
index e17018693b..da7e9f7eb3 100644
--- a/iothub/device/src/Common/Amqp/ClientWebSocketTransport.cs
+++ b/iothub/device/src/Common/Amqp/ClientWebSocketTransport.cs
@@ -249,7 +249,7 @@ private static void OnReadComplete(IAsyncResult result)
private static void HandleReadComplete(IAsyncResult result)
{
- Task taskResult = (Task)result;
+ var taskResult = (Task)result;
var args = (TransportAsyncCallbackArgs)taskResult.AsyncState;
ReadTaskDone(taskResult, args);
@@ -291,7 +291,7 @@ private static void OnWriteComplete(IAsyncResult result)
private static void HandleWriteComplete(IAsyncResult result)
{
- Task taskResult = (Task)result;
+ var taskResult = (Task)result;
var args = (TransportAsyncCallbackArgs)taskResult.AsyncState;
WriteTaskDone(taskResult, args);
args.CompletedCallback(args);
diff --git a/iothub/device/src/Common/Extensions/CommonExtensions.cs b/iothub/device/src/Common/Extensions/CommonExtensions.cs
index 95f2c6ddb1..944e21eda8 100644
--- a/iothub/device/src/Common/Extensions/CommonExtensions.cs
+++ b/iothub/device/src/Common/Extensions/CommonExtensions.cs
@@ -121,7 +121,7 @@ public static string GetMaskedClientIpAddress(this HttpRequestMessage requestMes
// note that this only works if we are hosted as an OWIN app
if (requestMessage.Properties.ContainsKey("MS_OwinContext"))
{
- OwinContext owinContext = requestMessage.Properties["MS_OwinContext"] as OwinContext;
+ var owinContext = requestMessage.Properties["MS_OwinContext"] as OwinContext;
if (owinContext != null)
{
string remoteIpAddress = owinContext.Request.RemoteIpAddress;
diff --git a/iothub/device/src/Common/Fx.cs b/iothub/device/src/Common/Fx.cs
index 14dc31e8ec..12d03b05b6 100644
--- a/iothub/device/src/Common/Fx.cs
+++ b/iothub/device/src/Common/Fx.cs
@@ -212,7 +212,7 @@ internal static Type[] BreakOnExceptionTypes
string[] typeNames = value as string[];
if (typeNames != null && typeNames.Length > 0)
{
- List types = new List(typeNames.Length);
+ var types = new List(typeNames.Length);
for (int i = 0; i < typeNames.Length; i++)
{
types.Add(Type.GetType(typeNames[i], false));
diff --git a/iothub/device/src/Common/PartialTrustHelpers.cs b/iothub/device/src/Common/PartialTrustHelpers.cs
index fbd857815e..0d7976e9bd 100644
--- a/iothub/device/src/Common/PartialTrustHelpers.cs
+++ b/iothub/device/src/Common/PartialTrustHelpers.cs
@@ -173,7 +173,7 @@ internal static bool HasEtwPermissions()
throw new NotImplementedException();
#else
//Currently unrestricted permissions are required to create Etw provider.
- PermissionSet permissions = new PermissionSet(PermissionState.Unrestricted);
+ var permissions = new PermissionSet(PermissionState.Unrestricted);
return CheckAppDomainPermissions(permissions);
#endif
}
diff --git a/iothub/device/src/Common/ReadOnlyDictionary45.cs b/iothub/device/src/Common/ReadOnlyDictionary45.cs
index 7faf42c1a6..f63baf8af2 100644
--- a/iothub/device/src/Common/ReadOnlyDictionary45.cs
+++ b/iothub/device/src/Common/ReadOnlyDictionary45.cs
@@ -283,7 +283,7 @@ bool IDictionary.Contains(object key)
IDictionaryEnumerator IDictionary.GetEnumerator()
{
- IDictionary d = Dictionary as IDictionary;
+ var d = Dictionary as IDictionary;
if (d != null)
{
return d.GetEnumerator();
@@ -352,17 +352,17 @@ void ICollection.CopyTo(Array array, int index)
throw Fx.Exception.Argument(nameof(array), Resources.InvalidBufferSize);
}
- KeyValuePair[] pairs = array as KeyValuePair[];
+ var pairs = array as KeyValuePair[];
if (pairs != null)
{
Dictionary.CopyTo(pairs, index);
}
else
{
- DictionaryEntry[] dictEntryArray = array as DictionaryEntry[];
+ var dictEntryArray = array as DictionaryEntry[];
if (dictEntryArray != null)
{
- foreach (var item in Dictionary)
+ foreach (KeyValuePair item in Dictionary)
{
dictEntryArray[index++] = new DictionaryEntry(item.Key, item.Value);
}
@@ -377,7 +377,7 @@ void ICollection.CopyTo(Array array, int index)
try
{
- foreach (var item in Dictionary)
+ foreach (KeyValuePair item in Dictionary)
{
objects[index++] = new KeyValuePair(item.Key, item.Value);
}
@@ -401,7 +401,7 @@ object ICollection.SyncRoot
{
if (_syncRoot == null)
{
- ICollection c = Dictionary as ICollection;
+ var c = Dictionary as ICollection;
if (c != null)
{
_syncRoot = c.SyncRoot;
@@ -568,7 +568,7 @@ object ICollection.SyncRoot
{
if (_syncRoot == null)
{
- ICollection c = _collection as ICollection;
+ var c = _collection as ICollection;
if (c != null)
{
_syncRoot = c.SyncRoot;
@@ -715,7 +715,7 @@ object ICollection.SyncRoot
{
if (m_syncRoot == null)
{
- ICollection c = m_collection as ICollection;
+ var c = m_collection as ICollection;
if (c != null)
{
m_syncRoot = c.SyncRoot;
diff --git a/iothub/device/src/Common/SynchronizedPool.cs b/iothub/device/src/Common/SynchronizedPool.cs
index 5fce4fc1b4..25ca74a7bd 100644
--- a/iothub/device/src/Common/SynchronizedPool.cs
+++ b/iothub/device/src/Common/SynchronizedPool.cs
@@ -201,7 +201,7 @@ private void RecordTakeFromGlobalPool(int thisThreadID)
}
else
{
- PendingEntry[] newPending = new PendingEntry[localPending.Length * 2];
+ var newPending = new PendingEntry[localPending.Length * 2];
Array.Copy(localPending, newPending, localPending.Length);
this.pending = newPending;
}
diff --git a/iothub/device/src/Common/TaskHelpers.cs b/iothub/device/src/Common/TaskHelpers.cs
index a258da2980..6fffea7e20 100644
--- a/iothub/device/src/Common/TaskHelpers.cs
+++ b/iothub/device/src/Common/TaskHelpers.cs
@@ -122,7 +122,7 @@ internal static void MarshalTaskResults(Task source, TaskCompletionSour
break;
case TaskStatus.RanToCompletion:
- Task castedSource = source as Task;
+ var castedSource = source as Task;
proxy.TrySetResult(
castedSource == null ? default(TResult) : // source is a Task
castedSource.Result); // source is a Task
diff --git a/iothub/device/src/Common/Utils.cs b/iothub/device/src/Common/Utils.cs
index 723bdfc762..7b0784d23a 100644
--- a/iothub/device/src/Common/Utils.cs
+++ b/iothub/device/src/Common/Utils.cs
@@ -118,7 +118,7 @@ public static void ValidateDataIsEmptyOrJson(byte[] data)
throw new ArgumentNullException(nameof(dictionaries), "Provided dictionaries should not be null");
}
- Dictionary result = dictionaries.SelectMany(dict => dict)
+ var result = dictionaries.SelectMany(dict => dict)
.ToLookup(pair => pair.Key, pair => pair.Value)
.ToDictionary(group => group.Key, group => group.First());
diff --git a/iothub/device/src/DeviceClient.ConventionBasedOperations.cs b/iothub/device/src/DeviceClient.ConventionBasedOperations.cs
index 4b22036d85..0aa2922054 100644
--- a/iothub/device/src/DeviceClient.ConventionBasedOperations.cs
+++ b/iothub/device/src/DeviceClient.ConventionBasedOperations.cs
@@ -19,7 +19,7 @@ public partial class DeviceClient : IDisposable
#endif
{
///
- /// The that the client uses for convention-based operations.
+ /// The payload convention implementation that the client uses for convention-based operations.
///
public PayloadConvention PayloadConvention => InternalClient.PayloadConvention;
@@ -28,7 +28,7 @@ public partial class DeviceClient : IDisposable
///
///
/// Use the constructor to pass in the optional component name
- /// that the telemetry message is from.
+ /// that the telemetry message belongs to.
///
/// The telemetry message.
/// A cancellation token to cancel the operation.
@@ -36,21 +36,18 @@ public Task SendTelemetryAsync(TelemetryMessage telemetryMessage, CancellationTo
=> InternalClient.SendTelemetryAsync(telemetryMessage, cancellationToken);
///
- /// Set the global command callback handler.
+ /// Sets the listener for command invocation requests.
///
- /// A method implementation that will handle the incoming command.
- /// Generic parameter to be interpreted by the client code.
+ /// The callback to handle all incoming commands for the client.
/// A cancellation token to cancel the operation.
- public Task SubscribeToCommandsAsync(
- Func> callback, object userContext,
- CancellationToken cancellationToken = default)
- => InternalClient.SubscribeToCommandsAsync(callback, userContext, cancellationToken);
+ public Task SubscribeToCommandsAsync(Func> callback, CancellationToken cancellationToken = default)
+ => InternalClient.SubscribeToCommandsAsync(callback, cancellationToken);
///
/// Retrieve the client properties.
///
/// A cancellation token to cancel the operation.
- /// The device properties.
+ /// The client properties.
public Task GetClientPropertiesAsync(CancellationToken cancellationToken = default)
=> InternalClient.GetClientTwinPropertiesAsync(cancellationToken);
@@ -61,16 +58,17 @@ public Task GetClientPropertiesAsync(CancellationToken cancell
/// Reported properties to push.
/// A cancellation token to cancel the operation.
/// The response of the update operation.
- public Task UpdateClientPropertiesAsync(ClientPropertyCollection propertyCollection, CancellationToken cancellationToken = default)
+ public Task UpdateClientPropertiesAsync(
+ ClientPropertyCollection propertyCollection,
+ CancellationToken cancellationToken = default)
=> InternalClient.UpdateClientPropertiesAsync(propertyCollection, cancellationToken);
///
- /// Sets the global listener for writable property update events.
+ /// Sets the listener for writable property update events.
///
- /// The global call back to handle all writable property updates.
- /// Generic parameter to be interpreted by the client code.
+ /// The callback to handle all writable property updates for the client.
/// A cancellation token to cancel the operation.
- public Task SubscribeToWritablePropertyUpdateRequestsAsync(Func callback, object userContext, CancellationToken cancellationToken = default)
- => InternalClient.SubscribeToWritablePropertyUpdateRequestsAsync(callback, userContext, cancellationToken);
+ public Task SubscribeToWritablePropertyUpdateRequestsAsync(Func callback, CancellationToken cancellationToken = default)
+ => InternalClient.SubscribeToWritablePropertyUpdateRequestsAsync(callback, cancellationToken);
}
}
diff --git a/iothub/device/src/DeviceClient.cs b/iothub/device/src/DeviceClient.cs
index 3da5d4d3e3..01910c541c 100644
--- a/iothub/device/src/DeviceClient.cs
+++ b/iothub/device/src/DeviceClient.cs
@@ -289,7 +289,7 @@ public void SetRetryPolicy(IRetryPolicy retryPolicy)
public Task OpenAsync(CancellationToken cancellationToken) => InternalClient.OpenAsync(cancellationToken);
///
- /// Close the DeviceClient instance
+ /// Close the DeviceClient instance.
///
public Task CloseAsync() => InternalClient.CloseAsync();
@@ -298,7 +298,6 @@ public void SetRetryPolicy(IRetryPolicy retryPolicy)
///
/// A cancellation token to cancel the operation.
/// Thrown when the operation has been canceled.
- ///
public Task CloseAsync(CancellationToken cancellationToken) => InternalClient.CloseAsync(cancellationToken);
///
@@ -319,12 +318,12 @@ public void SetRetryPolicy(IRetryPolicy retryPolicy)
/// , or , and then dispose the message.
///
///
- /// You cannot Reject or Abandon messages over MQTT protocol.
+ /// You cannot reject or abandon messages over MQTT protocol.
/// For more details, see https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle.
///
/// A cancellation token to cancel the operation.
- /// Thrown when the operation has been canceled.
- /// The receive message or null if there was no message until CancellationToken Expired
+ /// Thrown when the operation has been canceled. The inner exception will be .
+ /// The received message or null if there was no message until cancellation token has expired
public Task ReceiveAsync(CancellationToken cancellationToken) => InternalClient.ReceiveAsync(cancellationToken);
///
@@ -333,10 +332,10 @@ public void SetRetryPolicy(IRetryPolicy retryPolicy)
/// , or , and then dispose the message.
///
///
- /// You cannot Reject or Abandon messages over MQTT protocol.
+ /// You cannot reject or abandon messages over MQTT protocol.
/// For more details, see https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle.
///
- /// The receive message or null if there was no message until the specified time has elapsed
+ /// The received message or null if there was no message until the specified time has elapsed.
public Task ReceiveAsync(TimeSpan timeout) => InternalClient.ReceiveAsync(timeout);
///
@@ -352,94 +351,85 @@ public void SetRetryPolicy(IRetryPolicy retryPolicy)
InternalClient.SetReceiveMessageHandlerAsync(messageHandler, userContext, cancellationToken);
///
- /// Deletes a received message from the device queue
+ /// Deletes a received message from the device queue.
///
/// The message lockToken.
- /// The lock identifier for the previously received message
public Task CompleteAsync(string lockToken) => InternalClient.CompleteAsync(lockToken);
///
- /// Deletes a received message from the device queue
+ /// Deletes a received message from the device queue.
///
/// The message lockToken.
/// A cancellation token to cancel the operation.
- /// The lock identifier for the previously received message
- /// Thrown when the operation has been canceled.
+ /// Thrown when the operation has been canceled. The inner exception will be .
public Task CompleteAsync(string lockToken, CancellationToken cancellationToken) => InternalClient.CompleteAsync(lockToken, cancellationToken);
///
- /// Deletes a received message from the device queue
+ /// Deletes a received message from the device queue.
///
/// The message.
- /// The previously received message
public Task CompleteAsync(Message message) => InternalClient.CompleteAsync(message);
///
- /// Deletes a received message from the device queue
+ /// Deletes a received message from the device queue.
///
/// The message.
/// A cancellation token to cancel the operation.
- /// Thrown when the operation has been canceled.
- /// The previously received message
+ /// Thrown when the operation has been canceled. The inner exception will be .
public Task CompleteAsync(Message message, CancellationToken cancellationToken) => InternalClient.CompleteAsync(message, cancellationToken);
///
- /// Puts a received message back onto the device queue
+ /// Puts a received message back onto the device queue.
///
///
- /// You cannot Abandon a message over MQTT protocol.
+ /// You cannot abandon a message over MQTT protocol.
/// For more details, see https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle.
///
/// The message lockToken.
- /// The previously received message
public Task AbandonAsync(string lockToken) => InternalClient.AbandonAsync(lockToken);
///
/// Puts a received message back onto the device queue
///
///
- /// You cannot Abandon a message over MQTT protocol.
+ /// You cannot abandon a message over MQTT protocol.
/// For more details, see https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle.
///
/// The message lockToken.
/// A cancellation token to cancel the operation.
- /// Thrown when the operation has been canceled.
- /// The previously received message
+ /// Thrown when the operation has been canceled. The inner exception will be .
public Task AbandonAsync(string lockToken, CancellationToken cancellationToken) => InternalClient.AbandonAsync(lockToken, cancellationToken);
///
- /// Puts a received message back onto the device queue
+ /// Puts a received message back onto the device queue.
///
///
- /// You cannot Abandon a message over MQTT protocol.
+ /// You cannot abandon a message over MQTT protocol.
/// For more details, see https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle.
///
- /// The message.
- /// The lock identifier for the previously received message
+ /// The message to abandon.
public Task AbandonAsync(Message message) => InternalClient.AbandonAsync(message);
///
- /// Puts a received message back onto the device queue
+ /// Puts a received message back onto the device queue.
///
///
- /// You cannot Abandon a message over MQTT protocol.
+ /// You cannot abandon a message over MQTT protocol.
/// For more details, see https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle.
///
- /// The message.
+ /// The message to abandon.
/// A cancellation token to cancel the operation.
- /// Thrown when the operation has been canceled.
- /// The lock identifier for the previously received message
+ /// Thrown when the operation has been canceled. The inner exception will be .
public Task AbandonAsync(Message message, CancellationToken cancellationToken) => InternalClient.AbandonAsync(message, cancellationToken);
///
/// Deletes a received message from the device queue and indicates to the server that the message could not be processed.
///
///
- /// You cannot Reject a message over MQTT protocol.
+ /// You cannot reject a message over MQTT protocol.
/// For more details, see https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle.
///
/// The message lockToken.
- /// The previously received message
public Task RejectAsync(string lockToken) => InternalClient.RejectAsync(lockToken);
///
@@ -451,32 +441,29 @@ public void SetRetryPolicy(IRetryPolicy retryPolicy)
///
/// A cancellation token to cancel the operation.
/// The message lockToken.
- /// Thrown when the operation has been canceled.
- /// The previously received message
+ /// Thrown when the operation has been canceled. The inner exception will be .
public Task RejectAsync(string lockToken, CancellationToken cancellationToken) => InternalClient.RejectAsync(lockToken, cancellationToken);
///
/// Deletes a received message from the device queue and indicates to the server that the message could not be processed.
///
///
- /// You cannot Reject a message over MQTT protocol.
+ /// You cannot reject a message over MQTT protocol.
/// For more details, see https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle.
///
/// The message.
- /// The lock identifier for the previously received message
public Task RejectAsync(Message message) => InternalClient.RejectAsync(message);
///
/// Deletes a received message from the device queue and indicates to the server that the message could not be processed.
///
///
- /// You cannot Reject a message over MQTT protocol.
+ /// You cannot reject a message over MQTT protocol.
/// For more details, see https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-messages-c2d#the-cloud-to-device-message-life-cycle.
///
- /// The message.
+ /// The message to reject.
/// A cancellation token to cancel the operation.
- /// Thrown when the operation has been canceled.
- /// The lock identifier for the previously received message
+ /// Thrown when the operation has been canceled. The inner exception will be .
public Task RejectAsync(Message message, CancellationToken cancellationToken) => InternalClient.RejectAsync(message, cancellationToken);
///
@@ -488,6 +475,7 @@ public void SetRetryPolicy(IRetryPolicy retryPolicy)
/// The timeout values are largely transport protocol specific. Check the corresponding transport settings to see if they can be configured.
/// The operation timeout for the client can be set using .
/// Thrown if the client encounters a transient retryable exception.
+ /// Thrown when the operation has been canceled. The inner exception will be .
/// Thrown if a socket error occurs.
/// Thrown if an error occurs when performing an operation on a WebSocket connection.
/// Thrown if an I/O error occurs.
@@ -499,7 +487,6 @@ public void SetRetryPolicy(IRetryPolicy retryPolicy)
/// In case of a transient issue, retrying the operation should work. In case of a non-transient issue, inspect the error details and take steps accordingly.
/// Please note that the list of exceptions is not exhaustive.
///
- /// The task to await
public Task SendEventAsync(Message message) => InternalClient.SendEventAsync(message);
///
@@ -512,6 +499,7 @@ public void SetRetryPolicy(IRetryPolicy retryPolicy)
/// If a cancellation token is not supplied to the operation call, a cancellation token with an expiration time of 4 minutes is used.
///
/// Thrown if the client encounters a transient retryable exception.
+ /// Thrown when the operation has been canceled. The inner exception will be .
/// Thrown if a socket error occurs.
/// Thrown if an error occurs when performing an operation on a WebSocket connection.
/// Thrown if an I/O error occurs.
@@ -523,23 +511,20 @@ public void SetRetryPolicy(IRetryPolicy retryPolicy)
/// In case of a transient issue, retrying the operation should work. In case of a non-transient issue, inspect the error details and take steps accordingly.
/// Please note that the list of exceptions is not exhaustive.
///
- /// The task to await
public Task SendEventAsync(Message message, CancellationToken cancellationToken) => InternalClient.SendEventAsync(message, cancellationToken);
///
/// Sends a batch of events to IoT hub. Use AMQP or HTTPs for a true batch operation. MQTT will just send the messages one after the other.
///
/// A list of one or more messages to send. The messages should be disposed after sending.
- /// The task to await
public Task SendEventBatchAsync(IEnumerable messages) => InternalClient.SendEventBatchAsync(messages);
///
/// Sends a batch of events to IoT hub. Use AMQP or HTTPs for a true batch operation. MQTT will just send the messages one after the other.
///
- /// An IEnumerable set of Message objects.
+ /// An set of message objects.
/// A cancellation token to cancel the operation.
- /// Thrown when the operation has been canceled.
- /// The task to await
+ /// Thrown when the operation has been canceled. The inner exception will be .
public Task SendEventBatchAsync(IEnumerable messages, CancellationToken cancellationToken) => InternalClient.SendEventBatchAsync(messages, cancellationToken);
///
@@ -548,7 +533,6 @@ public void SetRetryPolicy(IRetryPolicy retryPolicy)
///
/// The name of the blob to upload.
/// A stream with blob contents. Should be disposed after upload completes.
- /// AsncTask
[Obsolete("This API has been split into three APIs: GetFileUploadSasUri, uploading to blob directly using the Azure Storage SDK, and CompleteFileUploadAsync")]
public Task UploadToBlobAsync(string blobName, Stream source) => InternalClient.UploadToBlobAsync(blobName, source);
@@ -560,7 +544,6 @@ public void SetRetryPolicy(IRetryPolicy retryPolicy)
/// A stream with blob contents.. Should be disposed after upload completes.
/// A cancellation token to cancel the operation.
/// Thrown when the operation has been canceled.
- /// The task to await
[Obsolete("This API has been split into three APIs: GetFileUploadSasUri, uploading to blob directly using the Azure Storage SDK, and CompleteFileUploadAsync")]
public Task UploadToBlobAsync(string blobName, Stream source, CancellationToken cancellationToken) =>
InternalClient.UploadToBlobAsync(blobName, source, cancellationToken);
@@ -579,7 +562,6 @@ public void SetRetryPolicy(IRetryPolicy retryPolicy)
///
/// The notification details, including if the file upload succeeded.
/// The cancellation token.
- /// The task to await.
public Task CompleteFileUploadAsync(FileUploadCompletionNotification notification, CancellationToken cancellationToken = default) =>
InternalClient.CompleteFileUploadAsync(notification, cancellationToken);
@@ -603,6 +585,7 @@ public void SetRetryPolicy(IRetryPolicy retryPolicy)
/// generic parameter to be interpreted by the client code.
/// A cancellation token to cancel the operation.
/// Thrown when the operation has been canceled.
+ /// Thrown when the operation has been canceled.
///
public Task SetMethodHandlerAsync(string methodName, MethodCallback methodHandler, object userContext, CancellationToken cancellationToken) =>
InternalClient.SetMethodHandlerAsync(methodName, methodHandler, userContext, cancellationToken);
@@ -626,6 +609,7 @@ public void SetRetryPolicy(IRetryPolicy retryPolicy)
/// Generic parameter to be interpreted by the client code.
/// A cancellation token to cancel the operation.
/// Thrown when the operation has been canceled.
+ /// Thrown when the operation has been canceled.
public Task SetMethodDefaultHandlerAsync(MethodCallback methodHandler, object userContext, CancellationToken cancellationToken) =>
InternalClient.SetMethodDefaultHandlerAsync(methodHandler, userContext, cancellationToken);
@@ -665,7 +649,7 @@ public void Dispose()
// IAsyncDisposable is available in .NET Standard 2.1 and above
///
- /// Disposes the client in an async way. See for more information.
+ /// Disposes the client in an asynchronous way. See for more information.
///
///
/// Includes a call to .
@@ -707,7 +691,6 @@ protected virtual void Dispose(bool disposing)
if (disposing)
{
InternalClient?.Dispose();
- InternalClient = null;
}
}
@@ -743,10 +726,12 @@ protected virtual void Dispose(bool disposing)
///
/// This has the side-effect of subscribing to the PATCH topic on the service.
///
- /// Callback to call after the state update has been received and applied
- /// Context object that will be passed into callback
+ /// Callback to call after the state update has been received and applied.
+ /// Context object that will be passed into callback.
/// A cancellation token to cancel the operation.
+ /// TODO:azabbasi
/// Thrown when the operation has been canceled.
+ /// Thrown when the operation has been canceled.
public Task SetDesiredPropertyUpdateCallbackAsync(DesiredPropertyUpdateCallback callback, object userContext, CancellationToken cancellationToken) =>
InternalClient.SetDesiredPropertyUpdateCallbackAsync(callback, userContext, cancellationToken);
@@ -762,7 +747,7 @@ protected virtual void Dispose(bool disposing)
/// For the complete device twin object, use Microsoft.Azure.Devices.RegistryManager.GetTwinAsync(string deviceId).
///
/// A cancellation token to cancel the operation.
- /// Thrown when the operation has been canceled.
+ /// Thrown when the operation has been canceled. The inner exception will be .
/// The device twin object for the current device
public Task GetTwinAsync(CancellationToken cancellationToken) => InternalClient.GetTwinAsync(cancellationToken);
@@ -778,7 +763,7 @@ protected virtual void Dispose(bool disposing)
///
/// Reported properties to push
/// A cancellation token to cancel the operation.
- /// Thrown when the operation has been canceled.
+ /// Thrown when the operation has been canceled. The inner exception will be .
public Task UpdateReportedPropertiesAsync(TwinCollection reportedProperties, CancellationToken cancellationToken) =>
InternalClient.UpdateReportedPropertiesAsync(reportedProperties, cancellationToken);
}
diff --git a/iothub/device/src/GlobalSuppressions.cs b/iothub/device/src/GlobalSuppressions.cs
index 30c80222e1..0dc33d307d 100644
--- a/iothub/device/src/GlobalSuppressions.cs
+++ b/iothub/device/src/GlobalSuppressions.cs
@@ -7,7 +7,35 @@
using System.Diagnostics.CodeAnalysis;
-[assembly: SuppressMessage("Globalization", "CA1303:Do not pass literals as localized parameters", Justification = "Not localizing", Scope = "module")]
-[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "SDK hides non-actionable errors from user", Scope = "module")]
-[assembly: SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "Public API cannot be changed.", Scope = "type", Target = "~T:Microsoft.Azure.Devices.Client.ConnectionStatusChangeReason")]
-[assembly: SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "Public API cannot be changed.", Scope = "type", Target = "~T:Microsoft.Azure.Devices.Client.ConnectionStatus")]
+[assembly: SuppressMessage(
+ "Globalization",
+ "CA1303:Do not pass literals as localized parameters",
+ Justification = "Not localizing",
+ Scope = "module")]
+[assembly: SuppressMessage(
+ "Design",
+ "CA1031:Do not catch general exception types",
+ Justification = "SDK hides non-actionable errors from user",
+ Scope = "module")]
+[assembly: SuppressMessage(
+ "Naming",
+ "CA1707:Identifiers should not contain underscores",
+ Justification = "Public API cannot be changed.",
+ Scope = "type",
+ Target = "~T:Microsoft.Azure.Devices.Client.ConnectionStatusChangeReason")]
+[assembly: SuppressMessage(
+ "Naming",
+ "CA1707:Identifiers should not contain underscores",
+ Justification = "Public API cannot be changed.",
+ Scope = "type",
+ Target = "~T:Microsoft.Azure.Devices.Client.ConnectionStatus")]
+[assembly: SuppressMessage(
+ "Style",
+ "IDE0011:Add braces",
+ Justification = "Agreement in the team to keep this style as is for logging methods only.",
+ Scope = "module")]
+[assembly: SuppressMessage(
+ "CodeQuality",
+ "IDE0079:Remove unnecessary suppression",
+ Justification = "Each frameworks consider certain suppressions required by other frameworks unnecessary.",
+ Scope = "module")]
diff --git a/iothub/device/src/Http1TransportSettings.cs b/iothub/device/src/Http1TransportSettings.cs
index d8d638d30e..cd8db8a784 100644
--- a/iothub/device/src/Http1TransportSettings.cs
+++ b/iothub/device/src/Http1TransportSettings.cs
@@ -45,9 +45,7 @@ public TransportType GetTransportType()
///
public TimeSpan DefaultReceiveTimeout => s_defaultOperationTimeout;
- ///
- /// Proxy information.
- ///
+ ///
public IWebProxy Proxy { get; set; }
}
}
diff --git a/iothub/device/src/IDelegatingHandler.cs b/iothub/device/src/IDelegatingHandler.cs
index 41e925ed0a..e437ce1e59 100644
--- a/iothub/device/src/IDelegatingHandler.cs
+++ b/iothub/device/src/IDelegatingHandler.cs
@@ -72,11 +72,5 @@ internal interface IDelegatingHandler : IContinuationProvider GetPropertiesAsync(PayloadConvention payloadConvention, CancellationToken cancellationToken);
-
- Task SendPropertyPatchAsync(ClientPropertyCollection reportedProperties, CancellationToken cancellationToken);
}
}
diff --git a/iothub/device/src/ITransportSettings.cs b/iothub/device/src/ITransportSettings.cs
index e4fccefdc3..2d064751c9 100644
--- a/iothub/device/src/ITransportSettings.cs
+++ b/iothub/device/src/ITransportSettings.cs
@@ -2,6 +2,8 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
+using System.Net;
+using Microsoft.Azure.Devices.Shared;
namespace Microsoft.Azure.Devices.Client
{
@@ -20,5 +22,41 @@ public interface ITransportSettings
/// The time to wait for a receive operation.
///
TimeSpan DefaultReceiveTimeout { get; }
+
+ ///
+ /// The web proxy that will be used to connect to IoT hub using a web socket connection for AMQP, MQTT, or when using the HTTP protocol.
+ ///
+ ///
+ /// An instance of a class that implements .
+ ///
+ ///
+ /// This setting will be used when the client attempts to connect over web sockets. For example, if the client attempts to connect to IoT hub using or the client will first try over TCP. If that fails, the client will fall back to using web sockets and will use the proxy setting. The setting will also be used when , , or is specified.
+ ///
+ ///
+ /// To set a proxy you must instantiate an instance of the class--or any class that derives from . The snippet below shows a method that returns a device using a proxy that connects to localhost on port 8888.
+ ///
+ /// static DeviceClient GetClientWithProxy()
+ /// {
+ /// try
+ /// {
+ /// var proxyHost = "localhost";
+ /// var proxyPort = 8888;
+ /// // Specify the WebProxy to be used for the web socket connection
+ /// var transportSettings = new AmqpTransportSettings(Microsoft.Azure.Devices.Client.TransportType.Amqp_WebSocket_Only)
+ /// {
+ /// Proxy = new WebProxy(proxyHost, proxyPort)
+ /// };
+ /// var deviceClient = DeviceClient.CreateFromConnectionString("a connection string", new ITransportSettings[] { transportSettings });
+ /// return deviceClient;
+ /// }
+ /// catch (Exception)
+ /// {
+ /// Console.WriteLine("Error creating client.");
+ /// throw;
+ /// }
+ /// }
+ ///
+ ///
+ IWebProxy Proxy { get; set; }
}
}
diff --git a/iothub/device/src/InternalClient.ConventionBasedOperations.cs b/iothub/device/src/InternalClient.ConventionBasedOperations.cs
index a8e19cb9cc..c6c721bde1 100644
--- a/iothub/device/src/InternalClient.ConventionBasedOperations.cs
+++ b/iothub/device/src/InternalClient.ConventionBasedOperations.cs
@@ -37,7 +37,7 @@ internal Task SendTelemetryAsync(TelemetryMessage telemetryMessage, Cancellation
return SendEventAsync(telemetryMessage, cancellationToken);
}
- internal Task SubscribeToCommandsAsync(Func> callback, object userContext, CancellationToken cancellationToken)
+ internal Task SubscribeToCommandsAsync(Func> callback, CancellationToken cancellationToken)
{
// Subscribe to methods default handler internally and use the callback received internally to invoke the user supplied command callback.
var methodDefaultCallback = new MethodCallback(async (methodRequest, userContext) =>
@@ -56,14 +56,19 @@ internal Task SubscribeToCommandsAsync(Func GetClientTwinPropertiesAsync(CancellationToken cancellationToken)
@@ -105,19 +110,22 @@ internal async Task UpdateClientPropertiesAsync(
}
}
- internal Task SubscribeToWritablePropertyUpdateRequestsAsync(Func callback, object userContext, CancellationToken cancellationToken)
+ internal Task SubscribeToWritablePropertyUpdateRequestsAsync(Func callback, CancellationToken cancellationToken)
{
// Subscribe to DesiredPropertyUpdateCallback internally and use the callback received internally to invoke the user supplied Property callback.
- var desiredPropertyUpdateCallback = new DesiredPropertyUpdateCallback((twinCollection, userContext) =>
+ var desiredPropertyUpdateCallback = new DesiredPropertyUpdateCallback(async (twinCollection, userContext) =>
{
// convert a TwinCollection to PropertyCollection
var propertyCollection = ClientPropertyCollection.WritablePropertyUpdateRequestsFromTwinCollection(twinCollection, PayloadConvention);
- callback.Invoke(propertyCollection, userContext);
-
- return TaskHelpers.CompletedTask;
+ await callback.Invoke(propertyCollection).ConfigureAwait(false);
});
- return SetDesiredPropertyUpdateCallbackAsync(desiredPropertyUpdateCallback, userContext, cancellationToken);
+ // We pass in a null context to the internal API because the updated SubscribeToWritablePropertyUpdateRequestsAsync API
+ // does not require you to pass in a user context.
+ // Since SubscribeToWritablePropertyUpdateRequestsAsync callback is invoked for all property update events,
+ // the user context passed in would be the same for all scenarios.
+ // This user context can be set at a class level instead.
+ return SetDesiredPropertyUpdateCallbackAsync(desiredPropertyUpdateCallback, null, cancellationToken);
}
}
}
diff --git a/iothub/device/src/InternalClient.cs b/iothub/device/src/InternalClient.cs
index 5d6a9953fc..f5c0b2a08c 100644
--- a/iothub/device/src/InternalClient.cs
+++ b/iothub/device/src/InternalClient.cs
@@ -1894,7 +1894,6 @@ internal void ValidateModuleTransportHandler(string apiName)
public void Dispose()
{
InnerHandler?.Dispose();
- InnerHandler = null;
_methodsSemaphore?.Dispose();
_moduleReceiveMessageSemaphore?.Dispose();
_fileUploadHttpTransportHandler?.Dispose();
diff --git a/iothub/device/src/IotHubClientDiagnostic.cs b/iothub/device/src/IotHubClientDiagnostic.cs
index 0917efc570..9e27bea66d 100644
--- a/iothub/device/src/IotHubClientDiagnostic.cs
+++ b/iothub/device/src/IotHubClientDiagnostic.cs
@@ -34,7 +34,7 @@ internal static bool HasDiagnosticProperties(MessageBase message)
private static string GenerateEightRandomCharacters()
{
- var stringChars = new char[8];
+ char[] stringChars = new char[8];
var random = new Random();
for (int i = 0; i < stringChars.Length; i++)
{
diff --git a/iothub/device/src/IotHubConnectionString.Core.cs b/iothub/device/src/IotHubConnectionString.Core.cs
index 70edd63dd0..543ea47c5f 100644
--- a/iothub/device/src/IotHubConnectionString.Core.cs
+++ b/iothub/device/src/IotHubConnectionString.Core.cs
@@ -19,11 +19,14 @@ Task IAuthorizationProvider.GetPasswordAsync()
if (Logging.IsEnabled)
Logging.Enter(this, $"{nameof(IotHubConnectionString)}.{nameof(IAuthorizationProvider.GetPasswordAsync)}");
- Debug.Assert(TokenRefresher != null);
+ Debug.Assert(
+ !string.IsNullOrWhiteSpace(SharedAccessSignature)
+ || TokenRefresher != null,
+ "The token refresher and the shared access signature can't both be null");
return !string.IsNullOrWhiteSpace(SharedAccessSignature)
? Task.FromResult(SharedAccessSignature)
- : TokenRefresher.GetTokenAsync(Audience);
+ : TokenRefresher?.GetTokenAsync(Audience);
}
finally
{
diff --git a/iothub/device/src/IotHubConnectionString.cs b/iothub/device/src/IotHubConnectionString.cs
index 3d8a7349fc..b41bad43e6 100644
--- a/iothub/device/src/IotHubConnectionString.cs
+++ b/iothub/device/src/IotHubConnectionString.cs
@@ -92,6 +92,33 @@ public IotHubConnectionString(IotHubConnectionStringBuilder builder)
}
}
+ // This constructor is only used for unit testing.
+ internal IotHubConnectionString(
+ string ioTHubName = null,
+ string deviceId = null,
+ string moduleId = null,
+ string hostName = null,
+ Uri httpsEndpoint = null,
+ Uri amqpEndpoint = null,
+ string audience = null,
+ string sharedAccessKeyName = null,
+ string sharedAccessKey = null,
+ string sharedAccessSignature = null,
+ bool isUsingGateway = false)
+ {
+ IotHubName = ioTHubName;
+ DeviceId = deviceId;
+ ModuleId = moduleId;
+ HostName = hostName;
+ HttpsEndpoint = httpsEndpoint;
+ AmqpEndpoint = amqpEndpoint;
+ Audience = audience;
+ SharedAccessKeyName = sharedAccessKeyName;
+ SharedAccessKey = sharedAccessKey;
+ SharedAccessSignature = sharedAccessSignature;
+ IsUsingGateway = isUsingGateway;
+ }
+
public string IotHubName { get; private set; }
public string DeviceId { get; private set; }
diff --git a/iothub/device/src/IotHubConnectionStringBuilder.cs b/iothub/device/src/IotHubConnectionStringBuilder.cs
index 8c133f9e04..181cd642f6 100644
--- a/iothub/device/src/IotHubConnectionStringBuilder.cs
+++ b/iothub/device/src/IotHubConnectionStringBuilder.cs
@@ -53,7 +53,7 @@ public sealed class IotHubConnectionStringBuilder
///
/// Initializes a new instance of the class.
///
- private IotHubConnectionStringBuilder()
+ internal IotHubConnectionStringBuilder()
{
}
diff --git a/iothub/device/src/Microsoft.Azure.Devices.Client.csproj b/iothub/device/src/Microsoft.Azure.Devices.Client.csproj
index 9dc7f14c8c..a8a79410a5 100644
--- a/iothub/device/src/Microsoft.Azure.Devices.Client.csproj
+++ b/iothub/device/src/Microsoft.Azure.Devices.Client.csproj
@@ -79,6 +79,8 @@
+
+
diff --git a/iothub/device/src/ModernDotNet/HsmAuthentication/Transport/HttpUdsMessageHandler.cs b/iothub/device/src/ModernDotNet/HsmAuthentication/Transport/HttpUdsMessageHandler.cs
index 66a0ea0372..62889cf2d3 100644
--- a/iothub/device/src/ModernDotNet/HsmAuthentication/Transport/HttpUdsMessageHandler.cs
+++ b/iothub/device/src/ModernDotNet/HsmAuthentication/Transport/HttpUdsMessageHandler.cs
@@ -40,7 +40,7 @@ protected override async Task SendAsync(HttpRequestMessage
private async Task GetConnectedSocketAsync()
{
- Socket socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
+ var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
// The Edge Agent uses unix sockets for communication with the modules deployed in docker for HSM.
// For netstandard 2.0 there was no implementation for a Unix Domain Socket (UDS) so we used a version
diff --git a/iothub/device/src/ModuleClient.ConventionBasedOperations.cs b/iothub/device/src/ModuleClient.ConventionBasedOperations.cs
index 59cbf76061..ca1a6a669d 100644
--- a/iothub/device/src/ModuleClient.ConventionBasedOperations.cs
+++ b/iothub/device/src/ModuleClient.ConventionBasedOperations.cs
@@ -36,15 +36,12 @@ public Task SendTelemetryAsync(TelemetryMessage telemetryMessage, CancellationTo
=> InternalClient.SendTelemetryAsync(telemetryMessage, cancellationToken);
///
- /// Set the global command callback handler.
+ /// Sets the listener for command invocation requests.
///
- /// A method implementation that will handle the incoming command.
- /// Generic parameter to be interpreted by the client code.
+ /// The callback to handle all incoming commands for the client.
/// A cancellation token to cancel the operation.
- public Task SubscribeToCommandsAsync(
- Func> callback, object userContext,
- CancellationToken cancellationToken = default)
- => InternalClient.SubscribeToCommandsAsync(callback, userContext, cancellationToken);
+ public Task SubscribeToCommandsAsync(Func> callback, CancellationToken cancellationToken = default)
+ => InternalClient.SubscribeToCommandsAsync(callback, cancellationToken);
///
/// Retrieve the client properties.
@@ -65,12 +62,11 @@ public Task UpdateClientPropertiesAsync(ClientPr
=> InternalClient.UpdateClientPropertiesAsync(propertyCollection, cancellationToken);
///
- /// Sets the global listener for writable property update events.
+ /// Sets the listener for writable property update events.
///
- /// The global call back to handle all writable property updates.
- /// Generic parameter to be interpreted by the client code.
+ /// The callback to handle all writable property updates for the client.
/// A cancellation token to cancel the operation.
- public Task SubscribeToWritablePropertyUpdateRequestsAsync(Func callback, object userContext, CancellationToken cancellationToken = default)
- => InternalClient.SubscribeToWritablePropertyUpdateRequestsAsync(callback, userContext, cancellationToken);
+ public Task SubscribeToWritablePropertyUpdateRequestsAsync(Func callback, CancellationToken cancellationToken = default)
+ => InternalClient.SubscribeToWritablePropertyUpdateRequestsAsync(callback, cancellationToken);
}
}
diff --git a/iothub/device/src/PayloadCollection.cs b/iothub/device/src/PayloadCollection.cs
index d4dcbc2295..c86c2e1957 100644
--- a/iothub/device/src/PayloadCollection.cs
+++ b/iothub/device/src/PayloadCollection.cs
@@ -20,7 +20,7 @@ public abstract class PayloadCollection : IEnumerable
/// The underlying collection for the payload.
///
- public IDictionary Collection { get; private set; } = new Dictionary();
+ internal IDictionary Collection { get; } = new Dictionary();
///
/// The convention to use with this payload.
@@ -28,18 +28,16 @@ public abstract class PayloadCollection : IEnumerable
- /// Get the value at the specified key.
+ /// Gets the value with the specified key.
///
///
/// This accessor is best used to access and cast to simple types.
/// It is recommended to use to deserialize to a complex type.
///
- ///
/// For setting component-level property values see
- /// and instead.
- /// These convenience methods ensure that component-level properties include the component identifier markers { "__t": "c" }.
+ /// and instead
+ /// as these convenience methods ensure that component-level properties include the component identifier markers: { "__t": "c" }.
/// For more information see .
- ///
///
///
/// Key of value.
@@ -73,8 +71,8 @@ public virtual void Add(string key, object value)
/// For property operations see
/// and instead.
///
- /// The name of the telemetry.
- /// The value of the telemetry.
+ /// The name of the key to be added to the collection.
+ /// The value to be added to the collection.
/// is null.
public virtual void AddOrUpdate(string key, object value)
{
@@ -95,10 +93,10 @@ public virtual byte[] GetPayloadObjectBytes()
}
///
- /// Determines whether the specified property is present.
+ /// Determines whether the specified key is present.
///
/// The key in the collection to locate.
- /// true if the specified property is present; otherwise, false.
+ /// true if the specified property is present, otherwise false.
public bool Contains(string key)
{
return Collection.ContainsKey(key);
diff --git a/iothub/device/src/TransientFaultHandling/AsyncExecution[T].cs b/iothub/device/src/TransientFaultHandling/AsyncExecution[T].cs
index 7645591a68..278ca97689 100644
--- a/iothub/device/src/TransientFaultHandling/AsyncExecution[T].cs
+++ b/iothub/device/src/TransientFaultHandling/AsyncExecution[T].cs
@@ -79,7 +79,7 @@ private Task ExecuteAsyncImpl(Task ignore)
{
return this.previousTask;
}
- TaskCompletionSource taskCompletionSource = new TaskCompletionSource();
+ var taskCompletionSource = new TaskCompletionSource();
taskCompletionSource.TrySetCanceled();
return taskCompletionSource.Task;
}
@@ -96,7 +96,7 @@ private Task ExecuteAsyncImpl(Task ignore)
{
throw;
}
- TaskCompletionSource taskCompletionSource2 = new TaskCompletionSource();
+ var taskCompletionSource2 = new TaskCompletionSource();
taskCompletionSource2.TrySetException(ex);
task = taskCompletionSource2.Task;
}
diff --git a/iothub/device/src/Transport/Amqp/AmqpAuthenticationRefresher.cs b/iothub/device/src/Transport/Amqp/AmqpAuthenticationRefresher.cs
index 4d9a8d6cad..0b9c09b1b7 100644
--- a/iothub/device/src/Transport/Amqp/AmqpAuthenticationRefresher.cs
+++ b/iothub/device/src/Transport/Amqp/AmqpAuthenticationRefresher.cs
@@ -21,7 +21,7 @@ internal class AmqpAuthenticationRefresher : IAmqpAuthenticationRefresher, IDisp
private Task _refreshLoop;
private bool _disposed;
- internal AmqpAuthenticationRefresher(DeviceIdentity deviceIdentity, AmqpIotCbsLink amqpCbsLink)
+ internal AmqpAuthenticationRefresher(IDeviceIdentity deviceIdentity, AmqpIotCbsLink amqpCbsLink)
{
_amqpIotCbsLink = amqpCbsLink;
_connectionString = deviceIdentity.IotHubConnectionString;
diff --git a/iothub/device/src/Transport/Amqp/AmqpConnectionHolder.cs b/iothub/device/src/Transport/Amqp/AmqpConnectionHolder.cs
index 691410b851..5d9681be70 100644
--- a/iothub/device/src/Transport/Amqp/AmqpConnectionHolder.cs
+++ b/iothub/device/src/Transport/Amqp/AmqpConnectionHolder.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.Amqp;
@@ -15,7 +16,7 @@ namespace Microsoft.Azure.Devices.Client.Transport.Amqp
{
internal class AmqpConnectionHolder : IAmqpConnectionHolder, IAmqpUnitManager
{
- private readonly DeviceIdentity _deviceIdentity;
+ private readonly IDeviceIdentity _deviceIdentity;
private readonly AmqpIotConnector _amqpIotConnector;
private readonly SemaphoreSlim _lock = new SemaphoreSlim(1, 1);
private readonly HashSet _amqpUnits = new HashSet();
@@ -24,7 +25,7 @@ internal class AmqpConnectionHolder : IAmqpConnectionHolder, IAmqpUnitManager
private IAmqpAuthenticationRefresher _amqpAuthenticationRefresher;
private volatile bool _disposed;
- public AmqpConnectionHolder(DeviceIdentity deviceIdentity)
+ public AmqpConnectionHolder(IDeviceIdentity deviceIdentity)
{
_deviceIdentity = deviceIdentity;
_amqpIotConnector = new AmqpIotConnector(deviceIdentity.AmqpTransportSettings, deviceIdentity.IotHubConnectionString.HostName);
@@ -35,7 +36,7 @@ public AmqpConnectionHolder(DeviceIdentity deviceIdentity)
}
public AmqpUnit CreateAmqpUnit(
- DeviceIdentity deviceIdentity,
+ IDeviceIdentity deviceIdentity,
Func onMethodCallback,
Action twinMessageListener,
Func onModuleMessageReceivedCallback,
@@ -141,7 +142,7 @@ private void Dispose(bool disposing)
_disposed = true;
}
- public async Task CreateRefresherAsync(DeviceIdentity deviceIdentity, CancellationToken cancellationToken)
+ public async Task CreateRefresherAsync(IDeviceIdentity deviceIdentity, CancellationToken cancellationToken)
{
if (Logging.IsEnabled)
{
@@ -160,7 +161,7 @@ public async Task CreateRefresherAsync(DeviceIdent
return amqpAuthenticator;
}
- public async Task OpenSessionAsync(DeviceIdentity deviceIdentity, CancellationToken cancellationToken)
+ public async Task OpenSessionAsync(IDeviceIdentity deviceIdentity, CancellationToken cancellationToken)
{
if (Logging.IsEnabled)
{
@@ -275,9 +276,14 @@ public void RemoveAmqpUnit(AmqpUnit amqpUnit)
}
}
- internal DeviceIdentity GetDeviceIdentityOfAuthenticationProvider()
+ internal IDeviceIdentity GetDeviceIdentityOfAuthenticationProvider()
{
return _deviceIdentity;
}
+
+ internal bool IsEmpty()
+ {
+ return !_amqpUnits.Any();
+ }
}
}
diff --git a/iothub/device/src/Transport/Amqp/AmqpConnectionPool.cs b/iothub/device/src/Transport/Amqp/AmqpConnectionPool.cs
index d682ffc51a..25cffd1482 100644
--- a/iothub/device/src/Transport/Amqp/AmqpConnectionPool.cs
+++ b/iothub/device/src/Transport/Amqp/AmqpConnectionPool.cs
@@ -17,8 +17,13 @@ internal class AmqpConnectionPool : IAmqpUnitManager
private readonly IDictionary _amqpSasGroupedPool = new Dictionary();
private readonly object _lock = new object();
+ protected virtual IDictionary GetAmqpSasGroupedPoolDictionary()
+ {
+ return _amqpSasGroupedPool;
+ }
+
public AmqpUnit CreateAmqpUnit(
- DeviceIdentity deviceIdentity,
+ IDeviceIdentity deviceIdentity,
Func onMethodCallback,
Action twinMessageListener,
Func onModuleMessageReceivedCallback,
@@ -37,21 +42,6 @@ internal class AmqpConnectionPool : IAmqpUnitManager
{
AmqpConnectionHolder[] amqpConnectionHolders = ResolveConnectionGroup(deviceIdentity);
amqpConnectionHolder = ResolveConnectionByHashing(amqpConnectionHolders, deviceIdentity);
-
- // For group sas token authenticated devices over a multiplexed connection, the TokenRefresher
- // of the first client connecting will be used for generating the group sas tokens
- // and will be associated with the connection itself.
- // For this reason, if the device identity of the client is not the one associated with the
- // connection, the associated TokenRefresher can be safely disposed.
- // Note - This does not cause any identity related issues since the group sas tokens are generated
- // against the hub host as the intended audience (without the "device Id").
- if (deviceIdentity.AuthenticationModel == AuthenticationModel.SasGrouped
- && !ReferenceEquals(amqpConnectionHolder.GetDeviceIdentityOfAuthenticationProvider(), deviceIdentity)
- && deviceIdentity.IotHubConnectionString?.TokenRefresher != null
- && deviceIdentity.IotHubConnectionString.TokenRefresher.DisposalWithClient)
- {
- deviceIdentity.IotHubConnectionString.TokenRefresher.Dispose();
- }
}
if (Logging.IsEnabled)
@@ -92,7 +82,7 @@ public void RemoveAmqpUnit(AmqpUnit amqpUnit)
Logging.Enter(this, amqpUnit, nameof(RemoveAmqpUnit));
}
- DeviceIdentity deviceIdentity = amqpUnit.GetDeviceIdentity();
+ IDeviceIdentity deviceIdentity = amqpUnit.GetDeviceIdentity();
if (deviceIdentity.IsPooling())
{
AmqpConnectionHolder amqpConnectionHolder;
@@ -100,8 +90,17 @@ public void RemoveAmqpUnit(AmqpUnit amqpUnit)
{
AmqpConnectionHolder[] amqpConnectionHolders = ResolveConnectionGroup(deviceIdentity);
amqpConnectionHolder = ResolveConnectionByHashing(amqpConnectionHolders, deviceIdentity);
+
+ amqpConnectionHolder.RemoveAmqpUnit(amqpUnit);
+
+ // If the connection holder does not have any more units, the entry needs to be nullified.
+ if (amqpConnectionHolder.IsEmpty())
+ {
+ int index = GetDeviceIdentityIndex(deviceIdentity, amqpConnectionHolders.Length);
+ amqpConnectionHolders[index] = null;
+ amqpConnectionHolder?.Dispose();
+ }
}
- amqpConnectionHolder.RemoveAmqpUnit(amqpUnit);
}
if (Logging.IsEnabled)
@@ -110,7 +109,7 @@ public void RemoveAmqpUnit(AmqpUnit amqpUnit)
}
}
- private AmqpConnectionHolder[] ResolveConnectionGroup(DeviceIdentity deviceIdentity)
+ private AmqpConnectionHolder[] ResolveConnectionGroup(IDeviceIdentity deviceIdentity)
{
if (deviceIdentity.AuthenticationModel == AuthenticationModel.SasIndividual)
{
@@ -124,25 +123,26 @@ private AmqpConnectionHolder[] ResolveConnectionGroup(DeviceIdentity deviceIdent
else
{
string scope = deviceIdentity.IotHubConnectionString.SharedAccessKeyName;
- _amqpSasGroupedPool.TryGetValue(scope, out AmqpConnectionHolder[] amqpConnectionHolders);
+ GetAmqpSasGroupedPoolDictionary().TryGetValue(scope, out AmqpConnectionHolder[] amqpConnectionHolders);
if (amqpConnectionHolders == null)
{
amqpConnectionHolders = new AmqpConnectionHolder[deviceIdentity.AmqpTransportSettings.AmqpConnectionPoolSettings.MaxPoolSize];
- _amqpSasGroupedPool.Add(scope, amqpConnectionHolders);
+ GetAmqpSasGroupedPoolDictionary().Add(scope, amqpConnectionHolders);
}
return amqpConnectionHolders;
}
}
- private AmqpConnectionHolder ResolveConnectionByHashing(AmqpConnectionHolder[] pool, DeviceIdentity deviceIdentity)
+ private AmqpConnectionHolder ResolveConnectionByHashing(AmqpConnectionHolder[] pool, IDeviceIdentity deviceIdentity)
{
if (Logging.IsEnabled)
{
Logging.Enter(this, deviceIdentity, nameof(ResolveConnectionByHashing));
}
- int index = Math.Abs(deviceIdentity.GetHashCode()) % pool.Length;
+ int index = GetDeviceIdentityIndex(deviceIdentity, pool.Length);
+
if (pool[index] == null)
{
pool[index] = new AmqpConnectionHolder(deviceIdentity);
@@ -155,5 +155,12 @@ private AmqpConnectionHolder ResolveConnectionByHashing(AmqpConnectionHolder[] p
return pool[index];
}
+
+ private static int GetDeviceIdentityIndex(IDeviceIdentity deviceIdentity, int poolLength)
+ {
+ return deviceIdentity == null
+ ? throw new ArgumentNullException(nameof(deviceIdentity))
+ : Math.Abs(deviceIdentity.GetHashCode()) % poolLength;
+ }
}
}
diff --git a/iothub/device/src/Transport/Amqp/AmqpTransportHandler.cs b/iothub/device/src/Transport/Amqp/AmqpTransportHandler.cs
index 01e33d5671..67430620d5 100644
--- a/iothub/device/src/Transport/Amqp/AmqpTransportHandler.cs
+++ b/iothub/device/src/Transport/Amqp/AmqpTransportHandler.cs
@@ -53,7 +53,7 @@ static AmqpTransportHandler()
{
_operationTimeout = transportSettings.OperationTimeout;
_onDesiredStatePatchListener = onDesiredStatePatchReceivedCallback;
- var deviceIdentity = new DeviceIdentity(connectionString, transportSettings, context.Get(), context.Get());
+ IDeviceIdentity deviceIdentity = new DeviceIdentity(connectionString, transportSettings, context.Get(), context.Get());
_amqpUnit = AmqpUnitManager.GetInstance().CreateAmqpUnit(
deviceIdentity,
onMethodCallback,
@@ -509,12 +509,11 @@ public override async Task EnableEventReceiveAsync(bool isAnEdgeModule, Cancella
{
Logging.Exit(this, cancellationToken, nameof(EnableEventReceiveAsync));
}
- }
+ }
else
{
await EnableReceiveMessageAsync(cancellationToken).ConfigureAwait(false);
}
-
}
#endregion Events
@@ -592,26 +591,6 @@ private async Task DisposeMessageAsync(string lockToken, AmqpIotDisposeActions o
#endregion Accept-Dispose
- #region Convention-based operations
-
- public override Task GetPropertiesAsync(PayloadConvention payloadConvention, CancellationToken cancellationToken)
- {
- throw new NotImplementedException("This operation is currently not supported over AMQP, please use MQTT protocol instead. " +
- "Note that you can still retrieve a client's properties using DeviceClient.GetTwinAsync(CancellationToken cancellationToken) or " +
- "ModuleClient.GetTwinAsync(CancellationToken cancellationToken) operations, but the properties will not be formatted " +
- "as per DTDL terminology.");
- }
-
- public override Task SendPropertyPatchAsync(ClientPropertyCollection reportedProperties, CancellationToken cancellationToken)
- {
- throw new NotImplementedException("This operation is currently not supported over AMQP, please use MQTT protocol instead. " +
- "Note that you can still retrieve a client's properties using DeviceClient.GetTwinAsync(CancellationToken cancellationToken) or " +
- "ModuleClient.GetTwinAsync(CancellationToken cancellationToken) operations, but the properties will not be formatted " +
- "as per DTDL terminology.");
- }
-
- #endregion Convention-based operations
-
#region Helpers
private void TwinMessageListener(AmqpMessage responseFromService, string correlationId, IotHubException ex = default)
diff --git a/iothub/device/src/Transport/Amqp/AmqpUnit.cs b/iothub/device/src/Transport/Amqp/AmqpUnit.cs
index 8fc5ea5f09..f8b0d32708 100644
--- a/iothub/device/src/Transport/Amqp/AmqpUnit.cs
+++ b/iothub/device/src/Transport/Amqp/AmqpUnit.cs
@@ -18,7 +18,7 @@ namespace Microsoft.Azure.Devices.Client.Transport.AmqpIot
internal class AmqpUnit : IDisposable
{
// If the first argument is set to true, we are disconnecting gracefully via CloseAsync.
- private readonly DeviceIdentity _deviceIdentity;
+ private readonly IDeviceIdentity _deviceIdentity;
private readonly Func _onMethodCallback;
private readonly Action _twinMessageListener;
@@ -53,7 +53,7 @@ internal class AmqpUnit : IDisposable
private IAmqpAuthenticationRefresher _amqpAuthenticationRefresher;
public AmqpUnit(
- DeviceIdentity deviceIdentity,
+ IDeviceIdentity deviceIdentity,
IAmqpConnectionHolder amqpConnectionHolder,
Func onMethodCallback,
Action twinMessageListener,
@@ -72,7 +72,7 @@ internal class AmqpUnit : IDisposable
Logging.Associate(this, _deviceIdentity, nameof(_deviceIdentity));
}
- internal DeviceIdentity GetDeviceIdentity()
+ internal IDeviceIdentity GetDeviceIdentity()
{
return _deviceIdentity;
}
@@ -801,11 +801,7 @@ private void OnDesiredPropertyReceived(AmqpMessage responseFromService, string c
}
}
- public async Task SendTwinMessageAsync(
- AmqpTwinMessageType amqpTwinMessageType,
- string correlationId,
- Stream reportedProperties,
- CancellationToken cancellationToken)
+ public async Task SendTwinMessageAsync(AmqpTwinMessageType amqpTwinMessageType, string correlationId, Stream reportedProperties, CancellationToken cancellationToken)
{
Logging.Enter(this, nameof(SendTwinMessageAsync));
diff --git a/iothub/device/src/Transport/Amqp/AmqpUnitManager.cs b/iothub/device/src/Transport/Amqp/AmqpUnitManager.cs
index a94dfe6829..64bea200c5 100644
--- a/iothub/device/src/Transport/Amqp/AmqpUnitManager.cs
+++ b/iothub/device/src/Transport/Amqp/AmqpUnitManager.cs
@@ -29,7 +29,7 @@ internal static AmqpUnitManager GetInstance()
}
public AmqpUnit CreateAmqpUnit(
- DeviceIdentity deviceIdentity,
+ IDeviceIdentity deviceIdentity,
Func onMethodCallback,
Action twinMessageListener,
Func onModuleMessageReceivedCallback,
@@ -48,9 +48,9 @@ internal static AmqpUnitManager GetInstance()
public void RemoveAmqpUnit(AmqpUnit amqpUnit)
{
- amqpUnit.Dispose();
IAmqpUnitManager amqpConnectionPool = ResolveConnectionPool(amqpUnit.GetDeviceIdentity().IotHubConnectionString.HostName);
amqpConnectionPool.RemoveAmqpUnit(amqpUnit);
+ amqpUnit.Dispose();
}
private IAmqpUnitManager ResolveConnectionPool(string host)
diff --git a/iothub/device/src/Transport/DeviceIdentity.cs b/iothub/device/src/Transport/Amqp/DeviceIdentity.cs
similarity index 77%
rename from iothub/device/src/Transport/DeviceIdentity.cs
rename to iothub/device/src/Transport/Amqp/DeviceIdentity.cs
index dc1505eac6..8689ac3111 100644
--- a/iothub/device/src/Transport/DeviceIdentity.cs
+++ b/iothub/device/src/Transport/Amqp/DeviceIdentity.cs
@@ -4,7 +4,7 @@
using System.Net;
using Microsoft.Azure.Devices.Client.Extensions;
-namespace Microsoft.Azure.Devices.Client.Transport
+namespace Microsoft.Azure.Devices.Client.Transport.Amqp
{
///
/// Device configurations
@@ -12,16 +12,20 @@ namespace Microsoft.Azure.Devices.Client.Transport
/// - connection string
/// - transport settings
///
- internal class DeviceIdentity
+ internal class DeviceIdentity : IDeviceIdentity
{
- internal IotHubConnectionString IotHubConnectionString { get; }
- internal AmqpTransportSettings AmqpTransportSettings { get; }
- internal ProductInfo ProductInfo { get; }
- internal AuthenticationModel AuthenticationModel { get; }
- internal string Audience { get; }
- internal ClientOptions Options { get; }
+ public IotHubConnectionString IotHubConnectionString { get; }
+ public AmqpTransportSettings AmqpTransportSettings { get; }
+ public ProductInfo ProductInfo { get; }
+ public AuthenticationModel AuthenticationModel { get; }
+ public string Audience { get; }
+ public ClientOptions Options { get; }
- internal DeviceIdentity(IotHubConnectionString iotHubConnectionString, AmqpTransportSettings amqpTransportSettings, ProductInfo productInfo, ClientOptions options)
+ internal DeviceIdentity(
+ IotHubConnectionString iotHubConnectionString,
+ AmqpTransportSettings amqpTransportSettings,
+ ProductInfo productInfo,
+ ClientOptions options)
{
IotHubConnectionString = iotHubConnectionString;
AmqpTransportSettings = amqpTransportSettings;
@@ -31,14 +35,9 @@ internal DeviceIdentity(IotHubConnectionString iotHubConnectionString, AmqpTrans
if (amqpTransportSettings.ClientCertificate == null)
{
Audience = CreateAudience(IotHubConnectionString);
- if (iotHubConnectionString.SharedAccessKeyName == null)
- {
- AuthenticationModel = AuthenticationModel.SasIndividual;
- }
- else
- {
- AuthenticationModel = AuthenticationModel.SasGrouped;
- }
+ AuthenticationModel = iotHubConnectionString.SharedAccessKeyName == null
+ ? AuthenticationModel.SasIndividual
+ : AuthenticationModel.SasGrouped;
}
else
{
@@ -61,7 +60,7 @@ private static string CreateAudience(IotHubConnectionString connectionString)
}
}
- internal bool IsPooling()
+ public bool IsPooling()
{
return (AuthenticationModel != AuthenticationModel.X509) && (AmqpTransportSettings?.AmqpConnectionPoolSettings?.Pooling ?? false);
}
diff --git a/iothub/device/src/Transport/Amqp/IAmqpConnectionHolder.cs b/iothub/device/src/Transport/Amqp/IAmqpConnectionHolder.cs
index 1fd4fa5fa4..5def753284 100644
--- a/iothub/device/src/Transport/Amqp/IAmqpConnectionHolder.cs
+++ b/iothub/device/src/Transport/Amqp/IAmqpConnectionHolder.cs
@@ -10,11 +10,11 @@ namespace Microsoft.Azure.Devices.Client.Transport.Amqp
{
internal interface IAmqpConnectionHolder : IDisposable
{
- Task OpenSessionAsync(DeviceIdentity deviceIdentity, CancellationToken cancellationToken);
+ Task OpenSessionAsync(IDeviceIdentity deviceIdentity, CancellationToken cancellationToken);
Task EnsureConnectionAsync(CancellationToken cancellationToken);
- Task CreateRefresherAsync(DeviceIdentity deviceIdentity, CancellationToken cancellationToken);
+ Task CreateRefresherAsync(IDeviceIdentity deviceIdentity, CancellationToken cancellationToken);
void Shutdown();
}
diff --git a/iothub/device/src/Transport/Amqp/IAmqpUnitManager.cs b/iothub/device/src/Transport/Amqp/IAmqpUnitManager.cs
index 09ffe1abc3..9f8705e290 100644
--- a/iothub/device/src/Transport/Amqp/IAmqpUnitManager.cs
+++ b/iothub/device/src/Transport/Amqp/IAmqpUnitManager.cs
@@ -13,7 +13,7 @@ namespace Microsoft.Azure.Devices.Client.Transport.Amqp
internal interface IAmqpUnitManager
{
AmqpUnit CreateAmqpUnit(
- DeviceIdentity deviceIdentity,
+ IDeviceIdentity deviceIdentity,
Func onMethodCallback,
Action twinMessageListener,
Func onModuleMessageReceivedCallback,
diff --git a/iothub/device/src/Transport/Amqp/IDeviceIdentity.cs b/iothub/device/src/Transport/Amqp/IDeviceIdentity.cs
new file mode 100644
index 0000000000..e459aed554
--- /dev/null
+++ b/iothub/device/src/Transport/Amqp/IDeviceIdentity.cs
@@ -0,0 +1,46 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Microsoft.Azure.Devices.Client.Transport.Amqp
+{
+ ///
+ /// Interface for device configurations and common attributes.
+ ///
+ internal interface IDeviceIdentity
+ {
+ ///
+ /// Authentication model for the device.
+ ///
+ AuthenticationModel AuthenticationModel { get; }
+
+ ///
+ /// AMQP transport layer settings of the device.
+ ///
+ AmqpTransportSettings AmqpTransportSettings { get; }
+
+ ///
+ /// Device connection string details.
+ ///
+ IotHubConnectionString IotHubConnectionString { get; }
+
+ ///
+ /// SDK,.NET version, Operating system and environment information.
+ ///
+ ProductInfo ProductInfo { get; }
+
+ ///
+ /// Device configuration options at the time of initialization.
+ ///
+ ClientOptions Options { get; }
+
+ ///
+ /// Device authentication audience.
+ ///
+ string Audience { get; }
+
+ ///
+ /// Whether or not the device is part of a connection pooling.
+ ///
+ bool IsPooling();
+ }
+}
diff --git a/iothub/device/src/Transport/AmqpIot/AmqpIotConnection.cs b/iothub/device/src/Transport/AmqpIot/AmqpIotConnection.cs
index 36004aeb1d..b97c0fc8ce 100644
--- a/iothub/device/src/Transport/AmqpIot/AmqpIotConnection.cs
+++ b/iothub/device/src/Transport/AmqpIot/AmqpIotConnection.cs
@@ -84,7 +84,7 @@ internal async Task OpenSessionAsync(CancellationToken cancellat
}
}
- internal async Task CreateRefresherAsync(DeviceIdentity deviceIdentity, CancellationToken cancellationToken)
+ internal async Task CreateRefresherAsync(IDeviceIdentity deviceIdentity, CancellationToken cancellationToken)
{
if (_amqpConnection.IsClosing())
{
diff --git a/iothub/device/src/Transport/AmqpIot/AmqpIotSendingLink.cs b/iothub/device/src/Transport/AmqpIot/AmqpIotSendingLink.cs
index 3f0518cb98..0761d48ab6 100644
--- a/iothub/device/src/Transport/AmqpIot/AmqpIotSendingLink.cs
+++ b/iothub/device/src/Transport/AmqpIot/AmqpIotSendingLink.cs
@@ -117,7 +117,7 @@ internal async Task SendMessagesAsync(IEnumerable m
}
Outcome outcome;
- using (AmqpMessage amqpMessage = AmqpMessage.Create(messageList))
+ using (var amqpMessage = AmqpMessage.Create(messageList))
{
amqpMessage.MessageFormat = AmqpConstants.AmqpBatchedMessageFormat;
outcome = await SendAmqpMessageAsync(amqpMessage, cancellationToken).ConfigureAwait(false);
@@ -228,10 +228,7 @@ internal async Task SendTwinGetMessageAsync(string correlationId
return new AmqpIotOutcome(outcome);
}
- internal async Task SendTwinPatchMessageAsync(
- string correlationId,
- Stream reportedProperties,
- CancellationToken cancellationToken)
+ internal async Task SendTwinPatchMessageAsync(string correlationId, Stream reportedProperties, CancellationToken cancellationToken)
{
if (Logging.IsEnabled)
{
diff --git a/iothub/device/src/Transport/AmqpIot/AmqpIotSession.cs b/iothub/device/src/Transport/AmqpIot/AmqpIotSession.cs
index cd6c6f26c1..b9c8eeb805 100644
--- a/iothub/device/src/Transport/AmqpIot/AmqpIotSession.cs
+++ b/iothub/device/src/Transport/AmqpIot/AmqpIotSession.cs
@@ -10,6 +10,7 @@
using Microsoft.Azure.Amqp.Framing;
using Microsoft.Azure.Devices.Client.Exceptions;
using Microsoft.Azure.Devices.Client.Extensions;
+using Microsoft.Azure.Devices.Client.Transport.Amqp;
using Microsoft.Azure.Devices.Shared;
namespace Microsoft.Azure.Devices.Client.Transport.AmqpIot
@@ -58,7 +59,7 @@ internal bool IsClosing()
#region Telemetry links
internal async Task OpenTelemetrySenderLinkAsync(
- DeviceIdentity deviceIdentity,
+ IDeviceIdentity deviceIdentity,
CancellationToken cancellationToken)
{
return await OpenSendingAmqpLinkAsync(
@@ -75,7 +76,7 @@ internal bool IsClosing()
}
internal async Task OpenMessageReceiverLinkAsync(
- DeviceIdentity deviceIdentity,
+ IDeviceIdentity deviceIdentity,
CancellationToken cancellationToken)
{
return await OpenReceivingAmqpLinkAsync(
@@ -96,7 +97,7 @@ internal bool IsClosing()
#region EventLink
internal async Task OpenEventsReceiverLinkAsync(
- DeviceIdentity deviceIdentity,
+ IDeviceIdentity deviceIdentity,
CancellationToken cancellationToken)
{
return await OpenReceivingAmqpLinkAsync(
@@ -117,7 +118,7 @@ internal bool IsClosing()
#region MethodLink
internal async Task OpenMethodsSenderLinkAsync(
- DeviceIdentity deviceIdentity,
+ IDeviceIdentity deviceIdentity,
string correlationIdSuffix,
CancellationToken cancellationToken)
{
@@ -135,7 +136,7 @@ internal bool IsClosing()
}
internal async Task OpenMethodsReceiverLinkAsync(
- DeviceIdentity deviceIdentity,
+ IDeviceIdentity deviceIdentity,
string correlationIdSuffix,
CancellationToken cancellationToken)
{
@@ -157,7 +158,7 @@ internal bool IsClosing()
#region TwinLink
internal async Task OpenTwinReceiverLinkAsync(
- DeviceIdentity deviceIdentity,
+ IDeviceIdentity deviceIdentity,
string correlationIdSuffix,
CancellationToken cancellationToken)
{
@@ -175,7 +176,7 @@ internal bool IsClosing()
}
internal async Task OpenTwinSenderLinkAsync(
- DeviceIdentity deviceIdentity,
+ IDeviceIdentity deviceIdentity,
string correlationIdSuffix,
CancellationToken cancellationToken)
{
@@ -197,7 +198,7 @@ internal bool IsClosing()
#region Common link handling
private static async Task OpenSendingAmqpLinkAsync(
- DeviceIdentity deviceIdentity,
+ IDeviceIdentity deviceIdentity,
AmqpSession amqpSession,
byte? senderSettleMode,
byte? receiverSettleMode,
@@ -278,7 +279,7 @@ internal bool IsClosing()
}
private static async Task OpenReceivingAmqpLinkAsync(
- DeviceIdentity deviceIdentity,
+ IDeviceIdentity deviceIdentity,
AmqpSession amqpSession,
byte? senderSettleMode,
byte? receiverSettleMode,
@@ -353,7 +354,7 @@ internal bool IsClosing()
}
}
- private static string BuildLinkAddress(DeviceIdentity deviceIdentity, string deviceTemplate, string moduleTemplate)
+ private static string BuildLinkAddress(IDeviceIdentity deviceIdentity, string deviceTemplate, string moduleTemplate)
{
string path = string.IsNullOrEmpty(deviceIdentity.IotHubConnectionString.ModuleId)
? string.Format(
diff --git a/iothub/device/src/Transport/AmqpIot/AmqpIotTransport.cs b/iothub/device/src/Transport/AmqpIot/AmqpIotTransport.cs
index 4af039ddb6..3406e2a13d 100644
--- a/iothub/device/src/Transport/AmqpIot/AmqpIotTransport.cs
+++ b/iothub/device/src/Transport/AmqpIot/AmqpIotTransport.cs
@@ -117,7 +117,7 @@ private async Task CreateClientWebSocketTransportAsync(Cancellati
|| (Environment.OSVersion.Version.Major == 6
&& Environment.OSVersion.Version.Minor <= 1))
{
- var websocket = await CreateLegacyClientWebSocketAsync(
+ IotHubClientWebSocket websocket = await CreateLegacyClientWebSocketAsync(
websocketUri,
this._amqpTransportSettings.ClientCertificate,
cancellationToken)
diff --git a/iothub/device/src/Transport/DefaultDelegatingHandler.cs b/iothub/device/src/Transport/DefaultDelegatingHandler.cs
index 5876904905..2facb74b96 100644
--- a/iothub/device/src/Transport/DefaultDelegatingHandler.cs
+++ b/iothub/device/src/Transport/DefaultDelegatingHandler.cs
@@ -31,10 +31,7 @@ protected DefaultDelegatingHandler(IPipelineContext context, IDelegatingHandler
public IDelegatingHandler InnerHandler
{
- get
- {
- return _innerHandler;
- }
+ get => _innerHandler;
protected set
{
_innerHandler = value;
@@ -203,18 +200,6 @@ public virtual Task SendClientTwinPropertyPatchA
return InnerHandler?.SendClientTwinPropertyPatchAsync(reportedProperties, cancellationToken) ?? Task.FromResult(null);
}
- public virtual Task GetPropertiesAsync(PayloadConvention payloadConvention, CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
- return InnerHandler?.GetPropertiesAsync(payloadConvention, cancellationToken) ?? Task.FromResult(null);
- }
-
- public virtual Task SendPropertyPatchAsync(ClientPropertyCollection reportedProperties, CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
- return InnerHandler?.SendPropertyPatchAsync(reportedProperties, cancellationToken) ?? Task.FromResult(null);
- }
-
public virtual bool IsUsable => InnerHandler?.IsUsable ?? true;
protected void ThrowIfDisposed()
diff --git a/iothub/device/src/Transport/ErrorDelegatingHandler.cs b/iothub/device/src/Transport/ErrorDelegatingHandler.cs
index d0f881fcd4..83942ad5d1 100644
--- a/iothub/device/src/Transport/ErrorDelegatingHandler.cs
+++ b/iothub/device/src/Transport/ErrorDelegatingHandler.cs
@@ -158,9 +158,12 @@ private static bool IsSecurityExceptionChain(Exception exceptionChain)
private static bool IsTlsSecurity(Exception singleException)
{
if (// WinHttpException (0x80072F8F): A security error occurred.
- (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && (singleException.HResult == unchecked((int)0x80072F8F))) ||
+ (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
+ && singleException.HResult == unchecked((int)0x80072F8F))
+ ||
// CURLE_SSL_CACERT (60): Peer certificate cannot be authenticated with known CA certificates.
- (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && (singleException.HResult == 60)) ||
+ (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && singleException.HResult == 60)
+ ||
singleException is AuthenticationException)
{
return true;
diff --git a/iothub/device/src/Transport/HttpTransportHandler.cs b/iothub/device/src/Transport/HttpTransportHandler.cs
index 772788c9b9..494bc964da 100644
--- a/iothub/device/src/Transport/HttpTransportHandler.cs
+++ b/iothub/device/src/Transport/HttpTransportHandler.cs
@@ -400,12 +400,12 @@ public override Task RejectAsync(string lockToken, CancellationToken cancellatio
public override Task GetClientTwinPropertiesAsync(CancellationToken cancellationToken)
{
- throw new NotImplementedException("This operation is not supported over HTTP. Please use MQTT or AMQP protocol instead.");
+ throw new NotImplementedException("This operation is not supported over HTTP. Please use MQTT protocol instead.");
}
public override Task SendClientTwinPropertyPatchAsync(Stream reportedProperties, CancellationToken cancellationToken)
{
- throw new NotImplementedException("This operation is not supported over HTTP. Please use MQTT or AMQP protocol instead.");
+ throw new NotImplementedException("This operation is not supported over HTTP. Please use MQTT protocol instead.");
}
// This is for invoking methods from an edge module to another edge device or edge module.
diff --git a/iothub/device/src/Transport/IDeviceClientEndpointIdentityFactory.cs b/iothub/device/src/Transport/IDeviceClientEndpointIdentityFactory.cs
deleted file mode 100644
index b0d61a6686..0000000000
--- a/iothub/device/src/Transport/IDeviceClientEndpointIdentityFactory.cs
+++ /dev/null
@@ -1,18 +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;
-using System.IO;
-
-namespace Microsoft.Azure.Devices.Client.Transport
-{
- ///
- /// Factory interface to create DeviceClientEndpointIdentity objects for Amqp transport layer
- ///
- internal interface IDeviceClientEndpointIdentityFactory
- {
- DeviceIdentity Create(IotHubConnectionString iotHubConnectionString, AmqpTransportSettings amqpTransportSettings, ProductInfo productInfo);
- }
-}
diff --git a/iothub/device/src/Transport/Mqtt/MqttIotHubAdapter.cs b/iothub/device/src/Transport/Mqtt/MqttIotHubAdapter.cs
index e93aaf7f7a..54b51c4951 100644
--- a/iothub/device/src/Transport/Mqtt/MqttIotHubAdapter.cs
+++ b/iothub/device/src/Transport/Mqtt/MqttIotHubAdapter.cs
@@ -5,6 +5,7 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.IO;
@@ -235,7 +236,7 @@ public override void ChannelRead(IChannelHandlerContext context, object message)
// If a message is received when the state is Connected or a CONNACK is received when the state is Connecting, then the message should be processed.
if (IsInState(StateFlags.Connected) || IsInState(StateFlags.Connecting) && packet.PacketType == PacketType.CONNACK)
{
- ProcessMessage(context, packet);
+ ProcessMessageAsync(context, packet);
}
else
{
@@ -697,10 +698,10 @@ private void ProcessUnsubAck(IChannelHandlerContext context, UnsubAckPacket pack
#region Receiving
- private async void ProcessMessage(IChannelHandlerContext context, Packet packet)
+ private async void ProcessMessageAsync(IChannelHandlerContext context, Packet packet)
{
if (Logging.IsEnabled)
- Logging.Enter(this, context.Name, packet.PacketType, nameof(ProcessMessage));
+ Logging.Enter(this, context.Name, packet.PacketType, nameof(ProcessMessageAsync));
try
{
@@ -732,7 +733,7 @@ private async void ProcessMessage(IChannelHandlerContext context, Packet packet)
default:
if (Logging.IsEnabled)
- Logging.Error(context, $"Received an unexpected packet type {packet.PacketType}, will shut down.", nameof(ProcessMessage));
+ Logging.Error(context, $"Received an unexpected packet type {packet.PacketType}, will shut down.", nameof(ProcessMessageAsync));
ShutdownOnErrorAsync(context, new InvalidOperationException($"Unexpected packet type {packet.PacketType}"));
break;
@@ -741,18 +742,18 @@ private async void ProcessMessage(IChannelHandlerContext context, Packet packet)
catch (Exception ex) when (!ex.IsFatal())
{
if (Logging.IsEnabled)
- Logging.Error(context, $"Received a non-fatal exception while processing a received packet of type {packet.PacketType}, will shut down: {ex}", nameof(ProcessMessage));
+ Logging.Error(context, $"Received a non-fatal exception while processing a received packet of type {packet.PacketType}, will shut down: {ex}", nameof(ProcessMessageAsync));
ShutdownOnErrorAsync(context, ex);
}
finally
{
if (Logging.IsEnabled)
- Logging.Exit(this, context.Name, packet.PacketType, nameof(ProcessMessage));
+ Logging.Exit(this, context.Name, packet.PacketType, nameof(ProcessMessageAsync));
}
}
- [System.Diagnostics.CodeAnalysis.SuppressMessage(
+ [SuppressMessage(
"Reliability",
"CA2000:Dispose objects before losing scope",
Justification = "The created message is handed to the user and the user application is in charge of disposing the message.")]
diff --git a/iothub/device/src/Transport/Mqtt/MqttIotHubAdapterFactory.cs b/iothub/device/src/Transport/Mqtt/MqttIotHubAdapterFactory.cs
index 536a0bfcbe..d15395125a 100644
--- a/iothub/device/src/Transport/Mqtt/MqttIotHubAdapterFactory.cs
+++ b/iothub/device/src/Transport/Mqtt/MqttIotHubAdapterFactory.cs
@@ -1,17 +1,15 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-using System;
-
namespace Microsoft.Azure.Devices.Client.Transport.Mqtt
{
internal class MqttIotHubAdapterFactory
{
- private readonly MqttTransportSettings settings;
+ private readonly MqttTransportSettings _settings;
public MqttIotHubAdapterFactory(MqttTransportSettings settings)
{
- this.settings = settings;
+ _settings = settings;
}
public MqttIotHubAdapter Create(
@@ -21,7 +19,7 @@ public MqttIotHubAdapterFactory(MqttTransportSettings settings)
ProductInfo productInfo,
ClientOptions options)
{
- IWillMessage willMessage = mqttTransportSettings.HasWill ? this.settings.WillMessage : null;
+ IWillMessage willMessage = mqttTransportSettings.HasWill ? _settings.WillMessage : null;
return new MqttIotHubAdapter(
iotHubConnectionString.DeviceId,
diff --git a/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs b/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs
index 151aa798f2..d547c487ef 100644
--- a/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs
+++ b/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs
@@ -972,56 +972,6 @@ public override async Task SendClientTwinPropert
return response;
}
- public override async Task GetPropertiesAsync(PayloadConvention payloadConvention, CancellationToken cancellationToken)
- {
- cancellationToken.ThrowIfCancellationRequested();
- EnsureValidState();
-
- using var request = new Message();
- string rid = Guid.NewGuid().ToString();
- request.MqttTopicName = TwinGetTopic.FormatInvariant(rid);
-
- using Message response = await SendTwinRequestAsync(request, rid, cancellationToken).ConfigureAwait(false);
-
- using var reader = new StreamReader(response.GetBodyStream(), payloadConvention.PayloadEncoder.ContentEncoding);
- string body = reader.ReadToEnd();
-
- try
- {
- ClientTwinProperties twinProperties = JsonConvert.DeserializeObject(body);
- var properties = twinProperties.ToClientProperties(payloadConvention);
- return properties;
- }
- catch (JsonReaderException ex)
- {
- if (Logging.IsEnabled)
- Logging.Error(this, $"Failed to parse Twin JSON: {ex}. Message body: '{body}'");
-
- throw;
- }
- }
-
- public override async Task SendPropertyPatchAsync(ClientPropertyCollection reportedProperties, CancellationToken cancellationToken)
- {
- cancellationToken.ThrowIfCancellationRequested();
- EnsureValidState();
-
- byte[] body = reportedProperties.GetPayloadObjectBytes();
- using var bodyStream = new MemoryStream(body);
-
- using var request = new Message(bodyStream);
-
- string rid = Guid.NewGuid().ToString();
- request.MqttTopicName = TwinPatchTopic.FormatInvariant(rid);
-
- using Message message = await SendTwinRequestAsync(request, rid, cancellationToken).ConfigureAwait(false);
- return new ClientPropertiesUpdateResponse
- {
- RequestId = message.Properties[RequestIdKey],
- Version = long.Parse(message.Properties[VersionKey], CultureInfo.InvariantCulture)
- };
- }
-
private async Task OpenInternalAsync(CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -1259,7 +1209,6 @@ private async Task SendTwinRequestAsync(Message request, string rid, Ca
.Handler(new ActionChannelInitializer(ch =>
{
var tlsHandler = new TlsHandler(streamFactory, clientTlsSettings);
-
ch.Pipeline.AddLast(
tlsHandler,
MqttEncoder.Instance,
@@ -1351,6 +1300,7 @@ private async Task SendTwinRequestAsync(Message request, string rid, Ca
await websocket.ConnectAsync(websocketUri, cts.Token).ConfigureAwait(false);
var clientWebSocketChannel = new ClientWebSocketChannel(null, websocket);
+
clientWebSocketChannel
.Option(ChannelOption.Allocator, UnpooledByteBufferAllocator.Default)
.Option(ChannelOption.AutoRead, false)
@@ -1432,7 +1382,7 @@ private static IEventLoopGroup GetEventLoopGroup()
if (!string.IsNullOrWhiteSpace(envValue))
{
string processorEventCountValue = Environment.ExpandEnvironmentVariables(envValue);
- if (int.TryParse(processorEventCountValue, out var processorThreadCount))
+ if (int.TryParse(processorEventCountValue, out int processorThreadCount))
{
if (Logging.IsEnabled)
Logging.Info(null, $"EventLoopGroup threads count {processorThreadCount}.");
diff --git a/iothub/device/src/Transport/Mqtt/MqttTransportSettings.cs b/iothub/device/src/Transport/Mqtt/MqttTransportSettings.cs
index e899c55994..ed9c960a79 100644
--- a/iothub/device/src/Transport/Mqtt/MqttTransportSettings.cs
+++ b/iothub/device/src/Transport/Mqtt/MqttTransportSettings.cs
@@ -232,9 +232,7 @@ public bool CertificateRevocationCheck
///
public X509Certificate ClientCertificate { get; set; }
- ///
- /// The proxy settings to be used when communicating with IoT Hub.
- ///
+ ///
public IWebProxy Proxy { get; set; }
///
diff --git a/iothub/device/src/Transport/Mqtt/OrderedTwoPhaseWorkQueue.cs b/iothub/device/src/Transport/Mqtt/OrderedTwoPhaseWorkQueue.cs
index 1db0c0490a..a137946a92 100644
--- a/iothub/device/src/Transport/Mqtt/OrderedTwoPhaseWorkQueue.cs
+++ b/iothub/device/src/Transport/Mqtt/OrderedTwoPhaseWorkQueue.cs
@@ -2,7 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
-using System.Collections.Generic;
+using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
using DotNetty.Transport.Channels;
@@ -27,7 +27,7 @@ public IncompleteWorkItem(TWorkId id, TWork workItem)
private readonly Func _getWorkId;
private readonly Func _completeWorkAsync;
- private readonly Queue _incompleteQueue = new Queue();
+ private readonly ConcurrentQueue _incompleteQueue = new ConcurrentQueue();
public OrderedTwoPhaseWorkQueue(
Func workerAsync,
@@ -46,16 +46,22 @@ public Task CompleteWorkAsync(IChannelHandlerContext context, TWorkId workId)
throw new IotHubException("Nothing to complete.", isTransient: false);
}
- IncompleteWorkItem incompleteWorkItem = _incompleteQueue.Peek();
- if (incompleteWorkItem.Id.Equals(workId))
+ if (_incompleteQueue.TryDequeue(out IncompleteWorkItem incompleteWorkItem))
{
- _incompleteQueue.Dequeue();
- return _completeWorkAsync(context, incompleteWorkItem.WorkItem);
- }
+ if (incompleteWorkItem.Id.Equals(workId))
+ {
+ return _completeWorkAsync(context, incompleteWorkItem.WorkItem);
+ }
- throw new IotHubException(
- $"Work must be complete in the same order as it was started. Expected work id: '{incompleteWorkItem.Id}', actual work id: '{workId}'",
- isTransient: false);
+ throw new IotHubException(
+ $"Work must be complete in the same order as it was started. Expected work id: '{incompleteWorkItem.Id}', actual work id: '{workId}'",
+ isTransient: false);
+ }
+#if NET451
+ return TaskHelpers.CompletedTask;
+#else
+ return Task.CompletedTask;
+#endif
}
protected override async Task DoWorkAsync(IChannelHandlerContext context, TWork work)
@@ -77,17 +83,17 @@ public override void Abort(Exception exception)
if (stateBefore != State
&& State == States.Aborted)
{
- while (_incompleteQueue.Any())
+ while (_incompleteQueue.TryDequeue(out IncompleteWorkItem workItem))
{
- var workItem = _incompleteQueue.Dequeue().WorkItem as ICancellable;
+ var cancellableWorkItem = workItem.WorkItem as ICancellable;
if (exception == null)
{
- workItem?.Cancel();
+ cancellableWorkItem?.Cancel();
}
else
{
- workItem?.Abort(exception);
+ cancellableWorkItem?.Abort(exception);
}
}
}
diff --git a/iothub/device/src/Transport/Mqtt/SimpleWorkQueue.cs b/iothub/device/src/Transport/Mqtt/SimpleWorkQueue.cs
index 85d9713a2d..1395f31c1f 100644
--- a/iothub/device/src/Transport/Mqtt/SimpleWorkQueue.cs
+++ b/iothub/device/src/Transport/Mqtt/SimpleWorkQueue.cs
@@ -2,7 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
-using System.Collections.Generic;
+using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
using DotNetty.Common.Utilities;
@@ -25,14 +25,14 @@ namespace Microsoft.Azure.Devices.Client.Transport.Mqtt
internal class SimpleWorkQueue
{
private readonly Func _workerAsync;
- private readonly Queue _backlogQueue;
+ private readonly ConcurrentQueue _backlogQueue;
private readonly TaskCompletionSource _completionSource;
public SimpleWorkQueue(Func workerAsync)
{
_workerAsync = workerAsync;
_completionSource = new TaskCompletionSource();
- _backlogQueue = new Queue();
+ _backlogQueue = new ConcurrentQueue();
}
protected States State { get; set; }
@@ -111,9 +111,8 @@ public virtual void Abort(Exception exception)
case States.FinalProcessing:
State = States.Aborted;
- while (_backlogQueue.Any())
+ while (_backlogQueue.TryDequeue(out TWork workItem))
{
- TWork workItem = _backlogQueue.Dequeue();
ReferenceCountUtil.Release(workItem);
var cancellableWorkItem = workItem as ICancellable;
@@ -146,9 +145,9 @@ private async void StartWorkQueueProcessingAsync(IChannelHandlerContext context)
try
{
while (_backlogQueue.Any()
- && State != States.Aborted)
+ && State != States.Aborted
+ && _backlogQueue.TryDequeue(out TWork workItem))
{
- TWork workItem = _backlogQueue.Dequeue();
await DoWorkAsync(context, workItem).ConfigureAwait(false);
}
diff --git a/iothub/device/src/Transport/RetryDelegatingHandler.cs b/iothub/device/src/Transport/RetryDelegatingHandler.cs
index 0e86bd2326..2b2ed73893 100644
--- a/iothub/device/src/Transport/RetryDelegatingHandler.cs
+++ b/iothub/device/src/Transport/RetryDelegatingHandler.cs
@@ -54,9 +54,7 @@ private class TransientErrorStrategy : ITransientErrorDetectionStrategy
{
public bool IsTransient(Exception ex)
{
- return ex is IotHubException
- ? ((IotHubException)ex).IsTransient
- : false;
+ return ex is IotHubException exception && exception.IsTransient;
}
}
@@ -610,50 +608,6 @@ public override async Task SendClientTwinPropert
}
}
- public override async Task GetPropertiesAsync(PayloadConvention payloadConvention, CancellationToken cancellationToken)
- {
- try
- {
- Logging.Enter(this, payloadConvention, cancellationToken, nameof(SendPropertyPatchAsync));
-
- return await _internalRetryPolicy
- .ExecuteAsync(
- async () =>
- {
- await EnsureOpenedAsync(false, cancellationToken).ConfigureAwait(false);
- return await base.GetPropertiesAsync(payloadConvention, cancellationToken).ConfigureAwait(false);
- },
- cancellationToken)
- .ConfigureAwait(false);
- }
- finally
- {
- Logging.Exit(this, payloadConvention, cancellationToken, nameof(SendPropertyPatchAsync));
- }
- }
-
- public override async Task SendPropertyPatchAsync(ClientPropertyCollection reportedProperties, CancellationToken cancellationToken)
- {
- try
- {
- Logging.Enter(this, reportedProperties, cancellationToken, nameof(SendPropertyPatchAsync));
-
- return await _internalRetryPolicy
- .ExecuteAsync(
- async () =>
- {
- await EnsureOpenedAsync(false, cancellationToken).ConfigureAwait(false);
- return await base.SendPropertyPatchAsync(reportedProperties, cancellationToken).ConfigureAwait(false);
- },
- cancellationToken)
- .ConfigureAwait(false);
- }
- finally
- {
- Logging.Exit(this, reportedProperties, cancellationToken, nameof(SendPropertyPatchAsync));
- }
- }
-
public override Task OpenAsync(CancellationToken cancellationToken)
{
return EnsureOpenedAsync(true, cancellationToken);
@@ -882,8 +836,8 @@ await _internalRetryPolicy
{
Logging.Enter(this, timeoutHelper, nameof(OpenAsync));
- // Will throw on error.
- await base.OpenAsync(timeoutHelper).ConfigureAwait(false);
+ // Will throw on error.
+ await base.OpenAsync(timeoutHelper).ConfigureAwait(false);
_onConnectionStatusChanged(ConnectionStatus.Connected, ConnectionStatusChangeReason.Connection_Ok);
}
catch (Exception ex) when (!ex.IsFatal())
@@ -897,7 +851,7 @@ await _internalRetryPolicy
}
}
-
+
}
// Triggered from connection loss event
diff --git a/iothub/device/tests/Amqp/AmqpConnectionPoolTests.cs b/iothub/device/tests/Amqp/AmqpConnectionPoolTests.cs
new file mode 100644
index 0000000000..506aa2ff20
--- /dev/null
+++ b/iothub/device/tests/Amqp/AmqpConnectionPoolTests.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using FluentAssertions;
+using Microsoft.Azure.Devices.Client.Transport;
+using Microsoft.Azure.Devices.Client.Transport.Amqp;
+using Microsoft.Azure.Devices.Client.Transport.AmqpIot;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+
+namespace Microsoft.Azure.Devices.Client.Tests.Amqp
+{
+ [TestClass]
+ public class AmqpConnectionPoolTests
+ {
+ internal class AmqpConnectionPoolTest : AmqpConnectionPool
+ {
+ private readonly IDictionary _dictionaryToUse;
+
+ public AmqpConnectionPoolTest(IDictionary dictionaryToUse)
+ {
+ _dictionaryToUse = dictionaryToUse;
+ }
+
+ protected override IDictionary GetAmqpSasGroupedPoolDictionary()
+ {
+ return _dictionaryToUse;
+ }
+ }
+
+ [TestMethod]
+ public void AmqpConnectionPool_Add_Remove_ConnectionHolderIsRemoved()
+ {
+ string sharedAccessKeyName = "HubOwner";
+ uint poolSize = 10;
+ IDeviceIdentity testDevice = CreatePooledSasGroupedDeviceIdentity(sharedAccessKeyName, poolSize);
+ IDictionary injectedDictionary = new Dictionary();
+
+ AmqpConnectionPoolTest pool = new AmqpConnectionPoolTest(injectedDictionary);
+
+ AmqpUnit addedUnit = pool.CreateAmqpUnit(testDevice, null, null, null, null, null);
+
+ injectedDictionary[sharedAccessKeyName].Count().Should().Be((int)poolSize);
+
+ pool.RemoveAmqpUnit(addedUnit);
+
+ foreach (object item in injectedDictionary[sharedAccessKeyName])
+ {
+ item.Should().BeNull();
+ }
+ }
+
+ private IDeviceIdentity CreatePooledSasGroupedDeviceIdentity(string sharedAccessKeyName, uint poolSize)
+ {
+ Mock