예제 #1
0
        /// <summary>
        /// Handle file notifications
        /// </summary>
        /// <param name="receiver"></param>
        /// <returns></returns>
        private async Task RunAsync(FileNotificationReceiver <FileNotification> receiver)
        {
            while (!_cts.IsCancellationRequested)
            {
                var notification = await receiver.ReceiveAsync();

                if (notification == null)
                {
                    continue;
                }

                // Parse content type from blob name
                var    blobName    = notification.BlobName;
                string contentType = null;
                var    delim       = blobName.IndexOf('/');
                if (delim != -1)
                {
                    // the first segment is the url encoded content type
                    contentType = blobName.Substring(0, delim).UrlDecode();
                    blobName    = blobName.Substring(delim + 1);
                }

                // Call handlers
                await Try.Async(() => Task.WhenAll(_handlers
                                                   .Select(h => h.HandleAsync(notification.DeviceId, null,
                                                                              blobName, contentType, notification.BlobUri,
                                                                              notification.EnqueuedTimeUtc, _cts.Token))));

                await receiver.CompleteAsync(notification);
            }
        }
예제 #2
0
        private static async Task <FileNotification> VerifyFileNotification(FileNotificationReceiver <FileNotification> fileNotificationReceiver, string deviceId)
        {
            FileNotification fileNotification = null;

            Stopwatch sw = new Stopwatch();

            sw.Start();
            while (sw.Elapsed.TotalMinutes < 2)
            {
                // Receive the file notification from queue
                fileNotification = await fileNotificationReceiver.ReceiveAsync(TimeSpan.FromSeconds(20)).ConfigureAwait(false);

                if (fileNotification != null)
                {
                    if (fileNotification.DeviceId == deviceId)
                    {
                        await fileNotificationReceiver.CompleteAsync(fileNotification).ConfigureAwait(false);

                        break;
                    }

                    await fileNotificationReceiver.AbandonAsync(fileNotification).ConfigureAwait(false);

                    fileNotification = null;
                }
            }
            sw.Stop();
            return(fileNotification);
        }
예제 #3
0
        private static async Task <FileNotification> VerifyFileNotification(Tuple <string, string> deviceInfo)
        {
            FileNotification fileNotification = null;

            Stopwatch sw = new Stopwatch();

            sw.Start();
            while (sw.Elapsed.Minutes < 2)
            {
                // Receive the file notification from queue
                fileNotification = await fileNotificationReceiver.ReceiveAsync(TimeSpan.FromSeconds(20));

                if (fileNotification != null)
                {
                    if (fileNotification.DeviceId == deviceInfo.Item1)
                    {
                        await fileNotificationReceiver.CompleteAsync(fileNotification);

                        break;
                    }

                    await fileNotificationReceiver.AbandonAsync(fileNotification);

                    fileNotification = null;
                }
            }
            sw.Stop();
            return(fileNotification);
        }
