Beispiel #1
0
        private async Task SendSingleMessage(Client.TransportType transport)
        {
            Tuple <string, string> deviceInfo = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager);

            EventHubClient   eventHubClient;
            EventHubReceiver eventHubReceiver = CreateEventHubReceiver(deviceInfo.Item1, out eventHubClient);

            var deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, transport);
            await deviceClient.OpenAsync();

            string payload;
            string p1Value;

            Client.Message testMessage = ComposeD2CTestMessage(out payload, out p1Value);
            await deviceClient.SendEventAsync(testMessage);

            var events = await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5));

            VerifyTestMessage(events, deviceInfo.Item1, payload, p1Value);

            await deviceClient.CloseAsync();

            await eventHubClient.CloseAsync();

            TestUtil.RemoveDevice(deviceInfo.Item1, registryManager);
        }
Beispiel #2
0
        private async Task SendMessageRecovery(Client.TransportType transport,
                                               string faultType, string reason, int delayInSec, int durationInSec = 0, int retryDurationInMilliSec = 240000)
        {
            await sequentialTestSemaphore.WaitAsync();

            Tuple <string, string> deviceInfo = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager);

            EventHubClient   eventHubClient;
            EventHubReceiver eventHubReceiver = CreateEventHubReceiver(deviceInfo.Item1, out eventHubClient);

            var deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, transport);

            deviceClient.OperationTimeoutInMilliseconds = (uint)retryDurationInMilliSec;
            await deviceClient.OpenAsync();

            string payload, p1Value;

            Client.Message testMessage = ComposeD2CTestMessage(out payload, out p1Value);
            await deviceClient.SendEventAsync(testMessage);

            bool      isReceived = false;
            Stopwatch sw         = new Stopwatch();

            sw.Start();
            while (!isReceived && sw.Elapsed.Minutes < 1)
            {
                var events = await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5));

                isReceived = VerifyTestMessage(events, deviceInfo.Item1, payload, p1Value);
            }
            sw.Stop();

            // send error command and clear eventHubReceiver of the fault injection message
            await deviceClient.SendEventAsync(TestUtil.ComposeErrorInjectionProperties(faultType, reason, delayInSec,
                                                                                       durationInSec));

            await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5));

            Thread.Sleep(1000);
            testMessage = ComposeD2CTestMessage(out payload, out p1Value);
            await deviceClient.SendEventAsync(testMessage);

            sw.Reset();
            sw.Start();
            while (!isReceived && sw.Elapsed.Minutes < 1)
            {
                var events = await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5));

                isReceived = VerifyTestMessage(events, deviceInfo.Item1, payload, p1Value);
            }
            sw.Stop();

            await deviceClient.CloseAsync();

            await eventHubClient.CloseAsync();

            TestUtil.RemoveDevice(deviceInfo.Item1, registryManager);

            sequentialTestSemaphore.Release(1);
        }
Beispiel #3
0
        // verify required message is present in the dictionary
        public static bool VerifyIfMessageIsReceived(string deviceId, Client.Message message, string payload, string p1Value, TimeSpan?maxWaitTime = null)
        {
            if (!maxWaitTime.HasValue)
            {
                maxWaitTime = s_maximumWaitTime;
            }

            s_log.WriteLine($"Expected payload: deviceId={deviceId}; messageId = {message.MessageId}, userId={message.UserId}, payload={payload}; property1={p1Value}");

            bool isReceived = false;

            var sw = new Stopwatch();

            sw.Start();

            while (!isReceived && sw.Elapsed < maxWaitTime)
            {
                events.TryRemove(payload, out EventData eventData);
                if (eventData == null)
                {
                    continue;
                }

                isReceived = VerifyTestMessage(eventData, deviceId, message, p1Value);
            }

            sw.Stop();

            return(isReceived);
        }
Beispiel #4
0
        private static async Task ReceiveMessageWithoutTimeoutCheckAsync(DeviceClient dc, TimeSpan bufferTime, MsTestLogger logger)
        {
            var sw = new Stopwatch();

            while (true)
            {
                try
                {
                    logger.Trace($"{nameof(ReceiveMessageWithoutTimeoutCheckAsync)} - Calling ReceiveAsync()");

                    sw.Restart();
                    using Client.Message message = await dc.ReceiveAsync().ConfigureAwait(false);

                    sw.Stop();

                    logger.Trace($"{nameof(ReceiveMessageWithoutTimeoutCheckAsync)} - Received message={message}; time taken={sw.ElapsedMilliseconds} ms");

                    if (message == null)
                    {
                        break;
                    }

                    await dc.CompleteAsync(message).ConfigureAwait(false);
                }
                finally
                {
                    TimeSpan maxLatency = TimeSpan.FromMilliseconds(dc.OperationTimeoutInMilliseconds) + bufferTime;
                    if (sw.Elapsed > maxLatency)
                    {
                        Assert.Fail($"ReceiveAsync did not return in {maxLatency}, instead it took {sw.Elapsed}.");
                    }
                }
            }
        }
