示例#1
0
        protected void AddNotification(
            LastComponentNotification lastComponentNotification,
            StatusInfo statusInfo,
            Subscription subscription,
            AccountDbContext accountDbContext,
            NotificationReason reason)
        {
            var realEvent = accountDbContext.Events.Find(statusInfo.EventId);

            if (realEvent == null)
            {
                return;
            }

            Interlocked.Increment(ref CreatedNotificationsCount);

            var newNotification = new Notification()
            {
                Id             = Guid.NewGuid(),
                Address        = lastComponentNotification.Address,
                CreationDate   = Now(),
                EventId        = statusInfo.EventId,
                Status         = NotificationStatus.InQueue,
                SubscriptionId = subscription.Id,
                Type           = lastComponentNotification.Type,
                UserId         = subscription.UserId,
                Reason         = reason
            };

            if (newNotification.Type == NotificationType.Http)
            {
                newNotification.NotificationHttp = new NotificationHttp()
                {
                    Notification = newNotification
                                   //Json = GetNotificationJson(lastComponentNotification.Component, eventObj)
                };
            }

            var notificationRepository = accountDbContext.GetNotificationRepository();

            notificationRepository.Add(newNotification);

            lastComponentNotification.Update(newNotification, statusInfo.Importance);

            accountDbContext.SaveChanges();
        }
