/// <summary> /// Run the mail synchronization service /// </summary> public void Run(object sender, EventArgs e, object[] parameters) { try { this.m_jobStateManager.SetState(this, JobStateType.Running); // We are to poll for alerts always (never push supported) var amiClient = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami")); using (this.GetCredentials(amiClient.Client, out Credentials credentials)) { amiClient.Client.Credentials = credentials; // When was the last time we polled an alert? var lastSync = this.m_synchronizationLogService.GetLastTime(typeof(MailMessage)); var syncTime = new DateTimeOffset(lastSync.GetValueOrDefault()); // Poll action for all alerts to "everyone" AmiCollection serverAlerts = amiClient.GetMailMessages(a => a.CreationTime >= syncTime && a.RcptTo.Any(o => o.UserName == "SYSTEM")); // SYSTEM WIDE ALERTS // TODO: We need to filter by users in which this tablet will be interested in ParameterExpression userParameter = Expression.Parameter(typeof(SecurityUser), "u"); // User name filter Expression userNameFilter = Expression.Equal(Expression.MakeMemberAccess(userParameter, userParameter.Type.GetRuntimeProperty("UserName")), Expression.Constant(this.m_securityConfiguration.DeviceName)); // Or eith other users which have logged into this tablet foreach (var user in ApplicationContext.Current.GetService <IDataPersistenceService <SecurityUser> >().Query(u => u.LastLoginTime != null && u.UserName != this.m_securityConfiguration.DeviceName, AuthenticationContext.SystemPrincipal)) { userNameFilter = Expression.OrElse(userNameFilter, Expression.Equal(Expression.MakeMemberAccess(userParameter, userParameter.Type.GetRuntimeProperty("UserName")), Expression.Constant(user.UserName)) ); } ParameterExpression parmExpr = Expression.Parameter(typeof(MailMessage), "a"); Expression timeExpression = Expression.GreaterThanOrEqual( Expression.Convert(Expression.MakeMemberAccess(parmExpr, parmExpr.Type.GetRuntimeProperty("CreationTime")), typeof(DateTimeOffset)), Expression.Constant(syncTime) ), // this tablet expression userExpression = Expression.Call( (MethodInfo)typeof(Enumerable).GetGenericMethod("Any", new Type[] { typeof(SecurityUser) }, new Type[] { typeof(IEnumerable <SecurityUser>), typeof(Func <SecurityUser, bool>) }), Expression.MakeMemberAccess(parmExpr, parmExpr.Type.GetRuntimeProperty("RcptTo")), Expression.Lambda <Func <SecurityUser, bool> >(userNameFilter, userParameter)); serverAlerts.CollectionItem = serverAlerts.CollectionItem.Union(amiClient.GetMailMessages(Expression.Lambda <Func <MailMessage, bool> >(Expression.AndAlso(timeExpression, userExpression), parmExpr)).CollectionItem).ToList(); // Import the alerts foreach (var itm in serverAlerts.CollectionItem.OfType <MailMessage>()) { this.m_tracer.TraceVerbose("Importing ALERT: [{0}]: {1}", itm.TimeStamp, itm.Subject); itm.Body = String.Format("<pre>{0}</pre>", itm.Body); this.m_mailRepository.Broadcast(itm); } this.m_synchronizationLogService.Save(typeof(MailMessage), String.Empty, String.Empty, "Mail", DateTime.Now); // Push alerts which I have created or updated //int tc = 0; //foreach(var itm in this.m_alertRepository.Find(a=> (a.TimeStamp >= lastTime ) && a.Flags != AlertMessageFlags.System, 0, null, out tc)) //{ // if (!String.IsNullOrEmpty(itm.To)) // { // this.m_tracer.TraceVerbose("Sending ALERT: [{0}]: {1}", itm.TimeStamp, itm.Subject); // if (itm.UpdatedTime != null) // amiClient.UpdateAlert(itm.Key.ToString(), new AlertMessageInfo(itm)); // else // amiClient.CreateAlert(new AlertMessageInfo(itm)); // } //} this.m_jobStateManager.SetState(this, JobStateType.Completed); } } catch (Exception ex) { this.m_tracer.TraceError("Could not pull alerts: {0}", ex.Message); this.m_jobStateManager.SetState(this, JobStateType.Aborted); this.m_jobStateManager.SetProgress(this, ex.Message, 0.0f); } }