Beispiel #5
0
        public static async Task SendSendBatchMessagesAndVerifyAsync(DeviceClient deviceClient, string deviceId)
        {
            var messagesToBeSent = new Dictionary <Client.Message, Tuple <string, string> >();

            try
            {
                var props = new List <Tuple <string, string> >();
                for (int i = 0; i < MessageBatchCount; i++)
                {
                    (Client.Message testMessage, string payload, string p1Value) = ComposeD2cTestMessage();
                    messagesToBeSent.Add(testMessage, Tuple.Create(payload, p1Value));
                }

                await deviceClient.SendEventBatchAsync(messagesToBeSent.Keys.ToList()).ConfigureAwait(false);

                foreach (KeyValuePair <Client.Message, Tuple <string, string> > messageEntry in messagesToBeSent)
                {
                    Client.Message         message = messageEntry.Key;
                    Tuple <string, string> prop    = messageEntry.Value;

                    bool isReceived = EventHubTestListener.VerifyIfMessageIsReceived(deviceId, message, prop.Item1, prop.Item2);
                    Assert.IsTrue(isReceived, "Message is not received.");
                }
            }
            finally
            {
                foreach (KeyValuePair <Client.Message, Tuple <string, string> > messageEntry in messagesToBeSent)
                {
                    Client.Message message = messageEntry.Key;
                    message.Dispose();
                }
            }
        }
        private async Task SendMessageThrottledForHttp()
        {
            await sequentialTestSemaphore.WaitAsync();

            Tuple <string, string> deviceInfo = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager);

            EventHubClient   eventHubClient;
            EventHubReceiver eventHubReceiver = CreateEventHubReceiver(deviceInfo.Item1, out eventHubClient);

            var deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, Client.TransportType.Http1);

            deviceClient.OperationTimeoutInMilliseconds = (uint)TestUtil.ShortRetryInMilliSec;
            await deviceClient.OpenAsync();

            string payload, p1Value;

            Client.Message testMessage = ComposeD2CTestMessage(out payload, out p1Value);
            await deviceClient.SendEventAsync(testMessage);

            var events = await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5));

            VerifyTestMessage(events, deviceInfo.Item1, payload, p1Value);

            // Implementation of error injection of throttling on http is that it will throttle the
            // fault injection message itself only.  The duration of fault has no effect on http throttle.
            // Client is supposed to retry sending the throttling fault message until operation timeout.
            await deviceClient.SendEventAsync(TestUtil.ComposeErrorInjectionProperties(TestUtil.FaultType_Throttle,
                                                                                       TestUtil.FaultCloseReason_Boom, TestUtil.DefaultDelayInSec, TestUtil.DefaultDurationInSec));

            sequentialTestSemaphore.Release(1);
        }
        /// <summary>
        /// Sends an event to IoT Hub using the provided eventId GUID
        /// </summary>
        /// <param name="device"></param>
        /// <param name="eventId"></param>
        /// <param name="eventData"></param>
        /// <returns></returns>
        public async Task SendEventAsync(Guid eventId, dynamic eventData)
        {
            byte[] bytes;
            string objectType       = this.GetObjectType(eventData);
            var    objectTypePrefix = _configurationProvider.GetConfigurationSettingValue("ObjectTypePrefix");

            if (!string.IsNullOrWhiteSpace(objectType) && !string.IsNullOrEmpty(objectTypePrefix))
            {
                eventData.ObjectType = objectTypePrefix + objectType;
            }

            // sample code to trace the raw JSON that is being sent
            //string rawJson = JsonConvert.SerializeObject(eventData);
            //Trace.TraceInformation(rawJson);

            bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(eventData));

            var message = new Client.Message(bytes);

            message.Properties["EventId"] = eventId.ToString();

            await AzureRetryHelper.OperationWithBasicRetryAsync(async() =>
            {
                try
                {
                    await _deviceClient.SendEventAsync(message);
                }
                catch (Exception ex)
                {
                    _logger.LogError($"SendEventAsync failed, device: {_device.DeviceID}, exception: {ex.Message}");
                }
            });
        }
        private async Task ReceiveMessageWithCallbackRecoveryAsync(
            TestDeviceType type,
            Client.TransportType transport,
            string faultType,
            string reason,
            TimeSpan delayInSec,
            string proxyAddress = null)
        {
            TestDeviceCallbackHandler testDeviceCallbackHandler = null;

            using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString);

            async Task InitOperationAsync(DeviceClient deviceClient, TestDevice testDevice)
            {
                await serviceClient.OpenAsync().ConfigureAwait(false);

                testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger);
                await testDeviceCallbackHandler.SetMessageReceiveCallbackHandlerAsync().ConfigureAwait(false);
            }

            async Task TestOperationAsync(DeviceClient deviceClient, TestDevice testDevice)
            {
                var timeout = TimeSpan.FromSeconds(20);

                using var cts = new CancellationTokenSource(timeout);
                (Message message, string payload, string p1Value) = MessageReceiveE2ETests.ComposeC2dTestMessage(Logger);

                testDeviceCallbackHandler.ExpectedMessageSentByService = message;
                await serviceClient.SendAsync(testDevice.Id, message).ConfigureAwait(false);

                Client.Message receivedMessage = await deviceClient.ReceiveAsync(timeout).ConfigureAwait(false);

                await testDeviceCallbackHandler.WaitForReceiveMessageCallbackAsync(cts.Token).ConfigureAwait(false);

                receivedMessage.Should().BeNull();
            }

            Task CleanupOperationAsync()
            {
                serviceClient.CloseAsync();
                testDeviceCallbackHandler?.Dispose();
                return(Task.FromResult(true));
            }

            await FaultInjection
            .TestErrorInjectionAsync(
                DevicePrefix,
                type,
                transport,
                proxyAddress,
                faultType,
                reason,
                delayInSec,
                FaultInjection.DefaultFaultDuration,
                InitOperationAsync,
                TestOperationAsync,
                CleanupOperationAsync,
                Logger)
            .ConfigureAwait(false);
        }
        protected async Task SendMessageAsync(CancellationToken ct)
        {
            ExceptionDispatchInfo exInfo = null;

            _m.OperationType = TelemetryMetrics.DeviceOperationSend;
            _m.ScheduleTime  = null;
            _sw.Restart();

            try
            {
                Client.Message message = new Client.Message(_messageBytes);
                Task           t       = _dc.SendEventAsync(message, ct);
                _m.ScheduleTime = _sw.ElapsedMilliseconds;

                _sw.Restart();
                await t.ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                _m.ErrorMessage = $"{ex.GetType().Name} - {ex.Message}";
                exInfo          = ExceptionDispatchInfo.Capture(ex);
            }

            _m.ExecuteTime = _sw.ElapsedMilliseconds;
            await _writer.WriteAsync(_m).ConfigureAwait(false);

            exInfo?.Throw();
        }
        public async Task DeviceClient_TokenConnectionDoubleRelease_Ok()
        {
            using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false);

            string deviceConnectionString = testDevice.ConnectionString;

            var    config   = new TestConfiguration.IoTHub.ConnectionStringParser(deviceConnectionString);
            string iotHub   = config.IotHubHostName;
            string deviceId = config.DeviceID;
            string key      = config.SharedAccessKey;

            var builder = new SharedAccessSignatureBuilder()
            {
                Key        = key,
                TimeToLive = new TimeSpan(0, 10, 0),
                Target     = $"{iotHub}/devices/{WebUtility.UrlEncode(deviceId)}",
            };

            var auth = new DeviceAuthenticationWithToken(deviceId, builder.ToSignature());

            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.");
            await deviceClient.OpenAsync().ConfigureAwait(false);

            Logger.Trace($"{deviceId}: DeviceClient SendEventAsync.");
            using var testMessage = new Client.Message(Encoding.UTF8.GetBytes("TestMessage"));
            await deviceClient.SendEventAsync(testMessage).ConfigureAwait(false);

            Logger.Trace($"{deviceId}: DeviceClient CloseAsync.");
            await deviceClient.CloseAsync().ConfigureAwait(false);
        }
        // This function create a device with x509 cert and send a message to the iothub on the transport specified.
        // It then verifies the message is received at the eventHubClient.
        private async Task SendSingleMessageX509(Client.TransportType transport)
        {
            Tuple <string, string> deviceInfo = TestUtil.CreateDeviceWithX509(DevicePrefix, hostName, registryManager);

            EventHubClient   eventHubClient;
            EventHubReceiver eventHubReceiver = CreateEventHubReceiver(deviceInfo.Item1, out eventHubClient);

            string certBase64 = Environment.GetEnvironmentVariable("IOTHUB_X509_PFX_CERTIFICATE");

            Byte[] buff = Convert.FromBase64String(certBase64);

            var cert = new X509Certificate2(buff);

            var auth         = new DeviceAuthenticationWithX509Certificate(deviceInfo.Item1, cert);
            var deviceClient = DeviceClient.Create(deviceInfo.Item2, auth, transport);
            await deviceClient.OpenAsync();

            string payload;
            string p1Value;

            Client.Message testMessage = ComposeD2CTestMessage(out payload, out p1Value);
            await deviceClient.SendEventAsync(testMessage);

            var events = await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5));

            VerifyTestMessage(events, deviceInfo.Item1, payload, p1Value);

            await deviceClient.CloseAsync();

            await eventHubClient.CloseAsync();

            TestUtil.RemoveDevice(deviceInfo.Item1, registryManager);
        }
        protected async Task ReceiveMessageAsync(CancellationToken ct)
        {
            ExceptionDispatchInfo exInfo = null;

            _mRecv.ScheduleTime = null;
            _swRecv.Restart();

            try
            {
                Task <Client.Message> t = _dc.ReceiveAsync(ct);
                _mRecv.ScheduleTime = _swRecv.ElapsedMilliseconds;

                _swRecv.Restart();
                Client.Message msg = await t.ConfigureAwait(false);

                await _dc.CompleteAsync(msg).ConfigureAwait(false);

                int deviceIdFromMessage = BitConverter.ToInt32(msg.GetBytes());
                if (_id != deviceIdFromMessage)
                {
                    throw new InvalidOperationException($"DeviceId mismatch: Expected {_id} actual {deviceIdFromMessage}.");
                }
            }
            catch (Exception ex)
            {
                _mRecv.ErrorMessage = $"{ex.GetType().Name} - {ex.Message}";
                exInfo = ExceptionDispatchInfo.Capture(ex);
            }

            _mRecv.ExecuteTime = _swRecv.ElapsedMilliseconds;
            await _writer.WriteAsync(_mRecv).ConfigureAwait(false);

            exInfo?.Throw();
        }
