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 NotificationHub(
     IUserNotificationStore userNotificationsStore,
     IUserNotificationService userNotificationService)
 {
     this.userNotificationsStore  = userNotificationsStore;
     this.userNotificationService = userNotificationService;
 }
 public NotificationsController(
     IUserNotificationStore userNotificationsStore,
     IUserNotificationService userNotificationService)
 {
     this.userNotificationsStore  = userNotificationsStore;
     this.userNotificationService = userNotificationService;
 }
        private async Task <GetNotificationsResult> GetNotificationsForUserAsync(string userId, int count)
        {
            ITenantedUserNotificationStoreFactory storeFactory = this.serviceProvider.GetRequiredService <ITenantedUserNotificationStoreFactory>();
            IUserNotificationStore store = await storeFactory.GetUserNotificationStoreForTenantAsync(this.featureContext.GetTransientTenant()).ConfigureAwait(false);

            return(await store.GetAsync(userId, null, count).ConfigureAwait(false));
        }
        private async Task <GetNotificationsResult> GetNotificationsAsync(
            string userId,
            string?sinceNotificationId,
            int maxItems,
            string?continuationToken,
            IUserNotificationStore userNotificationStore)
        {
            GetNotificationsResult results;

            try
            {
                this.logger.LogDebug($"Retrieving notifications for user {userId}");
                results = string.IsNullOrEmpty(continuationToken)
                                    ? await userNotificationStore.GetAsync(userId, sinceNotificationId, maxItems).ConfigureAwait(false)
                                    : await userNotificationStore.GetAsync(userId, continuationToken).ConfigureAwait(false);
            }
            catch (ArgumentException) when(!string.IsNullOrEmpty(continuationToken))
            {
                // The most likely reason for this is that the user Id in the continuation token doesn't match that in
                // the path - which makes this a bad request.
                throw new OpenApiBadRequestException("The combination of arguments supplied is invalid.", "The arguments supplied to the method were inconsistent. This likely means that the continuation token supplied was either invalid, or contained a different user Id to that specified in the path.");
            }

            return(results);
        }
        public async Task WhenIAskTheUserNotificationStoreForNotificationsForTheUserWithId(int itemCount, string userId, string resultName)
        {
            IUserNotificationStore store  = this.serviceProvider.GetRequiredService <IUserNotificationStore>();
            GetNotificationsResult result = await store.GetAsync(userId, null, itemCount).ConfigureAwait(false);

            this.scenarioContext.Set(result, resultName);
        }
        public async Task <OpenApiResult> GetNotificationsForUserAsync(
            IOpenApiContext context,
            string userId,
            string?sinceNotificationId,
            int?maxItems,
            string?continuationToken)
        {
            // We can guarantee tenant Id is available because it's part of the Uri.
            ITenant tenant = await this.marainServicesTenancy.GetRequestingTenantAsync(context.CurrentTenantId !).ConfigureAwait(false);

            IUserNotificationStore userNotificationStore =
                await this.userNotificationStoreFactory.GetUserNotificationStoreForTenantAsync(tenant).ConfigureAwait(false);

            maxItems ??= 50;

            GetNotificationsResult results = await this.GetNotificationsAsync(
                userId,
                sinceNotificationId,
                maxItems.Value,
                continuationToken,
                userNotificationStore).ConfigureAwait(false);

            await this.EnsureAllNotificationsMarkedAsDelivered(context, results).ConfigureAwait(false);

            HalDocument result = await this.userNotificationsMapper.MapAsync(
                results,
                new UserNotificationsMappingContext(context, userId, sinceNotificationId, maxItems.Value, continuationToken)).ConfigureAwait(false);

            return(this.OkResult(result));
        }
        public Task GivenIHaveCreatedAndStoredNotificationsWithTimestampsAtSecondIntervalsForTheUserWithId(int notificationCount, int interval, string userId)
        {
            IUserNotificationStore store = this.serviceProvider.GetRequiredService <IUserNotificationStore>();
            IPropertyBagFactory    propertyBagFactory = this.serviceProvider.GetRequiredService <IPropertyBagFactory>();

            DateTimeOffset timestamp = DateTimeOffset.UtcNow;
            var            offset    = TimeSpan.FromSeconds(interval);

            var tasks = new List <Task>();
            var propertiesDictionary = new Dictionary <string, object>
            {
                { "prop1", "val1" },
                { "prop2", 2 },
                { "prop3", DateTime.Now },
            };

            IPropertyBag properties = propertyBagFactory.Create(propertiesDictionary);

            for (int i = 0; i < notificationCount; i++)
            {
                string[] correlationIds = Enumerable.Range(0, 3).Select(_ => Guid.NewGuid().ToString()).ToArray();
                var      metadata       = new UserNotificationMetadata(correlationIds, null);
                tasks.Add(store.StoreAsync(new UserNotification(null, "marain.usernotifications.test", userId, timestamp, properties, metadata)));
                timestamp -= offset;
            }

            return(Task.WhenAll(tasks));
        }
        public async Task <OpenApiResult> GetNotificationAsync(
            IOpenApiContext context,
            string notificationId)
        {
            // We can guarantee tenant Id is available because it's part of the Uri.
            ITenant tenant = await this.marainServicesTenancy.GetRequestingTenantAsync(context.CurrentTenantId !).ConfigureAwait(false);

            IUserNotificationStore userNotificationStore =
                await this.userNotificationStoreFactory.GetUserNotificationStoreForTenantAsync(tenant).ConfigureAwait(false);

            UserNotification notifications;

            try
            {
                notifications = await userNotificationStore.GetByIdAsync(notificationId).ConfigureAwait(false);
            }
            catch (ArgumentException)
            {
                // This will happen if the supplied notification Id is invalid. Return a BadRequest response.
                throw new OpenApiBadRequestException("The supplied notificationId is not valid");
            }

            HalDocument response = await this.userNotificationMapper.MapAsync(notifications, context).ConfigureAwait(false);

            return(this.OkResult(response, "application/json"));
        }
        public async Task WhenIAskTheUserNotificationStoreForNotificationsUsingTheContinuationTokenFromTheResultCalledAndCallTheResult(string userId, string previousResultName, string newResultName)
        {
            IUserNotificationStore store          = this.serviceProvider.GetRequiredService <IUserNotificationStore>();
            GetNotificationsResult previousResult = this.scenarioContext.Get <GetNotificationsResult>(previousResultName);
            GetNotificationsResult result         = await store.GetAsync(userId, previousResult.ContinuationToken !).ConfigureAwait(false);

            this.scenarioContext.Set(result, newResultName);
        }
        public async Task WhenITellTheUserNotificationStoreToStoreTheUserNotificationCalled(string notificationName, string resultName)
        {
            IUserNotificationStore store        = this.serviceProvider.GetRequiredService <IUserNotificationStore>();
            UserNotification       notification = this.scenarioContext.Get <UserNotification>(notificationName);
            UserNotification       result       = await store.StoreAsync(notification).ConfigureAwait(false);

            this.scenarioContext.Set(result, resultName);
        }
