Exemple #1
0
        private static MailboxState GetMailboxState(MailBoxData mailbox, ILog log)
        {
            try
            {
                log.Debug("GetMailBoxState()");

                var engine = new EngineFactory(-1);
                var status = engine.MailboxEngine.GetMailboxStatus(new СoncreteUserMailboxExp(mailbox.MailBoxId, mailbox.TenantId, mailbox.UserId));

                if (mailbox.BeginDate != status.BeginDate)
                {
                    mailbox.BeginDateChanged = true;
                    mailbox.BeginDate        = status.BeginDate;

                    return(MailboxState.DateChanged);
                }

                if (status.IsRemoved)
                {
                    return(MailboxState.Deleted);
                }

                if (!status.Enabled)
                {
                    return(MailboxState.Disabled);
                }
            }
            catch (Exception exGetMbInfo)
            {
                log.InfoFormat("GetMailBoxState(Tenant = {0}, MailboxId = {1}, Address = '{2}') Exception: {3}",
                               mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail, exGetMbInfo.Message);
            }

            return(MailboxState.NoChanges);
        }
Exemple #2
0
        private void NotifySignalrIfNeed(MailBoxData mailbox, ILog log)
        {
            if (!_tasksConfig.EnableSignalr)
            {
                log.Debug("Skip NotifySignalrIfNeed: EnableSignalr == false");

                return;
            }

            var now = DateTime.UtcNow;

            try
            {
                if (mailbox.LastSignalrNotify.HasValue &&
                    !((now - mailbox.LastSignalrNotify.Value).TotalSeconds > SIGNALR_WAIT_SECONDS))
                {
                    mailbox.LastSignalrNotifySkipped = true;

                    log.InfoFormat(
                        "Skip NotifySignalrIfNeed: last notification has occurend less then {0} seconds ago",
                        SIGNALR_WAIT_SECONDS);

                    return;
                }

                if (_signalrWorker == null)
                {
                    throw new NullReferenceException("_signalrWorker");
                }

                _signalrWorker.AddMailbox(mailbox);

                log.InfoFormat("NotifySignalrIfNeed(UserId = {0} TenantId = {1}) has been succeeded",
                               mailbox.UserId, mailbox.TenantId);
            }
            catch (Exception ex)
            {
                log.ErrorFormat("NotifySignalrIfNeed(UserId = {0} TenantId = {1}) Exception: {2}", mailbox.UserId,
                                mailbox.TenantId, ex.ToString());
            }

            mailbox.LastSignalrNotify        = now;
            mailbox.LastSignalrNotifySkipped = false;
        }
Exemple #3
0
        private void DoOptionalOperations(MailMessageData message, MimeMessage mimeMessage, MailBoxData mailbox, MailFolder folder, ILog log)
        {
            var factory = new EngineFactory(mailbox.TenantId, mailbox.UserId, log);

            var tagIds = new List <int>();

            if (folder.Tags.Any())
            {
                log.Debug("DoOptionalOperations->GetOrCreateTags()");

                tagIds = factory.TagEngine.GetOrCreateTags(mailbox.TenantId, mailbox.UserId, folder.Tags);
            }

            log.Debug("DoOptionalOperations->IsCrmAvailable()");

            if (IsCrmAvailable(mailbox, log))
            {
                log.Debug("DoOptionalOperations->GetCrmTags()");

                var crmTagIds = factory.TagEngine.GetCrmTags(message.FromEmail);

                if (crmTagIds.Any())
                {
                    if (tagIds == null)
                    {
                        tagIds = new List <int>();
                    }

                    tagIds.AddRange(crmTagIds.Select(t => t.Id));
                }
            }

            if (tagIds.Any())
            {
                if (message.TagIds == null || !message.TagIds.Any())
                {
                    message.TagIds = tagIds;
                }
                else
                {
                    message.TagIds.AddRange(tagIds);
                }

                message.TagIds = message.TagIds.Distinct().ToList();
            }

            log.Debug("DoOptionalOperations->AddMessageToIndex()");

            var wrapper = message.ToMailWrapper(mailbox.TenantId, new Guid(mailbox.UserId));

            factory.IndexEngine.Add(wrapper);

            foreach (var tagId in tagIds)
            {
                try
                {
                    log.DebugFormat("DoOptionalOperations->SetMessagesTag(tagId: {0})", tagId);

                    factory.TagEngine.SetMessagesTag(new List <int> {
                        message.Id
                    }, tagId);
                }
                catch (Exception e)
                {
                    log.ErrorFormat(
                        "SetMessagesTag(tenant={0}, userId='{1}', messageId={2}, tagid = {3}) Exception:\r\n{4}\r\n",
                        mailbox.TenantId, mailbox.UserId, message.Id, e.ToString(),
                        tagIds != null ? string.Join(",", tagIds) : "null");
                }
            }

            log.Debug("DoOptionalOperations->AddRelationshipEventForLinkedAccounts()");

            factory.CrmLinkEngine.AddRelationshipEventForLinkedAccounts(mailbox, message, _tasksConfig.DefaultApiSchema);

            log.Debug("DoOptionalOperations->SaveEmailInData()");

            factory.EmailInEngine.SaveEmailInData(mailbox, message, _tasksConfig.DefaultApiSchema);

            log.Debug("DoOptionalOperations->SendAutoreply()");

            factory.AutoreplyEngine.SendAutoreply(mailbox, message, _tasksConfig.DefaultApiSchema, log);

            log.Debug("DoOptionalOperations->UploadIcsToCalendar()");

            factory
            .CalendarEngine
            .UploadIcsToCalendar(mailbox, message.CalendarId, message.CalendarUid, message.CalendarEventIcs,
                                 message.CalendarEventCharset, message.CalendarEventMimeType, mailbox.EMail.Address,
                                 _tasksConfig.DefaultApiSchema);

            if (_tasksConfig.SaveOriginalMessage)
            {
                log.Debug("DoOptionalOperations->StoreMailEml()");
                StoreMailEml(mailbox.TenantId, mailbox.UserId, message.StreamId, mimeMessage, log);
            }

            log.Debug("DoOptionalOperations->ApplyFilters()");

            var filters = GetFilters(factory, log);

            factory.FilterEngine.ApplyFilters(message, mailbox, folder, filters);

            log.Debug("DoOptionalOperations->NotifySignalrIfNeed()");

            NotifySignalrIfNeed(mailbox, log);
        }