Beispiel #13
0
        private static async Task ReceiveMessageWithoutTimeoutCheck(DeviceClient dc, TimeSpan bufferTime)
        {
            while (true)
            {
                Stopwatch sw = new Stopwatch();
                try
                {
                    sw.Start();
                    Client.Message message = await dc.ReceiveAsync().ConfigureAwait(false);

                    sw.Stop();

                    if (message == null)
                    {
                        break;
                    }

                    await dc.CompleteAsync(message).ConfigureAwait(false);
                }
                finally
                {
                    TimeSpan maxLatency = TimeSpan.FromMilliseconds(dc.OperationTimeoutInMilliseconds) + bufferTime;
                    if (sw.Elapsed > maxLatency)
                    {
                        Assert.Fail($"ReceiveAsync did not return in {maxLatency}.");
                    }
                }
            }
        }
Beispiel #14
0
        private static async Task ReceiveMessageWithTimeoutCheckAsync(DeviceClient dc, TimeSpan timeout)
        {
            while (true)
            {
                var sw = new Stopwatch();
                try
                {
                    sw.Start();
                    Client.Message message = await dc.ReceiveAsync(timeout).ConfigureAwait(false);

                    sw.Stop();

                    if (message == null)
                    {
                        break;
                    }

                    await dc.CompleteAsync(message).ConfigureAwait(false);
                }
                finally
                {
                    if (sw.Elapsed > (timeout + s_fiveSeconds))
                    {
                        Assert.Fail("ReceiveAsync did not return in Operation Timeout time.");
                    }
                }
            }
        }
        private async Task ReuseAuthenticationMethod_SingleDevice(Client.TransportType transport)
        {
            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.
            DeviceClient 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.
            DeviceClient 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 AuthenticationMethodDisposesTokenRefresher(Client.TransportType transport)
        {
            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.
            DeviceClient 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.
            DeviceClient deviceClient2 = DeviceClient.Create(testDevice.IoTHubHostName, authenticationMethod, transport);

            using var message2 = new Client.Message();

            Func <Task> act = async() => await deviceClient2.SendEventAsync(message2).ConfigureAwait(false);

            await act.Should().ThrowAsync <ObjectDisposedException>();
        }
        private async Task SendSingleSecurityMessageModuleAsync(
            ModuleClient moduleClient)
        {
            await moduleClient.OpenAsync().ConfigureAwait(false);

            using Client.Message testMessage = ComposeD2CSecurityTestMessage();
            await moduleClient.SendEventAsync(testMessage).ConfigureAwait(false);
        }
Beispiel #18
0
        private async Task DeviceClient_TokenIsRefreshed_Internal(Client.TransportType transport)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix).ConfigureAwait(false);

            int ttl    = 6;
            int buffer = 50;

            Device device = testDevice.Identity;

            var refresher = new TestTokenRefresher(
                device.Id,
                device.Authentication.SymmetricKey.PrimaryKey,
                ttl,
                buffer);

            DeviceClient deviceClient =
                DeviceClient.Create(testDevice.IoTHubHostName, refresher, transport);

            var message = new Client.Message(Encoding.UTF8.GetBytes("Hello"));

            // Create the first Token.
            Console.WriteLine($"[{DateTime.UtcNow}] OpenAsync");
            await deviceClient.OpenAsync().ConfigureAwait(false);

            Console.WriteLine($"[{DateTime.UtcNow}] SendEventAsync (1)");
            await deviceClient.SendEventAsync(message).ConfigureAwait(false);

            int countAfterOpenAndFirstSend = refresher.SafeCreateNewTokenCallCount;

            Assert.IsTrue(countAfterOpenAndFirstSend >= 1, $"[{DateTime.UtcNow}] Token should have been refreshed at least once.");

            Console.WriteLine($"[{DateTime.UtcNow}] Waiting {ttl} seconds.");

            // Wait for the Token to expire.
            await Task.Delay(ttl * 1000).ConfigureAwait(false);

            Console.WriteLine($"[{DateTime.UtcNow}] SendEventAsync (2)");
            await deviceClient.SendEventAsync(message).ConfigureAwait(false);

            // Ensure that the token was refreshed.
            if (transport == Client.TransportType.Mqtt)
            {
                // This is not currently supported for MQTT unless the connection is dropped and re-established.
                Assert.IsTrue(
                    refresher.SafeCreateNewTokenCallCount >= countAfterOpenAndFirstSend,
                    $"[{DateTime.UtcNow}] Token should have been refreshed after TTL expired.");
            }
            else
            {
                Assert.IsTrue(
                    refresher.SafeCreateNewTokenCallCount >= countAfterOpenAndFirstSend + 1,
                    $"[{DateTime.UtcNow}] Token should have been refreshed after TTL expired.");
            }

            Console.WriteLine($"[{DateTime.UtcNow}] CloseAsync");
            await deviceClient.CloseAsync().ConfigureAwait(false);
        }
        private Task SendSingleSecurityMessageModule(ModuleClient moduleClient, string deviceId, EventHubTestListener testListener, AzureSecurityCenterForIoTLogAnalyticsClient logAnalticsTestClient)
        {
            moduleClient.OpenAsync();

            Client.Message testMessage = ComposeD2CSecurityTestMessage(out string eventId, out string payload, out string p1Value);
            moduleClient.SendEventAsync(testMessage);

            return(ValidateEvent(deviceId, eventId, payload, p1Value, testListener, logAnalticsTestClient));
        }
        private async Task SendSingleSecurityMessage(DeviceClient deviceClient, string deviceId, EventHubTestListener testListener, AzureSecurityCenterForIoTLogAnalyticsClient logAnalticsTestClient)
        {
            await deviceClient.OpenAsync().ConfigureAwait(false);

            Client.Message testMessage = ComposeD2CSecurityTestMessage(out string eventId, out string payload, out string p1Value);
            await deviceClient.SendEventAsync(testMessage).ConfigureAwait(false);

            await ValidateEvent(deviceId, eventId, payload, p1Value, testListener, logAnalticsTestClient).ConfigureAwait(false);
        }
        private async Task DeviceClient_TokenIsRefreshed_Internal(Client.TransportType transport, int ttl = 6)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix).ConfigureAwait(false);

            int buffer = 50;

            Device device = testDevice.Identity;

            var refresher = new TestTokenRefresher(
                device.Id,
                device.Authentication.SymmetricKey.PrimaryKey,
                ttl,
                buffer,
                transport);

            DeviceClient deviceClient =
                DeviceClient.Create(testDevice.IoTHubHostName, refresher, transport);

            if (transport == Client.TransportType.Mqtt)
            {
                deviceClient.SetConnectionStatusChangesHandler((ConnectionStatus status, ConnectionStatusChangeReason reason) =>
                {
                    _log.WriteLine($"{nameof(ConnectionStatusChangesHandler)}: {status}; {reason}");
                });
            }


            var message = new Client.Message(Encoding.UTF8.GetBytes("Hello"));

            // Create the first Token.
            Console.WriteLine($"[{DateTime.UtcNow}] OpenAsync");
            await deviceClient.OpenAsync().ConfigureAwait(false);

            Console.WriteLine($"[{DateTime.UtcNow}] SendEventAsync (1)");
            await deviceClient.SendEventAsync(message).ConfigureAwait(false);

            int countAfterOpenAndFirstSend = refresher.SafeCreateNewTokenCallCount;

            Assert.IsTrue(countAfterOpenAndFirstSend >= 1, $"[{DateTime.UtcNow}] Token should have been refreshed at least once.");

            Console.WriteLine($"[{DateTime.UtcNow}] Waiting {ttl} seconds.");

            // Wait for the Token to expire.
            await Task.Delay(ttl * 1000).ConfigureAwait(false);

            Console.WriteLine($"[{DateTime.UtcNow}] SendEventAsync (2)");
            await deviceClient.SendEventAsync(message).ConfigureAwait(false);

            // Ensure that the token was refreshed.
            Assert.IsTrue(
                refresher.SafeCreateNewTokenCallCount >= countAfterOpenAndFirstSend + 1,
                $"[{DateTime.UtcNow}] Token should have been refreshed after TTL expired.");

            Console.WriteLine($"[{DateTime.UtcNow}] CloseAsync");
            await deviceClient.CloseAsync().ConfigureAwait(false);
        }
        internal async Task SendMessageRecovery(
            TestDeviceType type,
            Client.TransportType transport,
            string faultType,
            string reason,
            int delayInSec,
            int durationInSec           = FaultInjection.DefaultDurationInSec,
            int retryDurationInMilliSec = FaultInjection.RecoveryTimeMilliseconds)
        {
            EventHubTestListener testListener = null;

            Func <DeviceClient, TestDevice, Task> init = async(deviceClient, testDevice) =>
            {
                testListener = await EventHubTestListener.CreateListener(testDevice.Id).ConfigureAwait(false);

                deviceClient.OperationTimeoutInMilliseconds = (uint)retryDurationInMilliSec;
            };

            Func <DeviceClient, TestDevice, Task> testOperation = async(deviceClient, testDevice) =>
            {
                string payload, p1Value;

                Client.Message testMessage = ComposeD2CTestMessage(out payload, out p1Value);
                await deviceClient.SendEventAsync(testMessage).ConfigureAwait(false);

                bool isReceived = false;
                isReceived = await testListener.WaitForMessage(testDevice.Id, payload, p1Value).ConfigureAwait(false);

                Assert.IsTrue(isReceived);
            };

            Func <Task> cleanupOperation = () =>
            {
                if (testListener != null)
                {
                    return(testListener.CloseAsync());
                }
                else
                {
                    return(Task.FromResult(false));
                }
            };

            await FaultInjection.TestErrorInjectionAsync(
                DevicePrefix,
                type,
                transport,
                faultType,
                reason,
                delayInSec,
                durationInSec,
                init,
                testOperation,
                cleanupOperation).ConfigureAwait(false);
        }
        private static async Task TestDeviceClientInvalidServiceCertificate(Client.TransportType transport)
        {
            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);
        }
