public void ScheduleEmailForSendingLaterIsPaused() { var scheduleEmailForSendingLater = new ScheduleEmailForSendingLater { SendMessageAtUtc = DateTime.Now.AddDays(1), ScheduleMessageId = Guid.NewGuid(), EmailData = new EmailData() }; var sagaId = Guid.NewGuid(); var scheduledEmailData = new ScheduledEmailData { Id = sagaId, Originator = "place", OriginalMessageId = "one", OriginalMessageData = new OriginalEmailMessageData(new ScheduleEmailForSendingLater { EmailData = scheduleEmailForSendingLater.EmailData }) }; Test.Initialize(); Test.Saga <EmailScheduler>() .WithExternalDependencies(a => { a.Data = scheduledEmailData; }) .ExpectTimeoutToBeSetAt <ScheduleEmailTimeout>((state, timeout) => timeout == scheduleEmailForSendingLater.SendMessageAtUtc) .ExpectSendLocal <EmailScheduleCreated>() .When(s => s.Handle(scheduleEmailForSendingLater)) .ExpectPublish <MessageSchedulePaused>() .ExpectSendLocal <ScheduleStatusChanged>(s => s.Status == MessageStatus.Paused) .When(s => s.Handle(new PauseScheduledMessageIndefinitely(Guid.Empty))) .ExpectNotSend <SendOneEmailNow>(now => false) .WhenSagaTimesOut(); }
public void Handle(ScheduleEmailForSendingLater message) { Data.OriginalMessageData = new OriginalEmailMessageData(message); Data.ScheduleMessageId = message.ScheduleMessageId == Guid.NewGuid() ? Data.Id : message.ScheduleMessageId; Data.TimeoutCounter = 0; var timeout = new DateTime(message.SendMessageAtUtc.Ticks, DateTimeKind.Utc); RequestUtcTimeout(timeout, new ScheduleEmailTimeout { TimeoutCounter = 0 }); // TODO: Save coordinator id Bus.SendLocal(new EmailScheduleCreated { CorrelationId = message.CorrelationId, ScheduleId = Data.ScheduleMessageId, ScheduleTimeUtc = message.SendMessageAtUtc, EmailData = message.EmailData, Topic = message.Topic, Tags = message.Tags }); Bus.Publish(new EmailScheduled { ScheduleMessageId = Data.ScheduleMessageId, CoordinatorId = message.CorrelationId, EmailData = message.EmailData, Topic = message.Topic, Tags = message.Tags, ScheduleSendingTimeUtc = message.SendMessageAtUtc, Username = message.Username }); }
public void ScheduleEmailForSendingLaterFails() { var scheduleEmailForSendingLater = new ScheduleEmailForSendingLater { SendMessageAtUtc = DateTime.Now.AddDays(1), ScheduleMessageId = Guid.NewGuid(), EmailData = new EmailData() }; var sagaId = Guid.NewGuid(); var scheduledEmailData = new ScheduledEmailData { Id = sagaId, Originator = "place", OriginalMessageId = Guid.NewGuid().ToString(), OriginalMessageData = new OriginalEmailMessageData(new ScheduleEmailForSendingLater { EmailData = scheduleEmailForSendingLater.EmailData }) }; Test.Initialize(); Test.Saga <EmailScheduler>() .WithExternalDependencies(a => { a.Data = scheduledEmailData; }) .ExpectTimeoutToBeSetAt <ScheduleEmailTimeout>((state, timeout) => timeout == scheduleEmailForSendingLater.SendMessageAtUtc) .When(s => s.Handle(scheduleEmailForSendingLater)) .ExpectSendToDestination <SendOneEmailNow>((m, d) => d.Queue == "smsactioner") .WhenSagaTimesOut() .ExpectPublish <ScheduledEmailFailed>() .ExpectSendLocal <ScheduleStatusChanged>(s => s.Status == MessageStatus.Failed) .When(s => s.Handle(new EmailStatusUpdate { Status = EmailStatus.Failed })) .AssertSagaCompletionIs(true); }
public void EmailStatusUpdate_EmailIsComplained_ReplyFailed() { const EmailStatus emailStatus = EmailStatus.Complained; var emailData = new EmailData { ToAddress = "toaddress" }; var requestMessage = new ScheduleEmailForSendingLater(DateTime.Now.AddMinutes(5), emailData, new SmsMetaData(), Guid.NewGuid(), "username"); var data = new ScheduledEmailData { ScheduleMessageId = requestMessage.CorrelationId, OriginalMessageData = new OriginalEmailMessageData(requestMessage) }; var emailStatusUpdate = new EmailStatusUpdate { Status = emailStatus }; Test.Initialize(); Test.Saga <EmailScheduler>() .WithExternalDependencies(a => { a.Data = data; }) .WhenReceivesMessageFrom("address") .ExpectPublish <ScheduledEmailFailed>(m => m.CoordinatorId == requestMessage.CorrelationId && m.EmailStatus == emailStatus && m.ScheduledSmsId == data.ScheduleMessageId && m.ToAddress == emailData.ToAddress && m.Username == requestMessage.Username) .ExpectSendLocal <ScheduleStatusChanged>(s => s.Status == MessageStatus.Failed && s.ScheduleId == data.ScheduleMessageId) .When(s => s.Handle(emailStatusUpdate)) .AssertSagaCompletionIs(true); }
public void EmailStatusUpdate_EmailIsDelivered_SetsTimeoutForFurtherInformation_TimeoutExpires_PublishSuccess() { const EmailStatus emailStatus = EmailStatus.Delivered; var emailData = new EmailData { ToAddress = "toaddress" }; var requestMessage = new ScheduleEmailForSendingLater(DateTime.Now.AddMinutes(5), emailData, new SmsMetaData(), Guid.NewGuid(), "username"); var data = new ScheduledEmailData { ScheduleMessageId = requestMessage.CorrelationId, OriginalMessageData = new OriginalEmailMessageData(requestMessage) }; var emailStatusUpdate = new EmailStatusUpdate { Status = emailStatus }; Test.Initialize(); Test.Saga <EmailScheduler>() .WithExternalDependencies(a => { a.Data = data; }) .WhenReceivesMessageFrom("address") .ExpectTimeoutToBeSetIn <ScheduleEmailDeliveredTimeout>((message, timespan) => timespan.Ticks == new TimeSpan(1, 0, 0, 0).Ticks) .When(s => s.Handle(emailStatusUpdate)) .ExpectPublish <ScheduledEmailSent>(m => m.CoordinatorId == requestMessage.CorrelationId && m.EmailStatus == emailStatus && m.ScheduledSmsId == data.ScheduleMessageId && m.ToAddress == emailData.ToAddress && m.Username == requestMessage.Username) .ExpectSendLocal <ScheduleStatusChanged>(s => s.Status == MessageStatus.Sent && s.ScheduleId == data.ScheduleMessageId) .WhenSagaTimesOut() .AssertSagaCompletionIs(true); }
public void ScheduleEmailForSendingLaterButIsPausedThenResumedOutOfOrderAndSent() { var scheduleEmailForSendingLater = new ScheduleEmailForSendingLater { SendMessageAtUtc = DateTime.Now.AddDays(1), ScheduleMessageId = Guid.NewGuid(), EmailData = new EmailData() }; var sagaId = Guid.NewGuid(); var scheduledEmailData = new ScheduledEmailData { Id = sagaId, Originator = "place", OriginalMessageId = Guid.NewGuid().ToString(), OriginalMessageData = new OriginalEmailMessageData(new ScheduleEmailForSendingLater { EmailData = scheduleEmailForSendingLater.EmailData }) }; Test.Initialize(); Test.Saga <EmailScheduler>() .WithExternalDependencies(a => { a.Data = scheduledEmailData; }) .ExpectTimeoutToBeSetAt <ScheduleEmailTimeout>((state, timeout) => timeout == scheduleEmailForSendingLater.SendMessageAtUtc && state.TimeoutCounter == 0) .ExpectSendLocal <EmailScheduleCreated>() .When(s => s.Handle(scheduleEmailForSendingLater)) .ExpectTimeoutToBeSetAt <ScheduleEmailTimeout>((state, timeout) => state.TimeoutCounter == 1) .ExpectPublish <MessageRescheduled>() .ExpectSendLocal <ScheduleStatusChanged>(s => s.Status == MessageStatus.Scheduled) .When(s => s.Handle(new ResumeScheduledMessageWithOffset(Guid.Empty, new TimeSpan()) { MessageRequestTimeUtc = DateTime.Now })) .When(s => s.Handle(new PauseScheduledMessageIndefinitely(Guid.Empty) { MessageRequestTimeUtc = DateTime.Now.AddMinutes(-10) })) .ExpectSendToDestination <SendOneEmailNow>((m, d) => d.Queue == "smsactioner") .When(s => s.Timeout(new ScheduleEmailTimeout { TimeoutCounter = 1 })) .ExpectPublish <ScheduledEmailSent>() .ExpectSendLocal <ScheduleStatusChanged>(s => s.Status == MessageStatus.Sent) .When(s => s.Handle(new EmailStatusUpdate { Status = EmailStatus.Opened })) .AssertSagaCompletionIs(true); }
public OriginalEmailMessageData(ScheduleEmailForSendingLater requestMessage) { RequestingCoordinatorId = requestMessage.CorrelationId; Username = requestMessage.Username; ToAddress = requestMessage.EmailData.ToAddress; FromAddress = requestMessage.EmailData.FromAddress; FromDisplayName = requestMessage.EmailData.FromDisplayName; ReplyToAddress = requestMessage.EmailData.ReplyToAddress; Subject = requestMessage.EmailData.Subject; BodyHtml = requestMessage.EmailData.BodyHtml; BodyText = requestMessage.EmailData.BodyText; Topic = requestMessage.Topic; Tags = requestMessage.Tags; ConfirmationEmail = requestMessage.ConfirmationEmail; OriginalRequestSendTime = requestMessage.SendMessageAtUtc; }
public void OriginalMessageGetsSavedToSaga_Data() { var data = new ScheduledEmailData(); var originalMessage = new ScheduleEmailForSendingLater { SendMessageAtUtc = DateTime.Now }; Test.Initialize(); Test.Saga <EmailScheduler>() .WithExternalDependencies(a => { a.Data = data; }) .WhenReceivesMessageFrom("address") .ExpectPublish <SmsScheduled>(m => m.CoordinatorId == data.Id && m.ScheduleMessageId == originalMessage.ScheduleMessageId) .When(s => s.Handle(originalMessage)); Assert.That(data.OriginalMessageData, Is.EqualTo(originalMessage)); }
public void TimeoutPromptsMessageSending_Data() { var bus = MockRepository.GenerateMock <IBus>(); var sendOneEmailNow = new SendOneEmailNow(); bus.Expect(b => b.Send(Arg <string> .Is.Anything, Arg <SendOneEmailNow> .Is.NotNull)) .WhenCalled(i => sendOneEmailNow = (SendOneEmailNow)(i.Arguments[1])); var dataId = Guid.NewGuid(); var originalMessage = new ScheduleEmailForSendingLater { EmailData = new EmailData { BodyHtml = "html", BodyText = "text", FromAddress = "from", FromDisplayName = "display", ReplyToAddress = "replyto", Subject = "subject", ToAddress = "to" } }; var data = new ScheduledEmailData { Id = dataId, OriginalMessageData = new OriginalEmailMessageData(originalMessage) }; var scheduleEmail = new EmailScheduler { Bus = bus, Data = data }; var timeoutMessage = new ScheduleEmailTimeout(); scheduleEmail.Timeout(timeoutMessage); Assert.That(sendOneEmailNow.BodyHtml, Is.EqualTo(data.OriginalMessageData.BodyHtml)); Assert.That(sendOneEmailNow.BodyText, Is.EqualTo(data.OriginalMessageData.BodyText)); Assert.That(sendOneEmailNow.FromAddress, Is.EqualTo(data.OriginalMessageData.FromAddress)); Assert.That(sendOneEmailNow.FromDisplayName, Is.EqualTo(data.OriginalMessageData.FromDisplayName)); Assert.That(sendOneEmailNow.ReplyToAddress, Is.EqualTo(data.OriginalMessageData.ReplyToAddress)); Assert.That(sendOneEmailNow.Subject, Is.EqualTo(data.OriginalMessageData.Subject)); Assert.That(sendOneEmailNow.ToAddress, Is.EqualTo(data.OriginalMessageData.ToAddress)); Assert.That(sendOneEmailNow.Username, Is.EqualTo(data.OriginalMessageData.Username)); Assert.That(sendOneEmailNow.CorrelationId, Is.EqualTo(data.Id)); bus.VerifyAllExpectations(); }
public void TimeoutSendingPausedNoAction_Data() { var bus = MockRepository.GenerateStrictMock <IBus>(); var dataId = Guid.NewGuid(); var originalMessage = new ScheduleEmailForSendingLater { EmailData = new EmailData() }; var data = new ScheduledEmailData { Id = dataId, OriginalMessageData = new OriginalEmailMessageData(originalMessage), SchedulingPaused = true }; var scheduleEmail = new EmailScheduler { Bus = bus, Data = data }; var timeoutMessage = new ScheduleEmailTimeout(); scheduleEmail.Timeout(timeoutMessage); bus.VerifyAllExpectations(); }
// public void Handle(TrickleSmsWithDefinedTimeBetweenEachMessage message) // { // Data.CoordinatorId = message.CoordinatorId == Guid.Empty ? Data.Id : message.CoordinatorId; // Data.OriginalScheduleStartTime = message.StartTimeUtc; // Data.EmailAddresses = message.ConfirmationEmails; // Data.UserOlsenTimeZone = message.UserOlsenTimeZone; // Data.Topic = message.MetaData.Topic; // var messageList = new List<ScheduleSmsForSendingLater>(); // DateTime lastScheduledMessageTime = DateTime.Now; // for(int i = 0; i < message.Messages.Count; i++) // { // var extraTime = TimeSpan.FromTicks(message.TimeSpacing.Ticks*i); // lastScheduledMessageTime = message.StartTimeUtc.Add(extraTime); // var smsData = new SmsData(message.Messages[i].Mobile, message.Messages[i].Message); // var smsForSendingLater = new ScheduleSmsForSendingLater(message.StartTimeUtc.Add(extraTime), smsData, message.MetaData, Data.CoordinatorId, message.Username) // { // CorrelationId = Data.CoordinatorId // }; // messageList.Add(smsForSendingLater); // } // messageList.ForEach(m => Bus.Send(m)); // //Bus.Send(messageList.ToArray()); // var coordinatorCreated = new CoordinatorCreated // { // CoordinatorId = Data.CoordinatorId, // ScheduledMessages = messageList.Select(m => new MessageSchedule { Number = m.SmsData.Mobile, ScheduledTimeUtc = m.SendMessageAtUtc, ScheduleMessageId = m.ScheduleMessageId }).ToList(), // CreationDateUtc = DateTime.UtcNow, // MetaData = message.MetaData, // ConfirmationEmailAddresses = message.ConfirmationEmails, // UserOlsenTimeZone = message.UserOlsenTimeZone, // MessageBody = message.Messages.First().Message, // MessageCount = message.Messages.Count // }; // Bus.Publish(coordinatorCreated); // Bus.SendLocal(new CoordinatorCreatedEmail(coordinatorCreated)); // RequestUtcTimeout<CoordinatorTimeout>(lastScheduledMessageTime.AddMinutes(2)); // // RavenScheduleDocuments.SaveCoordinator(coordinatorCreated); // RavenScheduleDocuments.SaveSchedules(messageList, Data.CoordinatorId); // } public void Handle(TrickleSmsAndEmailBetweenSetTimes message) { Data.CoordinatorId = message.CoordinatorId == Guid.Empty ? Data.Id : message.CoordinatorId; Data.OriginalScheduleStartTime = message.StartTimeUtc; Data.EmailAddresses = message.ConfirmationEmails; Data.UserOlsenTimeZone = message.UserOlsenTimeZone; Data.Topic = message.MetaData.Topic; Data.Username = message.Username; var smsAndEmailCoordinatorData = RavenScheduleDocuments.GetSmsAndEmailCoordinatorData(message.SmsAndEmailDataId); if (smsAndEmailCoordinatorData == null) { throw new NotImplementedException("Need the data!"); } var messageTiming = TimingManager.CalculateTiming(message.StartTimeUtc, message.Duration, smsAndEmailCoordinatorData.CustomerContacts.Count); var lastScheduledMessageTime = DateTime.Now.AddTicks(message.Duration.Ticks); var messageList = new List <object>(); var smsList = new List <ScheduleSmsForSendingLater>(); var emailList = new List <ScheduleEmailForSendingLater>(); for (int i = 0; i < smsAndEmailCoordinatorData.CustomerContacts.Count; i++) { if (smsAndEmailCoordinatorData.CustomerContacts[i].SmsCustomer()) { var smsData = new SmsData(smsAndEmailCoordinatorData.CustomerContacts[i].MobileNumber, message.SmsMessage); var smsForSendingLater = new ScheduleSmsForSendingLater(messageTiming[i], smsData, message.MetaData, Data.CoordinatorId, message.Username) { CorrelationId = Data.CoordinatorId }; messageList.Add(smsForSendingLater); smsList.Add(smsForSendingLater); } if (smsAndEmailCoordinatorData.CustomerContacts[i].EmailCustomer()) { var emailData = new EmailData(message.EmailData, smsAndEmailCoordinatorData.CustomerContacts[i].EmailAddress); var emailForSendingLater = new ScheduleEmailForSendingLater(messageTiming[i], emailData, message.MetaData, Data.CoordinatorId, message.Username) { CorrelationId = Data.CoordinatorId }; messageList.Add(emailForSendingLater); emailList.Add(emailForSendingLater); } } messageList.ForEach(m => Bus.Send("smsscheduler", m)); var coordinatorCreated = new CoordinatorCreatedWithEmailAndSms { CoordinatorId = Data.CoordinatorId, CreationDateUtc = DateTime.UtcNow, MetaData = message.MetaData, ConfirmationEmailAddresses = message.ConfirmationEmails, UserOlsenTimeZone = message.UserOlsenTimeZone, SmsMessage = message.SmsMessage, SmsCount = smsAndEmailCoordinatorData.CustomerContacts.Count(c => c.SmsCustomer()), EmailCount = smsAndEmailCoordinatorData.CustomerContacts.Count(c => c.EmailCustomer()), EmailData = message.EmailData, UserName = message.Username }; RequestUtcTimeout <CoordinatorTimeout>(lastScheduledMessageTime.AddMinutes(2)); Bus.Publish(coordinatorCreated); // TODO: Send email message //Bus.SendLocal(new CoordinatorCreatedEmail(coordinatorCreated)); RavenScheduleDocuments.SaveCoordinator(coordinatorCreated); RavenScheduleDocuments.SaveSchedules(messageList, Data.CoordinatorId); }