Exemple #4
0
        private void workTimer_Elapsed(object state)
        {
            _log.Debug("Timer->workTimer_Elapsed");

            var cancelToken = state as CancellationToken? ?? new CancellationToken();

            try
            {
                if (_isFirstTime)
                {
                    _queueManager.LoadMailboxesFromDump();

                    if (_queueManager.ProcessingCount > 0)
                    {
                        _log.InfoFormat("Found {0} tasks to release", _queueManager.ProcessingCount);

                        _queueManager.ReleaseAllProcessingMailboxes();
                    }

                    _queueManager.LoadTenantsFromDump();

                    _isFirstTime = false;
                }

                if (cancelToken.IsCancellationRequested)
                {
                    _log.Debug("Timer->workTimer_Elapsed: IsCancellationRequested. Quit.");
                    return;
                }

                if (_workTimer == null)
                {
                    _log.Debug("Timer->workTimer_Elapsed: _workTimer == null. Quit.");
                    OnStop();
                    return;
                }

                StopTimer();

                var tasks = CreateTasks(_tasksConfig.MaxTasksAtOnce, cancelToken);

                // ***Add a loop to process the tasks one at a time until none remain.
                while (tasks.Any())
                {
                    // Identify the first task that completes.
                    var indexTask = Task.WaitAny(tasks.Select(t => t.Task).ToArray(), (int)_tsTaskStateCheckInterval.TotalMilliseconds, cancelToken);
                    if (indexTask > -1)
                    {
                        // ***Remove the selected task from the list so that you don't
                        // process it more than once.
                        var outTask = tasks[indexTask];

                        FreeTask(outTask, tasks);
                    }
                    else
                    {
                        _log.InfoFormat("Task.WaitAny timeout. Tasks count = {0}\r\nTasks:\r\n{1}", tasks.Count,
                                        string.Join("\r\n",
                                                    tasks.Select(
                                                        t =>
                                                        string.Format("Id: {0} Status: {1}, MailboxId: {2} Address: '{3}'",
                                                                      t.Task.Id, t.Task.Status, t.Mailbox.MailBoxId, t.Mailbox.EMail))));
                    }

                    var tasks2Free =
                        tasks.Where(
                            t =>
                            t.Task.Status == TaskStatus.Canceled || t.Task.Status == TaskStatus.Faulted ||
                            t.Task.Status == TaskStatus.RanToCompletion).ToList();

                    if (tasks2Free.Any())
                    {
                        _log.InfoFormat("Need free next tasks = {0}: ({1})", tasks2Free.Count,
                                        string.Join(",",
                                                    tasks2Free.Select(t => t.Task.Id.ToString(CultureInfo.InvariantCulture))));

                        tasks2Free.ForEach(task => FreeTask(task, tasks));
                    }

                    var difference = _tasksConfig.MaxTasksAtOnce - tasks.Count;

                    if (difference <= 0)
                    {
                        continue;
                    }

                    var newTasks = CreateTasks(difference, cancelToken);

                    tasks.AddRange(newTasks);

                    _log.InfoFormat("Total tasks count = {0} ({1}).", tasks.Count,
                                    string.Join(",", tasks.Select(t => t.Task.Id)));
                }

                _log.Info("All mailboxes were processed. Go back to timer.");
            }
            catch (Exception ex)
            {
                if (ex is AggregateException)
                {
                    ex = ((AggregateException)ex).GetBaseException();
                }

                if (ex is TaskCanceledException || ex is OperationCanceledException)
                {
                    _log.Info("Execution was canceled.");

                    _queueManager.ReleaseAllProcessingMailboxes();

                    _queueManager.CancelHandler.Set();

                    return;
                }

                _log.ErrorFormat("Timer->workTimer_Elapsed. Exception:\r\n{0}\r\n", ex.ToString());

                if (_queueManager.ProcessingCount != 0)
                {
                    _queueManager.ReleaseAllProcessingMailboxes();
                }
            }

            _queueManager.CancelHandler.Set();

            StartTimer();
        }