示例#2
0
        protected void ProcessAccountInternal(
            Guid accountId,
            User[] users,
            Dictionary <Guid, Subscription[]> userToSubscriptions,
            List <StatusInfo> statuses,
            AccountDbContext accountDbContext,
            ILogger logger)
        {
            var cancellationToken = DbProcessor.CancellationToken;

            // Обработаем каждый статус
            foreach (var status in statuses)
            {
                logger.Debug("Обрабатываем событие: " + status.EventId);

                cancellationToken.ThrowIfCancellationRequested();

                // Получим компонент
                var component = status.Component;
                if (component == null)
                {
                    logger.Trace("component == null");
                    continue;
                }

                // статус о выключенном компоненте мы должны получить, поэтому фильтр ниже закоментирован

                //if (component.Enable == false)
                //{
                //    if (isTraceEnabled)
                //    {
                //        log.Trace("component.Enable == false");
                //    }
                //    continue;
                //}

                // Пропускаем удалённые
                if (component.IsDeleted)
                {
                    logger.Trace("component.IsDeleted");
                    continue;
                }

                // Пропускаем удалённые
                if (component.IsRoot)
                {
                    logger.Trace("component.IsRoot");
                    continue;
                }

                // цикл по пользователям
                foreach (var user in users)
                {
                    var channels = new[]
                    {
                        SubscriptionChannel.Email,
                        SubscriptionChannel.Sms,
                        SubscriptionChannel.Http
                    };
                    if (userToSubscriptions.TryGetValue(user.Id, out var subscriptions))
                    {
                        foreach (var channel in channels)
                        {
                            var channelSubscriptions = subscriptions
                                                       .Where(x => x.Channel == channel)
                                                       .ToArray();

                            // ищем подписку на компонент
                            var subscription = channelSubscriptions.FirstOrDefault(x => x.ComponentId == status.ComponentId);
                            if (subscription == null)
                            {
                                // ищем подписку на тип события
                                subscription = channelSubscriptions.FirstOrDefault(x => x.ComponentTypeId == status.Component.ComponentTypeId);
                                if (subscription == null)
                                {
                                    // ищем дефолтную подписку
                                    subscription = channelSubscriptions.FirstOrDefault(x => x.Object == SubscriptionObject.Default);

                                    // если дефолтной для email канала нет, то создаем её
                                    if (subscription == null && channel == SubscriptionChannel.Email)
                                    {
                                        var dispatcherClient = AgentHelper.GetDispatcherClient();

                                        var response = dispatcherClient.CreateUserDefaultSubscription(
                                            accountId,
                                            new CreateUserDefaultSubscriptionRequestData()
                                        {
                                            Channel = channel,
                                            UserId  = user.Id
                                        });

                                        var repository = accountDbContext.GetSubscriptionRepository();
                                        subscription = repository.GetById(response.Data.Id);
                                    }
                                }
                            }

                            // проверим подписку
                            if (subscription != null)
                            {
                                logger.Trace("Проверяем подписку " + subscription.Id + ", событие " + status.EventId + " и компонент " + component.Id);

                                // если отправка запрещена
                                if (subscription.IsEnabled == false)
                                {
                                    logger.Trace("False by IsEnabled");
                                    continue;
                                }

                                // подписка шлет уведомления только по событиям, которые создались после создания подписки
                                if (status.CreateDate < subscription.LastUpdated)
                                {
                                    logger.Trace("False by LastUpdated");
                                    continue;
                                }

                                if (status.Category != EventCategory.ComponentExternalStatus)
                                {
                                    logger.Trace("False by Category");
                                    continue;
                                }

                                // минимальную длительность проверяем только у важных событий (цвет важности указывается пользователем в подписке)
                                if (subscription.DurationMinimumInSeconds.HasValue && status.Importance >= subscription.Importance)
                                {
                                    var eventDuration = (int)status.Duration.TotalSeconds;
                                    if (eventDuration < subscription.DurationMinimumInSeconds.Value)
                                    {
                                        logger.Trace("False by DurationMinimumInSeconds");
                                        continue;
                                    }
                                }

                                logger.Debug("Создаем уведомления для подписки: " + subscription.Id);
                                cancellationToken.ThrowIfCancellationRequested();

                                List <UserContact> contacts;

                                if (subscription.Channel == SubscriptionChannel.Email)
                                {
                                    contacts = GetUserEMailContacts(subscription.User);
                                }
                                else if (subscription.Channel == SubscriptionChannel.Sms)
                                {
                                    contacts = GetUserMobileContacts(subscription.User);
                                }
                                else if (subscription.Channel == SubscriptionChannel.Http)
                                {
                                    contacts = GetUserHttpContacts(subscription.User);
                                }
                                else
                                {
                                    contacts = new List <UserContact>();
                                }

                                logger.Debug("Адресов для уведомлений " + contacts.Count);

                                foreach (var contact in contacts)
                                {
                                    // Уведомления создаются только по контактам, добавленным до наступления события
                                    if (contact.CreateDate > status.CreateDate)
                                    {
                                        continue;
                                    }

                                    var address = contact.Value;
                                    logger.Debug("Создаём уведомление на адрес: " + address);

                                    NotificationType notificationType;
                                    if (contact.Type == UserContactType.Email)
                                    {
                                        notificationType = NotificationType.Email;
                                    }
                                    else if (contact.Type == UserContactType.MobilePhone)
                                    {
                                        notificationType = NotificationType.Sms;
                                    }
                                    else if (contact.Type == UserContactType.Http)
                                    {
                                        notificationType = NotificationType.Http;
                                    }
                                    else
                                    {
                                        logger.Debug("Неизвестный тип контакта: " + contact.Type);
                                        continue;
                                    }

                                    var lastComponentNotification = component.LastNotifications.FirstOrDefault(
                                        x => x.Address == address && x.Type == notificationType);

                                    var isImportanceColor = status.Importance >= subscription.Importance;

                                    // важный статус
                                    if (isImportanceColor)
                                    {
                                        // первое уведомление о важном статусе
                                        if (lastComponentNotification == null)
                                        {
                                            logger.Info("Первое уведомление на адрес " + address + " для компонента " + component.Id);
                                            lastComponentNotification = new LastComponentNotification()
                                            {
                                                Id              = Guid.NewGuid(),
                                                Address         = address,
                                                Component       = component,
                                                ComponentId     = component.Id,
                                                CreateDate      = Now(),
                                                EventId         = status.EventId,
                                                EventImportance = status.Importance,
                                                Type            = notificationType,
                                                NotificationId  = Guid.Empty
                                            };
                                            component.LastNotifications.Add(lastComponentNotification);

                                            AddNotification(
                                                lastComponentNotification,
                                                status,
                                                subscription,
                                                accountDbContext,
                                                NotificationReason.NewImportanceStatus);

                                            continue;
                                        }

                                        // тот же важный статус
                                        if (lastComponentNotification.EventId == status.EventId)
                                        {
                                            if (subscription.ResendTimeInSeconds > 0)
                                            {
                                                // Проверим, нужно ли отправлять повторное уведомление
                                                var notifyDuration = (int)(Now() - lastComponentNotification.CreateDate).TotalSeconds;

                                                if (notifyDuration >= subscription.ResendTimeInSeconds)
                                                {
                                                    logger.Info("Напоминание о статусе " + status.EventId + " на адрес " + address);

                                                    AddNotification(
                                                        lastComponentNotification,
                                                        status,
                                                        subscription,
                                                        accountDbContext,
                                                        NotificationReason.Reminder);

                                                    continue;
                                                }
                                            }
                                            logger.Debug("Уже есть уведомление о событии " + status.EventId + " на адрес " + address);
                                        }
                                        else // новый важный статус
                                        {
                                            logger.Info("Новый важный статус " + status.EventId + " на адрес " + address);

                                            AddNotification(
                                                lastComponentNotification,
                                                status,
                                                subscription,
                                                accountDbContext,
                                                NotificationReason.NewImportanceStatus);
                                        }
                                    }
                                    else // НЕ важное событие
                                    {
                                        if (lastComponentNotification != null &&
                                            subscription.NotifyBetterStatus &&
                                            lastComponentNotification.EventImportance >= subscription.Importance)
                                        {
                                            logger.Info("Уведомление о том, что стало лучше " + status.EventId + " на адрес " + address);

                                            AddNotification(
                                                lastComponentNotification,
                                                status,
                                                subscription,
                                                accountDbContext,
                                                NotificationReason.BetterStatus);
                                        }
                                        else
                                        {
                                            //log.Debug("Не отправляем уведомление об улучшении "+ status.EventId + " на адрес " + address);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        // у пользователя нет ни одной подписки
                        var dispatcherClient = AgentHelper.GetDispatcherClient();
                        var response         = dispatcherClient.CreateUserDefaultSubscription(accountId,
                                                                                              new CreateUserDefaultSubscriptionRequestData()
                        {
                            Channel = SubscriptionChannel.Email,
                            UserId  = user.Id
                        });
                        response.Check();
                    }
                }
            }
        }