private JobStatus CreateJobStatus(CloudQueueMessage message)
 {
     return(new JobStatus
     {
         QueueName = QueueProxy.GetQueue().Name,
         MessageId = message.Id,
         Success = true,
         RunDateTime = DateTime.UtcNow,
         Message = message.AsString
     });
 }
 /// <summary>
 /// Starts the worker task.
 /// </summary>
 public override void OnStart()
 {
     QueueProxy.GetQueue().CreateIfNotExists();
     base.OnStart(); //start timers
 }
        /// <summary>
        /// Continues processing after the waiting period has elapsed.
        /// </summary>
        public override IterationResult OnWaitingPeriodElapsedAdvanced()
        {
            var queue = QueueProxy.GetQueue();

            while (IsRunning)
            {
                CloudQueueMessage message = null;
                try
                {
                    CheckIn();
                    message = queue.GetMessage();
                    if (message == null)
                    {
                        return(new IterationResult());
                    }

                    var statEntity = MessageStatusTableProxy.Get(queue.Name.GetValidPartitionKey(),
                                                                 string.Format("M|{0}|S|{1}", message.Id, false));
                    var status = statEntity != null && statEntity.Entity != null
                        ? statEntity.Entity
                        : CreateJobStatus(message);

                    if (MessageFailedSkipSeconds > double.Epsilon &&
                        !status.Success &&
                        status.RunDateTime > DateTime.UtcNow.AddSeconds(-1 * MessageFailedSkipSeconds))
                    {   //do this here in case it was long running on error, so we dequeue it one extra time before hiding it.
                        var hideDuration = (DateTime.UtcNow - status.RunDateTime.AddSeconds(MessageFailedSkipSeconds)).Duration();
                        queue.UpdateMessage(message, hideDuration, MessageUpdateFields.Visibility);
                        continue; //skip this message temporarily and continue with the next.
                    }

                    //this lets us know the processing has started.
                    StatusLatestTableProxy.InsertOrUpdate(status);

                    CheckIn();
                    var result = ProcessMessageAdvanced(message, status);
                    CheckIn();
                    status.Success     = result.Success;
                    status.RunDateTime = DateTime.UtcNow;
                    if (status.Success)
                    {
                        queue.DeleteMessage(message);
                    }
                    else //log status record for failed processing
                    {
                        //record every failure by date/time
                        StatusTableProxy.InsertOrUpdate(status);
                        //in another table, record latest failure only for each message.
                        MessageStatusTableProxy.InsertOrUpdate(status);
                    }

                    //always update latest status for this queue
                    StatusLatestTableProxy.InsertOrUpdate(status);

                    if (result.DelayNextMessageSeconds > Double.Epsilon)
                    {
                        return new IterationResult {
                                   NextWaitingPeriodSeconds = result.DelayNextMessageSeconds
                        }
                    }
                    ;
                }
                catch (OperationCanceledException e)
                {
                    if (!IsRunning)
                    {
                        continue;
                    }
                    LogProvider.Info(e.Message);
                    throw;
                }
                catch (Exception ex)
                {
                    LogProvider.Error("Unhandled exception.", ex);
                    if (message == null)
                    {
                        continue;
                    }
                    var errorStatus = CreateJobStatus(message);
                    errorStatus.Success    = false;
                    errorStatus.LogMessage = ex.ToString();
                    MessageStatusTableProxy.InsertOrUpdate(errorStatus);
                }
            }
            return(new IterationResult());
        }
Example #4
0
        /// <summary>
        /// Processes a notification queue and sends the notification email.
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public override bool ProcessMessage(CloudQueueMessage message)
        {
            var change = QueueProxy.DeserializeRecordChangeNotification(message);

            var msg = new MailMessage();

            msg.To.Add(change.PartitionKey);
            msg.From       = new MailAddress(FromAddress, FromAddress);
            msg.IsBodyHtml = true;
            msg.Priority   = MailPriority.Normal;

            var user = ProviderResolver <UserProvider> .Get.Provider.GetUserByName(change.PartitionKey);

            var emailAddress = change.PartitionKey;

            try
            {
                if (user == null)
                {
                    msg.Subject = "Temporary Password - No Account found";
                    var template = _razorMachine.ExecuteUrl("~/Account/ForgotPasswordNoUser",
                                                            new { UserName = emailAddress });
                    msg.Body = template.Result;
                    if (string.IsNullOrWhiteSpace(msg.Body))
                    {
                        LogProvider.Error("No email body generated for /Views/Account/ForgotPasswordNoUser.cshtml");
                        return(true); //this is very likely on purpose.
                    }
                }
                else
                {
                    var resetCode = ProviderResolver <UserProvider> .Get.Provider.GenerateUserResetCode(emailAddress);

                    user.PasswordHash = resetCode;
                    msg.Subject       = "Temporary Password";
                    var template = _razorMachine.ExecuteUrl("~/Account/ForgotPassword", user);
                    msg.Body = template.Result;
                    if (string.IsNullOrWhiteSpace(msg.Body))
                    {
                        LogProvider.Error("No email body generated for /Views/Account/ForgotPassword.cshtml");
                        return(false);
                    }
                }
            }
            catch (Exception exBody)
            {
                LogProvider.ErrorFormat("Failed to generate body for password reset to email to address '{0}'; User:{1};", exBody,
                                        emailAddress, user != null);
                return(false);
            }

            var client = new SmtpClient {
                Host = SmtpServer, Port = Port
            };

            if (SmtpUserName.Length > 0)
            {
                client.Credentials = new NetworkCredential(SmtpUserName, SmtpPassword);
            }

            // try to send Mail
            try
            {
                client.Send(msg);
                return(true);
            }
            catch (Exception ex)
            {
                LogProvider.ErrorFormat("Failed to send password reset to email to address '{0}'; User:{1}", ex,
                                        emailAddress, user != null);
                return(false);
            }
        }