private async Task SetDelayTimeAndSendDelayedRetry( IConfiguration configuration, ServiceBusSendQueueMessageContent queueMessageContent) { // Simply initialize the variable for certain build environments and versions var sendRetryDelayNumberOfMinutes = 0; // If parsing fails, out variable is set to 0, so need to set the default if (!int.TryParse(configuration["SendRetryDelayNumberOfMinutes"], out sendRetryDelayNumberOfMinutes)) { sendRetryDelayNumberOfMinutes = 11; } // Shorten this time by 15 seconds to ensure that when the delayed retry message is taken off of the queue // the Send Retry Delay Time will be earlier and will not block it var sendRetryDelayTime = DateTime.UtcNow + TimeSpan.FromMinutes(sendRetryDelayNumberOfMinutes - 0.25); var globalSendingNotificationDataEntity = new GlobalSendingNotificationDataEntity { SendRetryDelayTime = sendRetryDelayTime, }; await CompanyCommunicatorSendFunction.globalSendingNotificationDataRepository .SetGlobalSendingNotificationDataEntity(globalSendingNotificationDataEntity); await this.SendDelayedRetryOfMessageToSendFunction(configuration, queueMessageContent); }
private async Task SendDelayedRetryOfMessageToSendFunction( IConfiguration configuration, ServiceBusSendQueueMessageContent queueMessageContent) { // Simply initialize the variable for certain build environments and versions var sendRetryDelayNumberOfMinutes = 0; // If parsing fails, out variable is set to 0, so need to set the default if (!int.TryParse(configuration["SendRetryDelayNumberOfMinutes"], out sendRetryDelayNumberOfMinutes)) { sendRetryDelayNumberOfMinutes = 11; } var messageBody = JsonConvert.SerializeObject(queueMessageContent); var serviceBusMessage = new Message(Encoding.UTF8.GetBytes(messageBody)); serviceBusMessage.ScheduledEnqueueTimeUtc = DateTime.UtcNow + TimeSpan.FromMinutes(sendRetryDelayNumberOfMinutes); await CompanyCommunicatorSendFunction.sendQueueServiceBusMessageSender.SendAsync(serviceBusMessage); }
/// <summary> /// Send a scheduled notification to target users. /// </summary> /// <param name="notificationEntity">The notification to be sent.</param> /// <returns>A task that represents the work queued to execute.</returns> public async Task SendScheduledNotificationAsync(NotificationDataEntity notificationEntity) { List <UserDataEntity> deDuplicatedReceiverEntities = new List <UserDataEntity>(); if (notificationEntity.AllUsers) { // Get all users var usersUserDataEntityDictionary = await this.metadataProvider.GetUserDataDictionaryAsync(); deDuplicatedReceiverEntities.AddRange(usersUserDataEntityDictionary.Select(kvp => kvp.Value)); } else { if (notificationEntity.Rosters.Count() != 0) { var rosterUserDataEntityDictionary = await this.metadataProvider.GetTeamsRostersAsync(notificationEntity.Rosters); deDuplicatedReceiverEntities.AddRange(rosterUserDataEntityDictionary.Select(kvp => kvp.Value)); } if (notificationEntity.Teams.Count() != 0) { var teamsReceiverEntities = await this.metadataProvider.GetTeamsReceiverEntities(notificationEntity.Teams); deDuplicatedReceiverEntities.AddRange(teamsReceiverEntities); } if (notificationEntity.ADGroups.Count() != 0) { // Get AD Groups members. var adGroupMemberEntities = await this.metadataProvider.GetADGroupReceiverEntities(notificationEntity.ADGroups); List <UserDataEntity> adGroupMembers = new List <UserDataEntity>(); adGroupMembers.AddRange(adGroupMemberEntities); adGroupMembers = adGroupMembers.ToList(); // Get all users details from database. var usersUserDataEntityDictionary = await this.metadataProvider.GetUserDataDictionaryAsync(); List <UserDataEntity> deAllEntities = new List <UserDataEntity>(); deAllEntities.AddRange(usersUserDataEntityDictionary.Select(kvp => kvp.Value)); deAllEntities = deAllEntities.ToList(); // To get conversation id, mapping all users and ad groups members. for (int i = 0; i < adGroupMembers.Count(); i++) { UserDataEntity userDataEntity = deAllEntities.Find(item => item.AadId == adGroupMembers[i].Id); if (userDataEntity != null && userDataEntity.AadId != null) { deDuplicatedReceiverEntities.Add(userDataEntity); } } deDuplicatedReceiverEntities = deDuplicatedReceiverEntities.Distinct().ToList(); } } var totalMessageCount = deDuplicatedReceiverEntities.Count; notificationEntity.TotalMessageCount = totalMessageCount; // Creates record in Sent notifications. var newSentNotificationId = await this.notificationDataRepository.CopyToSentPartitionAsync(notificationEntity); // Set in SendingNotification data await this.sendingNotificationCreator.CreateAsync(newSentNotificationId, notificationEntity); var allServiceBusMessages = deDuplicatedReceiverEntities .Select(userDataEntity => { var queueMessageContent = new ServiceBusSendQueueMessageContent { NotificationId = newSentNotificationId, UserDataEntity = userDataEntity, }; var messageBody = JsonConvert.SerializeObject(queueMessageContent); return(new Message(Encoding.UTF8.GetBytes(messageBody))); }) .ToList(); // Create batches to send to the service bus var serviceBusBatches = new List <List <Message> >(); var totalNumberMessages = allServiceBusMessages.Count; var batchSize = 100; var numberOfCompleteBatches = totalNumberMessages / batchSize; var numberMessagesInIncompleteBatch = totalNumberMessages % batchSize; for (var i = 0; i < numberOfCompleteBatches; i++) { var startingIndex = i * batchSize; var batch = allServiceBusMessages.GetRange(startingIndex, batchSize); serviceBusBatches.Add(batch); } if (numberMessagesInIncompleteBatch != 0) { var incompleteBatchStartingIndex = numberOfCompleteBatches * batchSize; var incompleteBatch = allServiceBusMessages.GetRange( incompleteBatchStartingIndex, numberMessagesInIncompleteBatch); serviceBusBatches.Add(incompleteBatch); } string serviceBusConnectionString = this.configuration["ServiceBusConnection"]; string queueName = "company-communicator-send"; var messageSender = new MessageSender(serviceBusConnectionString, queueName); // Send batches of messages to the service bus foreach (var batch in serviceBusBatches) { await messageSender.SendAsync(batch); } await this.SendTriggerToDataFunction( this.configuration, newSentNotificationId, totalMessageCount); }
/// <summary> /// Send a notification to target users. /// </summary> /// <param name="draftNotificationEntity">The draft notification to be sent.</param> /// <returns>A task that represents the work queued to execute.</returns> public async Task SendAsync(NotificationDataEntity draftNotificationEntity) { if (draftNotificationEntity == null || !draftNotificationEntity.IsDraft) { return; } List <UserDataEntity> deDuplicatedReceiverEntities = new List <UserDataEntity>(); if (draftNotificationEntity.AllUsers) { // Get all users var usersUserDataEntityDictionary = await this.metadataProvider.GetUserDataDictionaryAsync(); deDuplicatedReceiverEntities.AddRange(usersUserDataEntityDictionary.Select(kvp => kvp.Value)); } else { if (draftNotificationEntity.Rosters.Count() != 0) { var rosterUserDataEntityDictionary = await this.metadataProvider.GetTeamsRostersAsync(draftNotificationEntity.Rosters); deDuplicatedReceiverEntities.AddRange(rosterUserDataEntityDictionary.Select(kvp => kvp.Value)); } if (draftNotificationEntity.Teams.Count() != 0) { var teamsReceiverEntities = await this.metadataProvider.GetTeamsReceiverEntities(draftNotificationEntity.Teams); deDuplicatedReceiverEntities.AddRange(teamsReceiverEntities); } } var totalMessageCount = deDuplicatedReceiverEntities.Count; draftNotificationEntity.TotalMessageCount = totalMessageCount; var newSentNotificationId = await this.notificationDataRepository.MoveDraftToSentPartitionAsync(draftNotificationEntity); // Set in SendingNotification data await this.sendingNotificationCreator.CreateAsync(newSentNotificationId, draftNotificationEntity); var allServiceBusMessages = deDuplicatedReceiverEntities .Select(userDataEntity => { var queueMessageContent = new ServiceBusSendQueueMessageContent { NotificationId = newSentNotificationId, UserDataEntity = userDataEntity, }; var messageBody = JsonConvert.SerializeObject(queueMessageContent); return(new Message(Encoding.UTF8.GetBytes(messageBody))); }) .ToList(); // Create batches to send to the service bus var serviceBusBatches = new List <List <Message> >(); var totalNumberMessages = allServiceBusMessages.Count; var batchSize = 100; var numberOfCompleteBatches = totalNumberMessages / batchSize; var numberMessagesInIncompleteBatch = totalNumberMessages % batchSize; for (var i = 0; i < numberOfCompleteBatches; i++) { var startingIndex = i * batchSize; var batch = allServiceBusMessages.GetRange(startingIndex, batchSize); serviceBusBatches.Add(batch); } if (numberMessagesInIncompleteBatch != 0) { var incompleteBatchStartingIndex = numberOfCompleteBatches * batchSize; var incompleteBatch = allServiceBusMessages.GetRange( incompleteBatchStartingIndex, numberMessagesInIncompleteBatch); serviceBusBatches.Add(incompleteBatch); } string serviceBusConnectionString = this.configuration["ServiceBusConnection"]; string queueName = "company-communicator-send"; var messageSender = new MessageSender(serviceBusConnectionString, queueName); // Send batches of messages to the service bus foreach (var batch in serviceBusBatches) { await messageSender.SendAsync(batch); } await this.SendTriggerToDataFunction( this.configuration, newSentNotificationId, totalMessageCount); }
/// <summary> /// Send a notification to target users. /// </summary> /// <param name="draftNotificationEntity">The draft notification to be sent.</param> /// <returns>A task that represents the work queued to execute.</returns> public async Task SendAsync(NotificationDataEntity draftNotificationEntity) { if (draftNotificationEntity == null || !draftNotificationEntity.IsDraft) { return; } // If message is scheduled or recurrence if (draftNotificationEntity.IsScheduled || draftNotificationEntity.IsRecurrence) { DateTime notificationDate; bool isValidToProceed = true; // Calculate next schedule if (draftNotificationEntity.IsScheduled) { notificationDate = draftNotificationEntity.ScheduleDate; } else { DateTime repeatStartDate = draftNotificationEntity.RepeatStartDate; DateTime currentDate = DateTime.UtcNow.AddDays(-1); // If Recurring start date is older than today date, setting to today date if (repeatStartDate < currentDate) { repeatStartDate = currentDate; } notificationDate = repeatStartDate; if (notificationDate > draftNotificationEntity.RepeatEndDate) { isValidToProceed = false; } } if (isValidToProceed) { var newSentNotificationId = await this.notificationDataRepository.MoveDraftToSentPartitionAsync(draftNotificationEntity, true); var scheduleNotificationEntity = new ScheduleNotificationDataEntity { PartitionKey = PartitionKeyNames.ScheduleNotificationDataTable.ScheduleNotificationsPartition, RowKey = newSentNotificationId, NotificationId = newSentNotificationId, NotificationDate = notificationDate, CreatedDate = DateTime.UtcNow, }; await this.scheduleNotificationDataRepository.CreateScheduleNotification(scheduleNotificationEntity); } } else // If message is onetime sending { List <UserDataEntity> deDuplicatedReceiverEntities = new List <UserDataEntity>(); if (draftNotificationEntity.AllUsers) { // Get all users var usersUserDataEntityDictionary = await this.metadataProvider.GetUserDataDictionaryAsync(); deDuplicatedReceiverEntities.AddRange(usersUserDataEntityDictionary.Select(kvp => kvp.Value)); } else { if (draftNotificationEntity.Rosters.Count() != 0) { var rosterUserDataEntityDictionary = await this.metadataProvider.GetTeamsRostersAsync(draftNotificationEntity.Rosters); deDuplicatedReceiverEntities.AddRange(rosterUserDataEntityDictionary.Select(kvp => kvp.Value)); } if (draftNotificationEntity.Teams.Count() != 0) { var teamsReceiverEntities = await this.metadataProvider.GetTeamsReceiverEntities(draftNotificationEntity.Teams); deDuplicatedReceiverEntities.AddRange(teamsReceiverEntities); } if (draftNotificationEntity.ADGroups.Count() != 0) { // Get AD Groups members. var adGroupMemberEntities = await this.metadataProvider.GetADGroupReceiverEntities(draftNotificationEntity.ADGroups); List <UserDataEntity> adGroupMembers = new List <UserDataEntity>(); adGroupMembers.AddRange(adGroupMemberEntities); adGroupMembers = adGroupMembers.ToList(); // Get all users details from database. var usersUserDataEntityDictionary = await this.metadataProvider.GetUserDataDictionaryAsync(); List <UserDataEntity> deAllEntities = new List <UserDataEntity>(); deAllEntities.AddRange(usersUserDataEntityDictionary.Select(kvp => kvp.Value)); deAllEntities = deAllEntities.ToList(); // To get conversation id, mapping all users and ad groups members. for (int i = 0; i < adGroupMembers.Count(); i++) { UserDataEntity userDataEntity = deAllEntities.Find(item => item.AadId == adGroupMembers[i].Id); if (userDataEntity != null && userDataEntity.AadId != null) { deDuplicatedReceiverEntities.Add(userDataEntity); } } deDuplicatedReceiverEntities = deDuplicatedReceiverEntities.Distinct().ToList(); } } var totalMessageCount = deDuplicatedReceiverEntities.Count; draftNotificationEntity.TotalMessageCount = totalMessageCount; var newSentNotificationId = await this.notificationDataRepository.MoveDraftToSentPartitionAsync(draftNotificationEntity, false); // Set in SendingNotification data await this.sendingNotificationCreator.CreateAsync(newSentNotificationId, draftNotificationEntity); var allServiceBusMessages = deDuplicatedReceiverEntities .Select(userDataEntity => { var queueMessageContent = new ServiceBusSendQueueMessageContent { NotificationId = newSentNotificationId, UserDataEntity = userDataEntity, }; var messageBody = JsonConvert.SerializeObject(queueMessageContent); return(new Message(Encoding.UTF8.GetBytes(messageBody))); }) .ToList(); // Create batches to send to the service bus var serviceBusBatches = new List <List <Message> >(); var totalNumberMessages = allServiceBusMessages.Count; var batchSize = 100; var numberOfCompleteBatches = totalNumberMessages / batchSize; var numberMessagesInIncompleteBatch = totalNumberMessages % batchSize; for (var i = 0; i < numberOfCompleteBatches; i++) { var startingIndex = i * batchSize; var batch = allServiceBusMessages.GetRange(startingIndex, batchSize); serviceBusBatches.Add(batch); } if (numberMessagesInIncompleteBatch != 0) { var incompleteBatchStartingIndex = numberOfCompleteBatches * batchSize; var incompleteBatch = allServiceBusMessages.GetRange( incompleteBatchStartingIndex, numberMessagesInIncompleteBatch); serviceBusBatches.Add(incompleteBatch); } string serviceBusConnectionString = this.configuration["ServiceBusConnection"]; string queueName = "company-communicator-send"; var messageSender = new MessageSender(serviceBusConnectionString, queueName); // Send batches of messages to the service bus foreach (var batch in serviceBusBatches) { await messageSender.SendAsync(batch); } await this.SendTriggerToDataFunction( this.configuration, newSentNotificationId, totalMessageCount); } }