Beispiel #12
0
        public WebChannel(IUserNotificationStore userNotificationStore, IStreamClient streamClient,
                          ILogger <WebChannel> log)
        {
            this.streamClient          = streamClient;
            this.userNotificationStore = userNotificationStore;

            this.log = log;
        }
        public async Task WhenIAskTheUserNotificationStoreForTheUserNotificationWithTheSameIdAsTheUserNotificationCalledAndCallIt(string notificationName, string resultName)
        {
            IUserNotificationStore store        = this.serviceProvider.GetRequiredService <IUserNotificationStore>();
            UserNotification       notification = this.scenarioContext.Get <UserNotification>(notificationName);
            UserNotification       result       = await store.GetByIdAsync(notification.Id !).ConfigureAwait(false);

            this.scenarioContext.Set(result, resultName);
        }
        public async Task WhenIAskTheUserNotificationStoreForNotificationsSinceTheFirstNotificationInTheResultsCalledForTheUserWithIdAndCallTheResult(int itemCount, string previousResultName, string userId, string newResultName)
        {
            IUserNotificationStore store          = this.serviceProvider.GetRequiredService <IUserNotificationStore>();
            GetNotificationsResult previousResult = this.scenarioContext.Get <GetNotificationsResult>(previousResultName);
            GetNotificationsResult result         = await store.GetAsync(userId, previousResult.Results[0].Id, itemCount).ConfigureAwait(false);

            this.scenarioContext.Set(result, newResultName);
        }
Beispiel #15
0
 public TrackingController(
     IAppStore appStore,
     IUserNotificationService userNotificationService,
     IUserNotificationStore userNotificationStore)
 {
     this.appStore = appStore;
     this.userNotificationService = userNotificationService;
     this.userNotificationStore   = userNotificationStore;
 }