예제 #4
0
        public async Task StartListenAsync()
        {
            try
            {
                FileNotificationReceiver <FileNotification> fileNotificationReceiver = _serviceClient.GetFileNotificationReceiver();
                while (true)
                {
                    FileNotification fileNotification = null;
                    try
                    {
                        fileNotification = await fileNotificationReceiver.ReceiveAsync();

                        if (fileNotification != null)
                        {
                            await SendToWebAppAsync(fileNotification);

                            await fileNotificationReceiver.CompleteAsync(fileNotification);
                        }
                    }
                    catch (Exception ex)
                    {
                        await fileNotificationReceiver.AbandonAsync(fileNotification);
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }
예제 #5
0
        async Task uploadFile(Client.TransportType transport, string filename, bool x509auth = false)
        {
            DeviceClient           deviceClient;
            Tuple <string, string> deviceInfo;

            if (x509auth)
            {
                deviceInfo = TestUtil.CreateDeviceWithX509(DevicePrefix, hostName, registryManager);

                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);
                deviceClient = DeviceClient.Create(deviceInfo.Item2, auth, transport);
            }
            else
            {
                deviceInfo   = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager);
                deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, transport);
            }

            using (FileStream fileStreamSource = new FileStream(filename, FileMode.Open, FileAccess.Read))
            {
                await deviceClient.UploadToBlobAsync(filename, fileStreamSource);
            }

            ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(hubConnectionString);
            FileNotificationReceiver <FileNotification> fileNotificationReceiver = serviceClient.GetFileNotificationReceiver();

            FileNotification fileNotification;

            while (true)
            {
                // Receive the file notification from queue
                fileNotification = await fileNotificationReceiver.ReceiveAsync(TimeSpan.FromSeconds(20));

                Assert.IsNotNull(fileNotification);
                await fileNotificationReceiver.CompleteAsync(fileNotification);

                if (deviceInfo.Item1 == fileNotification.DeviceId)
                {
                    break;
                }
            }

            Assert.AreEqual(deviceInfo.Item1 + "/" + filename, fileNotification.BlobName, "Uploaded file name mismatch in notifications");
            Assert.AreEqual(new FileInfo(filename).Length, fileNotification.BlobSizeInBytes, "Uploaded file size mismatch in notifications");
            Assert.IsFalse(string.IsNullOrEmpty(fileNotification.BlobUri), "File notification blob uri is null or empty");

            await deviceClient.CloseAsync();

            await serviceClient.CloseAsync();

            TestUtil.RemoveDevice(deviceInfo.Item1, registryManager);
        }
        async Task uploadFile(Client.TransportType transport, string filename)
        {
            Tuple <string, string> deviceInfo = TestUtil.CreateDevice("E2E_FileUpload_CSharp_", hostName, registryManager);
            var deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, transport);

            using (FileStream fileStreamSource = new FileStream(filename, FileMode.Open, FileAccess.Read))
            {
                await deviceClient.UploadToBlobAsync(filename, fileStreamSource);
            }

            ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(hubConnectionString);
            FileNotificationReceiver <FileNotification> fileNotificationReceiver = serviceClient.GetFileNotificationReceiver();

            FileNotification fileNotification;

            while (true)
            {
                // Receive the file notification from queue
                fileNotification = await fileNotificationReceiver.ReceiveAsync(TimeSpan.FromSeconds(20));

                Assert.IsNotNull(fileNotification);
                await fileNotificationReceiver.CompleteAsync(fileNotification);

                if (deviceInfo.Item1 == fileNotification.DeviceId)
                {
                    break;
                }
            }

            Assert.AreEqual(deviceInfo.Item1 + "/" + filename, fileNotification.BlobName, "Uploaded file name mismatch in notifications");
            Assert.AreEqual(new FileInfo(filename).Length, fileNotification.BlobSizeInBytes, "Uploaded file size mismatch in notifications");
            Assert.IsFalse(string.IsNullOrEmpty(fileNotification.BlobUri), "File notification blob uri is null or empty");

            await deviceClient.CloseAsync();

            await serviceClient.CloseAsync();

            TestUtil.RemoveDevice(deviceInfo.Item1, registryManager);
        }
        public static async Task VerifyFileNotification(string fileName, string deviceId)
        {
            string    key       = RetrieveKey(fileName);
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            try
            {
                while (stopwatch.Elapsed < s_checkDuration)
                {
                    bool received = s_fileNotifications.TryRemove(key, out var fileNotification);
                    if (received)
                    {
                        s_log.WriteLine($"Completing FileNotification: deviceId={fileNotification.DeviceId}, blobName={fileNotification.BlobName}.");

                        Assert.AreEqual(deviceId, fileNotification.DeviceId);
                        Assert.IsFalse(string.IsNullOrEmpty(fileNotification.BlobUri), "File notification blob uri is null or empty.");
                        try
                        {
                            await s_fileNotificationReceiver.CompleteAsync(fileNotification).ConfigureAwait(false);
                        }
                        catch (Exception)
                        {
                            s_log.WriteLine("Ignore any exception while completing file upload notification.");
                        }
                        return;
                    }
                    await Task.Delay(s_checkInterval).ConfigureAwait(false);
                }
            }
            finally
            {
                stopwatch.Stop();
            }

            Assert.Fail($"FileNotification is not received in {s_checkDuration}: deviceId={deviceId}, fileName={fileName}.");
        }
        private async Task ReceiveFileUploadNotifications(string targetDeviceId, CancellationToken cancellationToken)
        {
            if (!string.IsNullOrWhiteSpace(targetDeviceId))
            {
                _logger.LogInformation($"Target device is specified, will only complete matching notifications.");
            }

            _logger.LogInformation($"Listening for file upload notifications from the service.");

            FileNotificationReceiver <FileNotification> notificationReceiver = _serviceClient.GetFileNotificationReceiver();

            int totalNotificationsReceived  = 0;
            int totalNotificationsCompleted = 0;
            int totalNotificationsAbandoned = 0;

            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    FileNotification fileUploadNotification = await notificationReceiver.ReceiveAsync(s_notificationReceiverTimeout);

                    if (fileUploadNotification == null)
                    {
                        _logger.LogInformation($"Did not receive any notification after {s_notificationReceiverTimeout.TotalSeconds} seconds.");
                        continue;
                    }

                    totalNotificationsReceived++;

                    _logger.LogInformation($"Received file upload notification.");
                    _logger.LogInformation($"\tDeviceId: {fileUploadNotification.DeviceId ?? "N/A"}.");
                    _logger.LogInformation($"\tFileName: {fileUploadNotification.BlobName ?? "N/A"}.");
                    _logger.LogInformation($"\tEnqueueTimeUTC: {fileUploadNotification.EnqueuedTimeUtc}.");
                    _logger.LogInformation($"\tBlobSizeInBytes: {fileUploadNotification.BlobSizeInBytes}.");

                    // If the targetDeviceId is set and does not match the notification's origin, ignore it by abandoning the notification.
                    // Completing a notification will remove that notification from the service's queue so it won't be delivered to any other receiver again.
                    // Abandoning a notification will put it back on the queue to be re-delivered to receivers. This is mostly used when multiple receivers
                    // are configured and each receiver is only interested in notifications from a particular device/s.
                    if (!string.IsNullOrWhiteSpace(targetDeviceId) &&
                        !string.Equals(fileUploadNotification.DeviceId, targetDeviceId, StringComparison.OrdinalIgnoreCase))
                    {
                        _logger.LogInformation($"Marking notification for {fileUploadNotification.DeviceId} as Abandoned.");

                        await notificationReceiver.AbandonAsync(fileUploadNotification);

                        _logger.LogInformation($"Successfully marked the notification for device {fileUploadNotification.DeviceId} as Abandoned.");
                        totalNotificationsAbandoned++;
                    }
                    else
                    {
                        _logger.LogInformation($"Marking notification for {fileUploadNotification.DeviceId} as Completed.");

                        await notificationReceiver.CompleteAsync(fileUploadNotification);

                        _logger.LogInformation($"Successfully marked the notification for device {fileUploadNotification.DeviceId} as Completed.");
                        totalNotificationsCompleted++;
                    }
                }
                catch (Exception e) when((e is IotHubException) || (e is DeviceMessageLockLostException))
                {
                    _logger.LogWarning($"Caught a recoverable exception, will retry: {e.Message} - {e}");
                }
            }

            _logger.LogInformation($"Total Notifications Received: {totalNotificationsReceived}.");
            _logger.LogInformation($"Total Notifications Marked as Completed: {totalNotificationsCompleted}.");
            _logger.LogInformation($"Total Notifications Marked as Abandoned: {totalNotificationsAbandoned}.");
        }
