Beispiel #1
0
        public async Task <UserNotification?> ExecuteAsync(
            [ActivityTrigger] IDurableActivityContext context,
            ILogger logger)
        {
            TenantedFunctionData <UserNotification> request = context.GetInput <TenantedFunctionData <UserNotification> >();

            ITenant tenant = await this.tenantProvider.GetTenantAsync(request.TenantId).ConfigureAwait(false);

            logger.LogInformation(
                "Executing CreateNotificationActivity for notification of type {notificationType} for user {userId}",
                request.Payload.NotificationType,
                request.Payload.UserId);

            IUserNotificationStore store = await this.notificationStoreFactory.GetUserNotificationStoreForTenantAsync(tenant).ConfigureAwait(false);

            try
            {
                return(await store.StoreAsync(request.Payload).ConfigureAwait(false));
            }
            catch (UserNotificationStoreConcurrencyException)
            {
                // We will ignore concurrency exceptions; these suggest that the notification has already been created,
                // which normally means that we've received the request to create it twice for reasons outside our
                // control.
                logger.LogInformation(
                    "Received a concurrency exception when attempting to store notification for user '{userId}'.",
                    request.Payload.UserId);
            }

            return(null);
        }
Beispiel #2
0
        public async Task RunAsync(
            [OrchestrationTrigger] IDurableOrchestrationContext orchestrationContext,
            ILogger log)
        {
            ILogger replaySafeLogger = orchestrationContext.CreateReplaySafeLogger(log);

            TenantedFunctionData <BatchReadStatusUpdateRequestItem[]> request = orchestrationContext.GetInput <TenantedFunctionData <BatchReadStatusUpdateRequestItem[]> >();

            try
            {
                await orchestrationContext.CallActivityAsync(
                    nameof(StartLongRunningOperationActivity),
                    (request.LongRunningOperationId !.Value, request.TenantId));

                // Fan out to update each notification
                IEnumerable <Task> updateStatusTasks = request.Payload
                                                       .Select(x => orchestrationContext.CallActivityAsync(
                                                                   nameof(UpdateNotificationReadStatusActivity),
                                                                   new TenantedFunctionData <BatchReadStatusUpdateRequestItem>(request.TenantId, x)));

                await Task.WhenAll(updateStatusTasks);

                await orchestrationContext.CallActivityAsync(
                    nameof(CompleteLongRunningOperationActivity),
                    (request.LongRunningOperationId !.Value, request.TenantId));
            }
            catch (FunctionFailedException)
            {
                await orchestrationContext.CallActivityAsync(
                    nameof(FailLongRunningOperationActivity),
                    (request.LongRunningOperationId !.Value, request.TenantId));
            }
        }
        public async Task RunAsync(
            [OrchestrationTrigger] IDurableOrchestrationContext orchestrationContext,
            ILogger log)
        {
            ILogger replaySafeLogger = orchestrationContext.CreateReplaySafeLogger(log);

            replaySafeLogger.LogInformation(
                "Executing orchestration {orchestrationName} with instance Id {orchestrationInstanceId} from parent instance Id {parentOrchestrationInstanceId}",
                nameof(CreateAndDispatchNotificationOrchestration),
                orchestrationContext.InstanceId,
                orchestrationContext.ParentInstanceId);

            TenantedFunctionData <UserNotification> request = orchestrationContext.GetInput <TenantedFunctionData <UserNotification> >();

            replaySafeLogger.LogDebug("Deserialized CreateNotificationsRequest for user Id '{userId}'", request.Payload.UserId);

            UserNotification?savedUserNotification = await orchestrationContext
                                                     .CallActivityAsync <UserNotification>(nameof(CreateNotificationActivity), request)
                                                     .ConfigureAwait(true);

            // Only trigger to send the notifications from the configured thirdparty delivery channels if they have been configured in the request.
            if (request.Payload.DeliveryChannelConfiguredPerCommunicationType != null && savedUserNotification != null)
            {
                // Add DeliveryChannelConfiguredPerCommunicationType
                UserNotification updatedNotification = savedUserNotification.AddDeliveryChannelConfiguredPerCommunicationType(request.Payload.DeliveryChannelConfiguredPerCommunicationType);

                await orchestrationContext.CallActivityAsync(
                    nameof(DispatchNotificationActivity),
                    new TenantedFunctionData <UserNotification>(request.TenantId, updatedNotification));
            }
        }
