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); }
private static async Task StartReceivingLoopAsync() { s_log.WriteLine("Starting receiving file notification loop..."); CancellationToken cancellationToken = new CancellationTokenSource(s_duration).Token; while (!cancellationToken.IsCancellationRequested) { try { FileNotification fileNotification = await s_fileNotificationReceiver.ReceiveAsync(s_interval).ConfigureAwait(false); if (fileNotification != null) { string key = RetrieveKey(fileNotification.BlobName); s_fileNotifications.TryAdd(key, fileNotification); s_log.WriteLine($"File notification received deviceId={fileNotification.DeviceId}, blobName={fileNotification.BlobName}."); await s_fileNotificationReceiver.AbandonAsync(fileNotification).ConfigureAwait(false); } } catch (Exception) { s_log.WriteLine("Ignore any exception while receiving/abandon file upload notification."); } } s_log.WriteLine("End receiving file notification loop."); }
/// <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); } }
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); }
public static async Task InitAsync() { bool gained = await s_lock.WaitAsync(s_interval).ConfigureAwait(false); if (gained) { try { if (!s_receiving) { s_log.WriteLine("Initializing FileNotificationReceiver..."); ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); s_fileNotificationReceiver = serviceClient.GetFileNotificationReceiver(); s_log.WriteLine("Receiving once to connect FileNotificationReceiver..."); await s_fileNotificationReceiver.ReceiveAsync(TimeSpan.FromSeconds(1)).ConfigureAwait(false); s_log.WriteLine("FileNotificationReceiver connected."); _ = StartReceivingLoopAsync().ConfigureAwait(false); s_receiving = true; } } finally { s_lock.Release(); } } }
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); } }
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); }
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}."); }
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); }