Beispiel #16
0
 public WebhookChannel(IHttpClientFactory httpClientFactory, ISemanticLog log, ILogStore logStore,
                       IUserNotificationQueue userNotificationQueue,
                       IUserNotificationStore userNotificationStore)
 {
     this.httpClientFactory = httpClientFactory;
     this.log      = log;
     this.logStore = logStore;
     this.userNotificationQueue = userNotificationQueue;
     this.userNotificationStore = userNotificationStore;
 }
        public async Task GivenIHaveCreatedAndStoredANotificationInTheCurrentTransientTenantAndCalledTheResult(string resultName, Table table)
        {
            ITenantedUserNotificationStoreFactory storeFactory = this.serviceProvider.GetRequiredService <ITenantedUserNotificationStoreFactory>();
            IJsonSerializerSettingsProvider       serializerSettingsProvider = this.serviceProvider.GetRequiredService <IJsonSerializerSettingsProvider>();
            UserNotification       notification = BuildNotificationFrom(table.Rows[0], serializerSettingsProvider.Instance);
            IUserNotificationStore store        = await storeFactory.GetUserNotificationStoreForTenantAsync(this.featureContext.GetTransientTenant()).ConfigureAwait(false);

            UserNotification result = await store.StoreAsync(notification).ConfigureAwait(false);

            this.scenarioContext.Set(result, resultName);
        }
Beispiel #18
0
 public UsersController(
     IIntegrationManager integrationManager,
     IUserStore userStore,
     IUserNotificationStore userNotificationStore,
     ISubscriptionStore subscriptionStore)
 {
     this.integrationManager    = integrationManager;
     this.userStore             = userStore;
     this.userNotificationStore = userNotificationStore;
     this.subscriptionStore     = subscriptionStore;
 }
Beispiel #19
0
 public SmsChannel(ISemanticLog log, ILogStore logStore,
                   ISmsSender smsSender,
                   IUserNotificationQueue userNotificationQueue,
                   IUserNotificationStore userNotificationStore)
 {
     this.log                   = log;
     this.logStore              = logStore;
     this.smsSender             = smsSender;
     this.userNotificationQueue = userNotificationQueue;
     this.userNotificationStore = userNotificationStore;
 }
Beispiel #20
0
 public WebhookChannel(IHttpClientFactory httpClientFactory, ILogStore logStore,
                       IIntegrationManager integrationManager,
                       IUserNotificationQueue userNotificationQueue,
                       IUserNotificationStore userNotificationStore)
 {
     this.httpClientFactory     = httpClientFactory;
     this.logStore              = logStore;
     this.integrationManager    = integrationManager;
     this.userNotificationQueue = userNotificationQueue;
     this.userNotificationStore = userNotificationStore;
 }
 public MobilePushChannel(ISemanticLog log, ILogStore logStore,
                          IAppStore appStore,
                          IUserNotificationQueue userNotificationQueue,
                          IUserNotificationStore userNotificationStore,
                          IUserStore userStore)
 {
     this.appStore = appStore;
     this.log      = log;
     this.logStore = logStore;
     this.userNotificationQueue = userNotificationQueue;
     this.userNotificationStore = userNotificationStore;
     this.userStore             = userStore;
 }
Beispiel #22
0
        private async Task UpdateNotificationDeliveryStatusAsync(string deliveryChannelId, string notificationId, UserNotificationDeliveryStatus deliveryStatus, ITenant tenant, string?failureMessage = null)
        {
            IUserNotificationStore store = await this.notificationStoreFactory.GetUserNotificationStoreForTenantAsync(tenant).ConfigureAwait(false);

            UserNotification originalNotification = await store.GetByIdAsync(notificationId).ConfigureAwait(false);

            UserNotification modifiedNotification = originalNotification.WithChannelDeliveryStatus(
                deliveryChannelId,
                deliveryStatus,
                DateTimeOffset.UtcNow,
                failureMessage);

            await store.StoreAsync(modifiedNotification).ConfigureAwait(false);
        }
        public async Task WhenITellTheUserNotificationStoreToStoreTheUserNotificationCalledAndCallTheResult(string notificationName, string resultName)
        {
            IUserNotificationStore store        = this.serviceProvider.GetRequiredService <IUserNotificationStore>();
            UserNotification       notification = this.scenarioContext.Get <UserNotification>(notificationName);

            try
            {
                UserNotification result = await store.StoreAsync(notification).ConfigureAwait(false);

                this.scenarioContext.Set(result, resultName);
            }
            catch (Exception ex)
            {
                ExceptionSteps.StoreLastExceptionInScenarioContext(ex, this.scenarioContext);
            }
        }
Beispiel #24
0
 public MessagingChannel(ILogger <MessagingChannel> log, ILogStore logStore,
                         IAppStore appStore,
                         IIntegrationManager integrationManager,
                         IMessagingFormatter messagingFormatter,
                         IMessagingTemplateStore messagingTemplateStore,
                         IUserNotificationQueue userNotificationQueue,
                         IUserNotificationStore userNotificationStore)
 {
     this.appStore               = appStore;
     this.log                    = log;
     this.logStore               = logStore;
     this.integrationManager     = integrationManager;
     this.messagingFormatter     = messagingFormatter;
     this.messagingTemplateStore = messagingTemplateStore;
     this.userNotificationQueue  = userNotificationQueue;
     this.userNotificationStore  = userNotificationStore;
 }