Beispiel #4
0
        public async Task ExecuteAsync(
            [ActivityTrigger] IDurableActivityContext context,
            ILogger logger)
        {
            TenantedFunctionData <UserNotification> request = context.GetInput <TenantedFunctionData <UserNotification> >();

            if (request.Payload.Id is null)
            {
                throw new Exception("Notification has to be created before being dispatched via Third Party Delivery Channels.");
            }

            ITenant tenant = await this.tenantProvider.GetTenantAsync(request.TenantId).ConfigureAwait(false);

            logger.LogInformation(
                "Executing DispatchNotificationActivity for notification of type {notificationType} for user {userId}",
                request.Payload.NotificationType,
                request.Payload.UserId);

            if (request.Payload.DeliveryChannelConfiguredPerCommunicationType is null)
            {
                throw new Exception($"There is no communication channels and delivery channel defined the notification type: {request.Payload.NotificationType}");
            }

            var registeredCommunicationChannels = request.Payload.DeliveryChannelConfiguredPerCommunicationType.Keys.ToList();

            if (registeredCommunicationChannels.Count == 0)
            {
                throw new Exception($"There is no communication channels and delivery channel defined the notification type: {request.Payload.NotificationType}");
            }

            // Gets the AzureBlobTemplateStore
            INotificationTemplateStore templateStore = await this.tenantedTemplateStoreFactory.GetTemplateStoreForTenantAsync(tenant).ConfigureAwait(false);

            NotificationTemplate notificationTemplate = await this.generateTemplateComposer.GenerateTemplateAsync(templateStore, request.Payload.Properties, registeredCommunicationChannels, request.Payload.NotificationType).ConfigureAwait(false);

            if (notificationTemplate is null)
            {
                throw new Exception("There was an issue generating notification templates.");
            }

            foreach (KeyValuePair <CommunicationType, string> keyValuePair in request.Payload.DeliveryChannelConfiguredPerCommunicationType)
            {
                switch (keyValuePair.Value)
                {
                case DeliveryChannel.Airship:
                    if (notificationTemplate.WebPushTemplate != null && keyValuePair.Key == CommunicationType.WebPush)
                    {
                        await this.SendWebPushNotificationAsync(request.Payload.UserId, request.Payload.NotificationType, request.Payload.Id, tenant, notificationTemplate.WebPushTemplate).ConfigureAwait(false);
                    }

                    break;

                default:
                    throw new Exception(
                              $"Currently the Delivery Channel is limited to {DeliveryChannel.Airship}");
                }
            }
        }
Beispiel #5
0
        public async Task RunAsync(
            [OrchestrationTrigger] IDurableOrchestrationContext orchestrationContext,
            ILogger log)
        {
            ILogger replaySafeLogger = orchestrationContext.CreateReplaySafeLogger(log);

            replaySafeLogger.LogInformation(
                "Executing orchestration {orchestrationName} with instance Id {orchestrationInstanceId} from parent instance Id {parentOrchestrationInstanceId}",
                nameof(CreateAndDispatchNotificationOrchestration),
                orchestrationContext.InstanceId,
                orchestrationContext.ParentInstanceId);

            TenantedFunctionData <UserNotification> request = orchestrationContext.GetInput <TenantedFunctionData <UserNotification> >();

            replaySafeLogger.LogDebug("Deserialized CreateNotificationsRequest for user Id '{userId}'", request.Payload.UserId);

            await orchestrationContext.CallActivityAsync(nameof(CreateNotificationActivity), request);
        }
        public async Task RunAsync(
            [OrchestrationTrigger] IDurableOrchestrationContext orchestrationContext,
            ILogger log)
        {
            ILogger replaySafeLogger = orchestrationContext.CreateReplaySafeLogger(log);

            TenantedFunctionData <CreateNotificationForDeliveryChannelsRequest> request = orchestrationContext.GetInput <TenantedFunctionData <CreateNotificationForDeliveryChannelsRequest> >();

            try
            {
                await orchestrationContext.CallActivityAsync(
                    nameof(StartLongRunningOperationActivity),
                    (request.LongRunningOperationId !.Value, request.TenantId));

                // Fan out to create each notification
                string[] correlationIds = new string[request.Payload.CorrelationIds.Length + 1];
                request.Payload.CorrelationIds.CopyTo(correlationIds, 0);
                correlationIds[^ 1] = orchestrationContext.InstanceId;
Beispiel #7
0
        public async Task ExecuteAsync(
            [ActivityTrigger] IDurableActivityContext context,
            ILogger logger)
        {
            TenantedFunctionData <BatchReadStatusUpdateRequestItem> request = context.GetInput <TenantedFunctionData <BatchReadStatusUpdateRequestItem> >();

            ITenant tenant = await this.tenantProvider.GetTenantAsync(request.TenantId).ConfigureAwait(false);

            logger.LogInformation(
                "Executing UpdateNotificationReadStatusActivity for notification with Id {notificationId}",
                request.Payload.NotificationId);

            IUserNotificationStore store = await this.notificationStoreFactory.GetUserNotificationStoreForTenantAsync(tenant).ConfigureAwait(false);

            UserNotification originalNotification = await store.GetByIdAsync(request.Payload.NotificationId).ConfigureAwait(false);

            UserNotification modifiedNotification = originalNotification.WithChannelReadStatus(
                request.Payload.DeliveryChannelId,
                request.Payload.NewStatus,
                request.Payload.UpdateTimestamp);

            await store.StoreAsync(modifiedNotification).ConfigureAwait(false);
        }