Beispiel #1
0
        public async Task SendNotification(NotificationScope scope, BaseNotification notification)
        {
            if (scope == null)
            {
                throw new ArgumentNullException(nameof(scope));
            }
            if (notification == null)
            {
                throw new ArgumentNullException(nameof(notification));
            }
            var users = await GetUsers(scope);

            using (var db = _contextFactory.CreateContext())
            {
                foreach (var uid in users)
                {
                    var obj  = JsonConvert.SerializeObject(notification);
                    var data = new NotificationData
                    {
                        Id                = Guid.NewGuid().ToString(),
                        Created           = DateTimeOffset.UtcNow,
                        ApplicationUserId = uid,
                        NotificationType  = GetNotificationTypeString(notification.GetType()),
                        Blob              = ZipUtils.Zip(obj),
                        Seen              = false
                    };
                    db.Notifications.Add(data);
                }

                await db.SaveChangesAsync();
            }
        }
Beispiel #2
0
        public async Task SendNotification(NotificationScope scope, BaseNotification notification)
        {
            ArgumentNullException.ThrowIfNull(scope);
            ArgumentNullException.ThrowIfNull(notification);
            var users = await GetUsers(scope, notification.Identifier);

            await using (var db = _contextFactory.CreateContext())
            {
                foreach (var uid in users)
                {
                    var obj  = JsonConvert.SerializeObject(notification);
                    var data = new NotificationData
                    {
                        Id                = Guid.NewGuid().ToString(),
                        Created           = DateTimeOffset.UtcNow,
                        ApplicationUserId = uid,
                        NotificationType  = notification.NotificationType,
                        Blob              = ZipUtils.Zip(obj),
                        Seen              = false
                    };
                    await db.Notifications.AddAsync(data);
                }
                await db.SaveChangesAsync();
            }
            foreach (string user in users)
            {
                _notificationManager.InvalidateNotificationCache(user);
            }
        }
Beispiel #3
0
        private IEnumerator AddNotification(int lines, NotificationScope scope)
        {
            string message = string.Join("\n", Enumerable.Range(0, lines).Select(i => "asdf" + i));

            NotificationBox.Add(new Notification()
            {
                Message = message,
                Type    = GetNotificationType(),
                Scope   = scope,
            });
            yield break;
        }
Beispiel #4
0
        private async Task <string[]> GetUsers(NotificationScope scope, string notificationIdentifier)
        {
            await using var ctx = _contextFactory.CreateContext();

            var split = notificationIdentifier.Split('_', StringSplitOptions.None);
            var terms = new List <string>();

            foreach (var t in split)
            {
                terms.Add(terms.Any() ? $"{terms.Last().TrimEnd(';')}_{t};" : $"{t};");
            }
            IQueryable <ApplicationUser> query;

            switch (scope)
            {
            case AdminScope _:
            {
                query = _userManager.GetUsersInRoleAsync(Roles.ServerAdmin).Result.AsQueryable();

                break;
            }

            case StoreScope s:
                query = ctx.UserStore
                        .Include(store => store.ApplicationUser)
                        .Where(u => u.StoreDataId == s.StoreId)
                        .Select(u => u.ApplicationUser);
                break;

            case UserScope userScope:
                query = ctx.Users
                        .Where(user => user.Id == userScope.UserId);
                break;

            default:
                throw new NotSupportedException("Notification scope not supported");
            }
            query = query.Where(store => store.DisabledNotifications != "all");
            foreach (string term in terms)
            {
                // Cannot specify StringComparison as EF core does not support it and would attempt client-side evaluation
                // ReSharper disable once CA1307
#pragma warning disable CA1307 // Specify StringComparison
                query = query.Where(user => user.DisabledNotifications == null || !user.DisabledNotifications.Contains(term));
#pragma warning restore CA1307 // Specify StringComparison
            }

            return(query.Select(user => user.Id).ToArray());
        }
Beispiel #5
0
        private async Task <string[]> GetUsers(NotificationScope scope)
        {
            if (scope is AdminScope)
            {
                var admins = await _userManager.GetUsersInRoleAsync(Roles.ServerAdmin);

                return(admins.Select(a => a.Id).ToArray());
            }
            if (scope is StoreScope s)
            {
                using var ctx = _contextFactory.CreateContext();
                return(ctx.UserStore
                       .Where(u => u.StoreDataId == s.StoreId)
                       .Select(u => u.ApplicationUserId)
                       .ToArray());
            }
            throw new NotSupportedException("Notification scope not supported");
        }
        public static void Send(Notification notification, NotificationScope scope)
        {
            // test inputs
            //Validate.IsNotNull<ArgumentNullException>(notification, "Must pass a valid notification");

            // adds the sender (current named instance of NB) to the notification
            // to find out that a certain notification was sent by yourself!
            if (string.IsNullOrEmpty(notification.Sender))
            {
                // only the initial sender is important. Do not overwrite by intermediary service callback
                // implementations calling this Send() too.
                notification.Sender = Id;
            }

            // fire locally. Get a copied list of subscription references.
            lock (subscriptions)
            {
                IList <Subscription> copiedSubscriptions = subscriptions.Get(notification.GetType());
                foreach (Subscription subscription in copiedSubscriptions)
                {
                    try
                    {
                        // fire when no filter specified
                        if (subscription.Filters == null)
                        {
                            SendAsync(subscription, notification, scope);
                            continue;
                        }
                        if (subscription.Filters.Count == 0)
                        {
                            SendAsync(subscription, notification, scope);
                            continue;
                        }

                        // fire when one of the filters evaluates to true
                        bool filterIncluded = true;
                        bool filterExcluded = false;
                        foreach (ISubscriptionFilter subscriptionFilter in subscription.Filters)
                        {
                            // fire when one (and only when; not and/or logic) filter include evaluates true
                            if (subscriptionFilter.FilterOperation == SubscriptionFilterOperation.Include &&
                                !subscriptionFilter.IsMatch(notification))
                            {
                                filterIncluded = false;                     // filter out
                            }
                            // however, does not fire when one (and only when; not and/or logic) filter exclude evaluates true
                            if (subscriptionFilter.FilterOperation == SubscriptionFilterOperation.Exclude &&
                                subscriptionFilter.IsMatch(notification))
                            {
                                filterExcluded = true;                      // filter out
                            }

                            if (filterIncluded && !filterExcluded)
                            {
                                SendAsync(subscription, notification, scope);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.Warn("One of the subscription handler invocations failed.", ex);
                    }
                }
            }
        }
 private static void SendAsync(Subscription subscription, Notification notification, NotificationScope scope)
 {
     if (subscription.Scope == scope || scope == NotificationScope.Remote)
     {
         // go to another thread to execute delegate!
         ThreadPool.QueueUserWorkItem(
             delegate(object state)
         {
             try
             {
                 // invoke one separate invocation handler on pool thread to decouple.
                 subscription.Send(notification);
             }
             catch (Exception ex)
             {
                 logger.Warn(string.Format(CultureInfo.InvariantCulture, "{0} subscription handler {1} invocations failed.", subscription.Scope, subscription.NotificationType.FullName), ex);
             }
         }, null);
     }
 }