예제 #9
0
        async Task uploadFileDisconnectTransport(Client.TransportType transport, string filename, string faultType, string reason, int delayInSec,
                                                 int durationInSec = 0, int retryDurationInMilliSec = 24000)
        {
            Tuple <string, string> deviceInfo   = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager);
            DeviceClient           deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, transport);

            deviceClient.OperationTimeoutInMilliseconds = (uint)retryDurationInMilliSec;

            Task fileuploadTask;

            using (FileStream fileStreamSource = new FileStream(filename, FileMode.Open, FileAccess.Read))
            {
                fileuploadTask = deviceClient.UploadToBlobAsync(filename, fileStreamSource);

                // send error command after 400ms to allow time for the actual fileupload operation to start
                await Task.Delay(400);

                try
                {
                    await
                    deviceClient.SendEventAsync(TestUtil.ComposeErrorInjectionProperties(faultType, reason,
                                                                                         delayInSec, durationInSec));
                }
                catch (Exception)
                {
                    // catch and ignore exceptions resulted from error injection and continue to
                    // check result of the file upload status
                }

                await fileuploadTask;
            }

            ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(hubConnectionString);
            FileNotificationReceiver <FileNotification> fileNotificationReceiver = serviceClient.GetFileNotificationReceiver();

            FileNotification fileNotification;

            while (true)
            {
                // Receive the file notification from queue
                fileNotification = await fileNotificationReceiver.ReceiveAsync(TimeSpan.FromSeconds(20));

                Assert.IsNotNull(fileNotification);
                await fileNotificationReceiver.CompleteAsync(fileNotification);

                if (deviceInfo.Item1 == fileNotification.DeviceId)
                {
                    break;
                }
            }

            Assert.AreEqual(deviceInfo.Item1 + "/" + filename, fileNotification.BlobName, "Uploaded file name mismatch in notifications");
            Assert.AreEqual(new FileInfo(filename).Length, fileNotification.BlobSizeInBytes, "Uploaded file size mismatch in notifications");
            Assert.IsFalse(string.IsNullOrEmpty(fileNotification.BlobUri), "File notification blob uri is null or empty");

            await deviceClient.CloseAsync();

            await serviceClient.CloseAsync();

            TestUtil.RemoveDevice(deviceInfo.Item1, registryManager);
        }