Beispiel #25
0
 public MobilePushChannel(ILogger <MobilePushChannel> log, ILogStore logStore,
                          IAppStore appStore,
                          IIntegrationManager integrationManager,
                          IUserNotificationQueue userNotificationQueue,
                          IUserNotificationStore userNotificationStore,
                          IUserStore userStore,
                          IClock clock)
 {
     this.appStore              = appStore;
     this.log                   = log;
     this.logStore              = logStore;
     this.integrationManager    = integrationManager;
     this.userNotificationQueue = userNotificationQueue;
     this.userNotificationStore = userNotificationStore;
     this.userStore             = userStore;
     this.clock                 = clock;
 }
Beispiel #26
0
 public EmailChannel(ISemanticLog log, ILogStore logStore,
                     IAppStore appStore,
                     IEmailFormatter emailFormatter,
                     IEmailServer emailServer,
                     IUserNotificationQueue userNotificationQueue,
                     IUserNotificationStore userNotificationStore,
                     IUserStore userStore)
 {
     this.appStore              = appStore;
     this.emailFormatter        = emailFormatter;
     this.emailServer           = emailServer;
     this.log                   = log;
     this.logStore              = logStore;
     this.userNotificationQueue = userNotificationQueue;
     this.userNotificationStore = userNotificationStore;
     this.userStore             = userStore;
 }
Beispiel #27
0
 public SmsChannel(ILogger <SmsChannel> log, ILogStore logStore,
                   IAppStore appStore,
                   IIntegrationManager integrationManager,
                   ISmsFormatter smsFormatter,
                   ISmsTemplateStore smsTemplateStore,
                   IUserNotificationQueue userNotificationQueue,
                   IUserNotificationStore userNotificationStore)
 {
     this.appStore           = appStore;
     this.integrationManager = integrationManager;
     this.log                   = log;
     this.logStore              = logStore;
     this.smsFormatter          = smsFormatter;
     this.smsTemplateStore      = smsTemplateStore;
     this.userNotificationQueue = userNotificationQueue;
     this.userNotificationStore = userNotificationStore;
 }
 public UserNotificationService(IEnumerable <ICommunicationChannel> channels,
                                IAppStore appStore,
                                ILogStore logStore,
                                IUserEventQueue userEventQueue,
                                IUserNotificationFactory userNotificationFactory,
                                IUserNotificationStore userNotificationsStore,
                                IUserStore userStore,
                                IClock clock)
 {
     this.appStore                = appStore;
     this.channels                = channels;
     this.logStore                = logStore;
     this.userEventQueue          = userEventQueue;
     this.userNotificationFactory = userNotificationFactory;
     this.userNotificationsStore  = userNotificationsStore;
     this.userStore               = userStore;
     this.clock = clock;
 }
Beispiel #29
0
        public WebPushChannel(ILogStore logStore, IOptions <WebPushOptions> options,
                              IUserNotificationQueue userNotificationQueue,
                              IUserNotificationStore userNotificationStore,
                              IUserStore userStore,
                              IJsonSerializer serializer)
        {
            this.serializer            = serializer;
            this.userNotificationQueue = userNotificationQueue;
            this.userNotificationStore = userNotificationStore;
            this.userStore             = userStore;
            this.logStore = logStore;

            webPushClient.SetVapidDetails(
                options.Value.Subject,
                options.Value.VapidPublicKey,
                options.Value.VapidPrivateKey);

            PublicKey = options.Value.VapidPublicKey;
        }
Beispiel #30
0
 public EmailChannel(ILogger <EmailChannel> log, ILogStore logStore,
                     IAppStore appStore,
                     IIntegrationManager integrationManager,
                     IEmailFormatter emailFormatter,
                     IEmailTemplateStore emailTemplateStore,
                     IUserNotificationQueue userNotificationQueue,
                     IUserNotificationStore userNotificationStore,
                     IUserStore userStore)
 {
     this.appStore           = appStore;
     this.emailFormatter     = emailFormatter;
     this.emailTemplateStore = emailTemplateStore;
     this.log                   = log;
     this.logStore              = logStore;
     this.integrationManager    = integrationManager;
     this.userNotificationQueue = userNotificationQueue;
     this.userNotificationStore = userNotificationStore;
     this.userStore             = userStore;
 }