Beispiel #24
0
        private async Task SendSingleSecurityMessageModuleAsync(
            ModuleClient moduleClient,
            string deviceId,
            AzureSecurityCenterForIoTLogAnalyticsClient logAnalticsTestClient)
        {
            await moduleClient.OpenAsync().ConfigureAwait(false);

            Client.Message testMessage = ComposeD2CSecurityTestMessage(out string eventId, out _, out _);
            await moduleClient.SendEventAsync(testMessage).ConfigureAwait(false);

            await ValidateEventAsync(deviceId, eventId, logAnalticsTestClient).ConfigureAwait(false);
        }
        public async Task DeviceClient_CreateFromConnectionString_TokenIsRefreshed_Mqtt()
        {
            var sasTokenTimeToLive    = TimeSpan.FromSeconds(10);
            int sasTokenRenewalBuffer = 50;

            using var deviceDisconnected = new SemaphoreSlim(0);

            int operationTimeoutInMilliseconds = (int)sasTokenTimeToLive.TotalMilliseconds * 2;

            // Service allows a buffer time of upto 10mins before dropping connections that are authenticated with an expired sas tokens.
            using var tokenRefreshCts = new CancellationTokenSource((int)(sasTokenTimeToLive.TotalMilliseconds * 2 + TimeSpan.FromMinutes(10).TotalMilliseconds));

            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false);

            var options = new ClientOptions
            {
                SasTokenTimeToLive    = sasTokenTimeToLive,
                SasTokenRenewalBuffer = sasTokenRenewalBuffer,
            };

            using DeviceClient deviceClient = testDevice.CreateDeviceClient(Client.TransportType.Mqtt, options);
            Logger.Trace($"Created {nameof(DeviceClient)} instance for {testDevice.Id}.");

            deviceClient.SetConnectionStatusChangesHandler((ConnectionStatus status, ConnectionStatusChangeReason reason) =>
            {
                Logger.Trace($"{nameof(ConnectionStatusChangesHandler)}: {status}; {reason}");
                if (status == ConnectionStatus.Disconnected_Retrying || status == ConnectionStatus.Disconnected)
                {
                    deviceDisconnected.Release();
                }
            });
            deviceClient.OperationTimeoutInMilliseconds = (uint)operationTimeoutInMilliseconds;

            var message = new Client.Message(Encoding.UTF8.GetBytes("Hello"));

            Logger.Trace($"[{testDevice.Id}]: SendEventAsync (1)");
            await deviceClient.SendEventAsync(message).ConfigureAwait(false);

            // Wait for the Token to expire.
            Logger.Trace($"[{testDevice.Id}]: Waiting for device disconnect.");
            await deviceDisconnected.WaitAsync(tokenRefreshCts.Token).ConfigureAwait(false);

            try
            {
                Logger.Trace($"[{testDevice.Id}]: SendEventAsync (2)");
                await deviceClient.SendEventAsync(message).ConfigureAwait(false);
            }
            catch (OperationCanceledException ex)
            {
                Assert.Fail($"{testDevice.Id} did not refresh token after expected ttl of {sasTokenTimeToLive}: {ex}");
                throw;
            }
        }
        //// This function create a device with x509 cert and send a message to the iothub on the transport specified.
        //// It then verifies the message is received at the eventHubClient.
        internal async Task SendSingleMessageX509(Client.TransportType transport)
        {
            // TODO: Update Jenkins Config
            string endpoint = Configuration.IoTHub.EventHubString;

            if (endpoint.IsNullOrWhiteSpace())
            {
                return;
            }

            Tuple <string, string> deviceInfo = TestUtil.CreateDeviceWithX509(DevicePrefix, hostName, registryManager);

            EventHubClient    eventHubClient;
            PartitionReceiver eventHubReceiver = await CreateEventHubReceiver(deviceInfo.Item1).ConfigureAwait(false);

            X509Certificate2 cert = Configuration.IoTHub.GetCertificateWithPrivateKey();

            var auth         = new DeviceAuthenticationWithX509Certificate(deviceInfo.Item1, cert);
            var deviceClient = DeviceClient.Create(deviceInfo.Item2, auth, transport);

            try
            {
                await deviceClient.OpenAsync().ConfigureAwait(false);

                string         payload;
                string         p1Value;
                Client.Message testMessage = ComposeD2CTestMessage(out payload, out p1Value);
                await deviceClient.SendEventAsync(testMessage).ConfigureAwait(false);

                bool      isReceived = false;
                Stopwatch sw         = new Stopwatch();
                sw.Start();
                while (!isReceived && sw.Elapsed.Minutes < 1)
                {
                    var events = await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5)).ConfigureAwait(false);

                    isReceived = VerifyTestMessage(events, deviceInfo.Item1, payload, p1Value);
                }

                sw.Stop();

                Assert.IsTrue(isReceived, "Message is not received.");
            }
            finally
            {
                await deviceClient.CloseAsync().ConfigureAwait(false);

                await eventHubReceiver.CloseAsync().ConfigureAwait(false);

                await TestUtil.RemoveDeviceAsync(deviceInfo.Item1, registryManager).ConfigureAwait(false);
            }
        }
        private Client.Message ComposeD2CSecurityTestMessage(out string eventId, out string payload, out string p1Value)
        {
            eventId = p1Value = Guid.NewGuid().ToString();
            payload = ComposeAzureSecurityCenterForIoTSecurityMessagePayload(eventId).ToString(Newtonsoft.Json.Formatting.None);

            var message = new Client.Message(Encoding.UTF8.GetBytes(payload))
            {
                Properties = { ["property1"] = p1Value }
            };
            message.SetAsSecurityMessage();

            return message;
        }
        internal async Task SendMessageThrottledForHttp()
        {
            // TODO: Update Jenkins Config
            if (Configuration.IoTHub.EventHubString.IsNullOrWhiteSpace())
            {
                return;
            }
            await sequentialTestSemaphore.WaitAsync();

            Tuple <string, string> deviceInfo = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager);

            EventHubClient    eventHubClient;
            PartitionReceiver eventHubReceiver = await CreateEventHubReceiver(deviceInfo.Item1);

            var deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, Client.TransportType.Http1);

            try
            {
                deviceClient.OperationTimeoutInMilliseconds = (uint)TestUtil.ShortRetryInMilliSec;
                await deviceClient.OpenAsync();

                string         payload, p1Value;
                Client.Message testMessage = ComposeD2CTestMessage(out payload, out p1Value);
                await deviceClient.SendEventAsync(testMessage);

                bool      isReceived = false;
                Stopwatch sw         = new Stopwatch();
                sw.Start();
                while (!isReceived && sw.Elapsed.Minutes < 1)
                {
                    var events = await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5));

                    isReceived = VerifyTestMessage(events, deviceInfo.Item1, payload, p1Value);
                }
                sw.Stop();

                // Implementation of error injection of throttling on http is that it will throttle the
                // fault injection message itself only.  The duration of fault has no effect on http throttle.
                // Client is supposed to retry sending the throttling fault message until operation timeout.
                await deviceClient.SendEventAsync(TestUtil.ComposeErrorInjectionProperties(TestUtil.FaultType_Throttle,
                                                                                           TestUtil.FaultCloseReason_Boom, TestUtil.DefaultDelayInSec, TestUtil.DefaultDurationInSec));
            }
            finally
            {
                await deviceClient.CloseAsync();

                await eventHubReceiver.CloseAsync();

                sequentialTestSemaphore.Release(1);
            }
        }
        // Fault timings:
        // --------------------------------------------------------------------------------------------------------------------------------------------------------------------
        //  --- device in normal operation --- | FaultRequested | --- <delayInSec> --- | --- Device in fault mode for <durationInSec> --- | --- device in normal operation ---
        // --------------------------------------------------------------------------------------------------------------------------------------------------------------------
        public static async Task ActivateFaultInjectionAsync(Client.TransportType transport, string faultType, string reason, TimeSpan delayInSec, TimeSpan durationInSec, DeviceClient deviceClient, MsTestLogger logger)
        {
            logger.Trace($"{nameof(ActivateFaultInjectionAsync)}: Requesting fault injection type={faultType} reason={reason}, delay={delayInSec}s, duration={DefaultFaultDuration}s");

            uint oldTimeout = deviceClient.OperationTimeoutInMilliseconds;

            try
            {
                // For MQTT FaultInjection will terminate the connection prior to a PUBACK
                // which leads to an infinite loop trying to resend the FaultInjection message.
                if (transport == Client.TransportType.Mqtt ||
                    transport == Client.TransportType.Mqtt_Tcp_Only ||
                    transport == Client.TransportType.Mqtt_WebSocket_Only)
                {
                    deviceClient.OperationTimeoutInMilliseconds = (uint)delayInSec.TotalMilliseconds;
                }

                using Client.Message faultInjectionMessage = ComposeErrorInjectionProperties(
                          faultType,
                          reason,
                          delayInSec,
                          durationInSec);

                await deviceClient.SendEventAsync(faultInjectionMessage).ConfigureAwait(false);
            }
            catch (IotHubCommunicationException ex)
            {
                logger.Trace($"{nameof(ActivateFaultInjectionAsync)}: {ex}");

                // For quota injection, the fault is only seen for the original HTTP request.
                if (transport == Client.TransportType.Http1)
                {
                    throw;
                }
            }
            catch (TimeoutException ex)
            {
                logger.Trace($"{nameof(ActivateFaultInjectionAsync)}: {ex}");

                // For quota injection, the fault is only seen for the original HTTP request.
                if (transport == Client.TransportType.Http1)
                {
                    throw;
                }
            }
            finally
            {
                deviceClient.OperationTimeoutInMilliseconds = oldTimeout;
                logger.Trace($"{nameof(ActivateFaultInjectionAsync)}: Fault injection requested.");
            }
        }
Beispiel #30
0
        // This function create a device with x509 cert and send a message to the iothub on the transport specified.
        // It then verifies the message is received at the eventHubClient.
        private async Task SendSingleMessageX509(Client.TransportType transport)
        {
            Tuple <string, string> deviceInfo = TestUtil.CreateDeviceWithX509(DevicePrefix, hostName, registryManager);

            EventHubClient   eventHubClient;
            EventHubReceiver eventHubReceiver = CreateEventHubReceiver(deviceInfo.Item1, out eventHubClient);

            string certBase64 = Environment.GetEnvironmentVariable("IOTHUB_X509_PFX_CERTIFICATE");

            Byte[] buff = Convert.FromBase64String(certBase64);

            var cert = new X509Certificate2(buff);

            var auth         = new DeviceAuthenticationWithX509Certificate(deviceInfo.Item1, cert);
            var deviceClient = DeviceClient.Create(deviceInfo.Item2, auth, transport);

            try
            {
                await deviceClient.OpenAsync();

                string         payload;
                string         p1Value;
                Client.Message testMessage = ComposeD2CTestMessage(out payload, out p1Value);
                await deviceClient.SendEventAsync(testMessage);

                bool      isReceived = false;
                Stopwatch sw         = new Stopwatch();
                sw.Start();
                while (!isReceived && sw.Elapsed.Minutes < 1)
                {
                    var events = await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5));

                    isReceived = VerifyTestMessage(events, deviceInfo.Item1, payload, p1Value);
                }
                sw.Stop();

                Assert.IsTrue(isReceived, "Message is not received.");
            }
            finally
            {
                await deviceClient.CloseAsync();

                await eventHubReceiver.CloseAsync();

                await eventHubClient.CloseAsync();

                TestUtil.RemoveDevice(deviceInfo.Item1, registryManager);
            }
        }
        /// <summary>
        /// Sends an event to IoT Hub using the provided eventId GUID
        /// </summary>
        /// <param name="device"></param>
        /// <param name="eventId"></param>
        /// <param name="eventData"></param>
        /// <returns></returns>
        public async Task SendEventAsync(Guid eventId, dynamic eventData)
        {
            byte[] bytes;
            string objectType = EventSchemaHelper.GetObjectType(eventData);
            var objectTypePrefix = _configurationProvider.GetConfigurationSettingValue("ObjectTypePrefix");

            if (!string.IsNullOrWhiteSpace(objectType) && !string.IsNullOrEmpty(objectTypePrefix))
            {
                eventData.ObjectType = objectTypePrefix + objectType;
            }

            // sample code to trace the raw JSON that is being sent
            //string rawJson = JsonConvert.SerializeObject(eventData);
            //Trace.TraceInformation(rawJson);

            bytes = _serializer.SerializeObject(eventData);

            var message = new Client.Message(bytes);
            message.Properties["EventId"] = eventId.ToString();

            await AzureRetryHelper.OperationWithBasicRetryAsync(async () =>
            {
                try
                {
                    await _deviceClient.SendEventAsync(message);
                }
                catch (Exception ex)
                {
                    _logger.LogError(
                        "{0}{0}*** Exception: SendEventAsync ***{0}{0}EventId: {1}{0}Event Data: {2}{0}Exception: {3}{0}{0}",
                        Console.Out.NewLine,
                        eventId,
                        eventData,
                        ex);
                }
            });
        }