diff --git a/MessagingService.BusinessLogic.Tests/MessagingService.BusinessLogic.Tests.csproj b/MessagingService.BusinessLogic.Tests/MessagingService.BusinessLogic.Tests.csproj index c4ea67e..a75f3b3 100644 --- a/MessagingService.BusinessLogic.Tests/MessagingService.BusinessLogic.Tests.csproj +++ b/MessagingService.BusinessLogic.Tests/MessagingService.BusinessLogic.Tests.csproj @@ -7,16 +7,16 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/MessagingService.BusinessLogic/MessagingService.BusinessLogic.csproj b/MessagingService.BusinessLogic/MessagingService.BusinessLogic.csproj index e45630d..4f60807 100644 --- a/MessagingService.BusinessLogic/MessagingService.BusinessLogic.csproj +++ b/MessagingService.BusinessLogic/MessagingService.BusinessLogic.csproj @@ -9,12 +9,12 @@ - - - - - - + + + + + + diff --git a/MessagingService.BusinessLogic/RequestHandlers/MessagingRequestHandler.cs b/MessagingService.BusinessLogic/RequestHandlers/MessagingRequestHandler.cs index a220a57..c133f6c 100644 --- a/MessagingService.BusinessLogic/RequestHandlers/MessagingRequestHandler.cs +++ b/MessagingService.BusinessLogic/RequestHandlers/MessagingRequestHandler.cs @@ -1,6 +1,4 @@ -namespace MessagingService.BusinessLogic.RequestHandlers -{ - using System; +namespace MessagingService.BusinessLogic.RequestHandlers{ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -8,16 +6,16 @@ using Requests; using Services; using EmailAttachment = Models.EmailAttachment; + using FileType = Models.FileType; /// /// /// /// - public class MessagingRequestHandler : IRequestHandler, + public class MessagingRequestHandler : IRequestHandler, IRequestHandler, IRequestHandler, - IRequestHandler - { + IRequestHandler{ #region Fields /// @@ -33,8 +31,7 @@ public class MessagingRequestHandler : IRequestHandler, /// Initializes a new instance of the class. /// /// The messaging domain service. - public MessagingRequestHandler(IMessagingDomainService messagingDomainService) - { + public MessagingRequestHandler(IMessagingDomainService messagingDomainService){ this.MessagingDomainService = messagingDomainService; } @@ -50,9 +47,9 @@ public MessagingRequestHandler(IMessagingDomainService messagingDomainService) /// /// Response from the request /// - public async Task Handle(SendEmailRequest request, - CancellationToken cancellationToken){ - List attachments = new List(); + public async Task Handle(SendEmailRequest request, + CancellationToken cancellationToken){ + List attachments = new List(); foreach (Requests.EmailAttachment requestEmailAttachment in request.EmailAttachments){ attachments.Add(new EmailAttachment{ @@ -61,7 +58,7 @@ public async Task Handle(SendEmailRequest request, Filename = requestEmailAttachment.Filename, }); } - + await this.MessagingDomainService.SendEmailMessage(request.ConnectionIdentifier, request.MessageId, request.FromAddress, @@ -71,46 +68,36 @@ await this.MessagingDomainService.SendEmailMessage(request.ConnectionIdentifier, request.IsHtml, attachments, cancellationToken); - - return Unit.Value; } - public async Task Handle(SendSMSRequest request, - CancellationToken cancellationToken) - { + public async Task Handle(SendSMSRequest request, + CancellationToken cancellationToken){ await this.MessagingDomainService.SendSMSMessage(request.ConnectionIdentifier, request.MessageId, request.Sender, request.Destination, request.Message, cancellationToken); - return Unit.Value; } - #endregion - - public async Task Handle(ResendEmailRequest request, - CancellationToken cancellationToken) { + public async Task Handle(ResendEmailRequest request, + CancellationToken cancellationToken){ await this.MessagingDomainService.ResendEmailMessage(request.ConnectionIdentifier, request.MessageId, cancellationToken); + } - return Unit.Value; + public async Task Handle(ResendSMSRequest request, CancellationToken cancellationToken){ + await this.MessagingDomainService.ResendSMSMessage(request.ConnectionIdentifier, request.MessageId, cancellationToken); } - private Models.FileType ConvertFileType(FileType emailAttachmentFileType) - { - switch (emailAttachmentFileType) - { - case FileType.PDF: - return Models.FileType.PDF; + private FileType ConvertFileType(Requests.FileType emailAttachmentFileType){ + switch(emailAttachmentFileType){ + case Requests.FileType.PDF: + return FileType.PDF; default: - return Models.FileType.None; + return FileType.None; } } - public async Task Handle(ResendSMSRequest request, CancellationToken cancellationToken){ - await this.MessagingDomainService.ResendSMSMessage(request.ConnectionIdentifier, request.MessageId, cancellationToken); - - return Unit.Value; - } + #endregion } } \ No newline at end of file diff --git a/MessagingService.Client/MessagingService.Client.csproj b/MessagingService.Client/MessagingService.Client.csproj index 0de4f0a..4dede13 100644 --- a/MessagingService.Client/MessagingService.Client.csproj +++ b/MessagingService.Client/MessagingService.Client.csproj @@ -6,8 +6,8 @@ - - + + diff --git a/MessagingService.DataTransferObjects/MessagingService.DataTransferObjects.csproj b/MessagingService.DataTransferObjects/MessagingService.DataTransferObjects.csproj index c2f163c..52ee4dd 100644 --- a/MessagingService.DataTransferObjects/MessagingService.DataTransferObjects.csproj +++ b/MessagingService.DataTransferObjects/MessagingService.DataTransferObjects.csproj @@ -9,7 +9,7 @@ - + diff --git a/MessagingService.EmailAggregate.Tests/MessagingService.EmailAggregate.Tests.csproj b/MessagingService.EmailAggregate.Tests/MessagingService.EmailAggregate.Tests.csproj index 7941efb..f530d8e 100644 --- a/MessagingService.EmailAggregate.Tests/MessagingService.EmailAggregate.Tests.csproj +++ b/MessagingService.EmailAggregate.Tests/MessagingService.EmailAggregate.Tests.csproj @@ -7,15 +7,15 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/MessagingService.EmailMessage.DomainEvents/MessagingService.EmailMessage.DomainEvents.csproj b/MessagingService.EmailMessage.DomainEvents/MessagingService.EmailMessage.DomainEvents.csproj index 03e4ccb..4cac690 100644 --- a/MessagingService.EmailMessage.DomainEvents/MessagingService.EmailMessage.DomainEvents.csproj +++ b/MessagingService.EmailMessage.DomainEvents/MessagingService.EmailMessage.DomainEvents.csproj @@ -5,8 +5,8 @@ - - + + diff --git a/MessagingService.EmailMessageAggregate/EmailAggregate.cs b/MessagingService.EmailMessageAggregate/EmailAggregate.cs index e10ff8c..61ec596 100644 --- a/MessagingService.EmailMessageAggregate/EmailAggregate.cs +++ b/MessagingService.EmailMessageAggregate/EmailAggregate.cs @@ -11,329 +11,328 @@ using Shared.General; using Shared.Logger; - public class EmailAggregate : Aggregate - { - #region Fields - - private readonly List Recipients; - - private readonly List Attachments; - - private List ToAddresses; - - public List GetToAddresses() { - return this.ToAddresses; - } - - public List GetAttachments() - { - return this.Attachments; - } - - #endregion - - #region Constructors - - [ExcludeFromCodeCoverage] - public EmailAggregate() - { - this.Recipients = new List(); - this.Attachments = new List(); - this.DeliveryStatusList = new List { - MessageStatus.NotSet - }; - } - - private EmailAggregate(Guid aggregateId) - { - Guard.ThrowIfInvalidGuid(aggregateId, "Aggregate Id cannot be an Empty Guid"); - - this.AggregateId = aggregateId; - this.MessageId = aggregateId; - this.Recipients = new List(); - this.Attachments = new List(); - this.DeliveryStatusList = new List { - MessageStatus.NotSet - }; - } - - #endregion - - #region Properties - - public String Body { get; private set; } - - public String FromAddress { get; private set; } - - public Boolean IsHtml { get; private set; } - - public Guid MessageId { get; } - - public String ProviderEmailReference { get; private set; } - - public String ProviderRequestReference { get; private set; } - - public String Error { get; private set; } - - public String ErrorCode { get; private set; } - - public String Subject { get; private set; } - - public Int32 ResendCount { get; private set; } - - private List DeliveryStatusList; - - #endregion - - #region Methods - - public static EmailAggregate Create(Guid aggregateId) - { - return new EmailAggregate(aggregateId); - } - - public void MarkMessageAsBounced(String providerStatus, + public static class EmailAggregateExtensions{ + public static void MarkMessageAsBounced(this EmailAggregate aggregate, String providerStatus, DateTime bouncedDateTime) { - this.CheckMessageCanBeSetToBounced(); + aggregate.CheckMessageCanBeSetToBounced(); - EmailMessageBouncedEvent messageBouncedEvent = new EmailMessageBouncedEvent(this.AggregateId, providerStatus, bouncedDateTime); + EmailMessageBouncedEvent messageBouncedEvent = new EmailMessageBouncedEvent(aggregate.AggregateId, providerStatus, bouncedDateTime); - this.ApplyAndAppend(messageBouncedEvent); + aggregate.ApplyAndAppend(messageBouncedEvent); } - public void MarkMessageAsDelivered(String providerStatus, - DateTime deliveredDateTime) + public static void MarkMessageAsDelivered(this EmailAggregate aggregate, String providerStatus, + DateTime deliveredDateTime) { - this.CheckMessageCanBeSetToDelivered(); + aggregate.CheckMessageCanBeSetToDelivered(); - EmailMessageDeliveredEvent messageDeliveredEvent = new EmailMessageDeliveredEvent(this.AggregateId, providerStatus, deliveredDateTime); + EmailMessageDeliveredEvent messageDeliveredEvent = new EmailMessageDeliveredEvent(aggregate.AggregateId, providerStatus, deliveredDateTime); - this.ApplyAndAppend(messageDeliveredEvent); + aggregate.ApplyAndAppend(messageDeliveredEvent); } - public void MarkMessageAsFailed(String providerStatus, + public static void MarkMessageAsFailed(this EmailAggregate aggregate, String providerStatus, DateTime failedDateTime) { - this.CheckMessageCanBeSetToFailed(); + aggregate.CheckMessageCanBeSetToFailed(); - EmailMessageFailedEvent messageFailedEvent = new EmailMessageFailedEvent(this.AggregateId, providerStatus, failedDateTime); + EmailMessageFailedEvent messageFailedEvent = new EmailMessageFailedEvent(aggregate.AggregateId, providerStatus, failedDateTime); - this.ApplyAndAppend(messageFailedEvent); + aggregate.ApplyAndAppend(messageFailedEvent); } - public void MarkMessageAsRejected(String providerStatus, + public static void MarkMessageAsRejected(this EmailAggregate aggregate, String providerStatus, DateTime rejectedDateTime) { - this.CheckMessageCanBeSetToRejected(); + aggregate.CheckMessageCanBeSetToRejected(); - EmailMessageRejectedEvent messageRejectedEvent = new EmailMessageRejectedEvent(this.AggregateId, providerStatus, rejectedDateTime); + EmailMessageRejectedEvent messageRejectedEvent = new EmailMessageRejectedEvent(aggregate.AggregateId, providerStatus, rejectedDateTime); - this.ApplyAndAppend(messageRejectedEvent); + aggregate.ApplyAndAppend(messageRejectedEvent); } - public void MarkMessageAsSpam(String providerStatus, + public static void MarkMessageAsSpam(this EmailAggregate aggregate, String providerStatus, DateTime spamDateTime) { - this.CheckMessageCanBeSetToSpam(); + aggregate.CheckMessageCanBeSetToSpam(); - EmailMessageMarkedAsSpamEvent messageMarkedAsSpamEvent = new EmailMessageMarkedAsSpamEvent(this.AggregateId, providerStatus, spamDateTime); + EmailMessageMarkedAsSpamEvent messageMarkedAsSpamEvent = new EmailMessageMarkedAsSpamEvent(aggregate.AggregateId, providerStatus, spamDateTime); - this.ApplyAndAppend(messageMarkedAsSpamEvent); + aggregate.ApplyAndAppend(messageMarkedAsSpamEvent); } - public void ReceiveResponseFromProvider(String providerRequestReference, + public static void ReceiveResponseFromProvider(this EmailAggregate aggregate, String providerRequestReference, String providerEmailReference) { ResponseReceivedFromEmailProviderEvent responseReceivedFromProviderEvent = - new ResponseReceivedFromEmailProviderEvent(this.AggregateId, providerRequestReference, providerEmailReference); + new ResponseReceivedFromEmailProviderEvent(aggregate.AggregateId, providerRequestReference, providerEmailReference); - this.ApplyAndAppend(responseReceivedFromProviderEvent); + aggregate.ApplyAndAppend(responseReceivedFromProviderEvent); } - public void ReceiveBadResponseFromProvider(String error, String errorCode) + public static void ReceiveBadResponseFromProvider(this EmailAggregate aggregate, String error, String errorCode) { BadResponseReceivedFromEmailProviderEvent badResponseReceivedFromProviderEvent = - new BadResponseReceivedFromEmailProviderEvent(this.AggregateId, errorCode,error); + new BadResponseReceivedFromEmailProviderEvent(aggregate.AggregateId, errorCode, error); - this.ApplyAndAppend(badResponseReceivedFromProviderEvent); + aggregate.ApplyAndAppend(badResponseReceivedFromProviderEvent); } - public void SendRequestToProvider(String fromAddress, + public static void SendRequestToProvider(this EmailAggregate aggregate, String fromAddress, List toAddresses, String subject, String body, Boolean isHtml, List attachments) { - if (this.DeliveryStatusList[this.ResendCount] != MessageStatus.NotSet) + if (aggregate.DeliveryStatusList[aggregate.ResendCount] != MessageStatus.NotSet) { throw new InvalidOperationException("Cannot send a message to provider that has already been sent"); } - RequestSentToEmailProviderEvent requestSentToProviderEvent = new RequestSentToEmailProviderEvent(this.AggregateId, fromAddress, toAddresses, subject, body, isHtml); + RequestSentToEmailProviderEvent requestSentToProviderEvent = new RequestSentToEmailProviderEvent(aggregate.AggregateId, fromAddress, toAddresses, subject, body, isHtml); - this.ApplyAndAppend(requestSentToProviderEvent); + aggregate.ApplyAndAppend(requestSentToProviderEvent); // Record the attachment data - foreach (EmailAttachment emailAttachment in attachments){ - EmailAttachmentRequestSentToProviderEvent emailAttachmentRequestSentToProviderEvent = new EmailAttachmentRequestSentToProviderEvent(this.AggregateId, + foreach (EmailAttachment emailAttachment in attachments) + { + EmailAttachmentRequestSentToProviderEvent emailAttachmentRequestSentToProviderEvent = new EmailAttachmentRequestSentToProviderEvent(aggregate.AggregateId, emailAttachment.Filename, emailAttachment.FileData, (Int32)emailAttachment.FileType); - this.ApplyAndAppend(emailAttachmentRequestSentToProviderEvent); + aggregate.ApplyAndAppend(emailAttachmentRequestSentToProviderEvent); } } - public void ResendRequestToProvider() + public static void ResendRequestToProvider(this EmailAggregate aggregate) { - if (this.DeliveryStatusList[this.ResendCount] != MessageStatus.Sent && - this.DeliveryStatusList[this.ResendCount] != MessageStatus.Delivered) + if (aggregate.DeliveryStatusList[aggregate.ResendCount] != MessageStatus.Sent && + aggregate.DeliveryStatusList[aggregate.ResendCount] != MessageStatus.Delivered) { - throw new InvalidOperationException($"Cannot re-send a message to provider that has not already been sent. Current Status [{this.DeliveryStatusList[this.ResendCount]}]"); + throw new InvalidOperationException($"Cannot re-send a message to provider that has not already been sent. Current Status [{aggregate.DeliveryStatusList[aggregate.ResendCount]}]"); } - RequestResentToEmailProviderEvent requestResentToEmailProviderEvent = new RequestResentToEmailProviderEvent(this.AggregateId); - - this.ApplyAndAppend(requestResentToEmailProviderEvent); - } - - [ExcludeFromCodeCoverage] - protected override Object GetMetadata() - { - return null; - } - - public override void PlayEvent(IDomainEvent domainEvent) - { - this.PlayEvent((dynamic)domainEvent); - } - - private void PlayEvent(Object @event) - { - Exception ex = new Exception($"Failed to apply event {@event.GetType()} to Aggregate {this.GetType().Name}"); + RequestResentToEmailProviderEvent requestResentToEmailProviderEvent = new RequestResentToEmailProviderEvent(aggregate.AggregateId); - Logger.LogCritical(ex); - throw ex; + aggregate.ApplyAndAppend(requestResentToEmailProviderEvent); } - private void CheckMessageCanBeSetToBounced() + private static void CheckMessageCanBeSetToBounced(this EmailAggregate aggregate) { - if (this.DeliveryStatusList[this.ResendCount] != MessageStatus.Sent) + if (aggregate.DeliveryStatusList[aggregate.ResendCount] != MessageStatus.Sent) { - throw new InvalidOperationException($"Message at status {this.DeliveryStatusList[this.ResendCount]} cannot be set to bounced"); + throw new InvalidOperationException($"Message at status {aggregate.DeliveryStatusList[aggregate.ResendCount]} cannot be set to bounced"); } } - private void CheckMessageCanBeSetToDelivered() + private static void CheckMessageCanBeSetToDelivered(this EmailAggregate aggregate) { - if (this.DeliveryStatusList[this.ResendCount] != MessageStatus.Sent) + if (aggregate.DeliveryStatusList[aggregate.ResendCount] != MessageStatus.Sent) { - throw new InvalidOperationException($"Message at status {this.DeliveryStatusList[this.ResendCount]} cannot be set to delivered"); + throw new InvalidOperationException($"Message at status {aggregate.DeliveryStatusList[aggregate.ResendCount]} cannot be set to delivered"); } } - private void CheckMessageCanBeSetToFailed() + private static void CheckMessageCanBeSetToFailed(this EmailAggregate aggregate) { - if (this.DeliveryStatusList[this.ResendCount] != MessageStatus.Sent) + if (aggregate.DeliveryStatusList[aggregate.ResendCount] != MessageStatus.Sent) { - throw new InvalidOperationException($"Message at status {this.DeliveryStatusList[this.ResendCount]} cannot be set to failed"); + throw new InvalidOperationException($"Message at status {aggregate.DeliveryStatusList[aggregate.ResendCount]} cannot be set to failed"); } } - private void CheckMessageCanBeSetToRejected() + private static void CheckMessageCanBeSetToRejected(this EmailAggregate aggregate) { - if (this.DeliveryStatusList[this.ResendCount] != MessageStatus.Sent) + if (aggregate.DeliveryStatusList[aggregate.ResendCount] != MessageStatus.Sent) { - throw new InvalidOperationException($"Message at status {this.DeliveryStatusList[this.ResendCount]} cannot be set to rejected"); + throw new InvalidOperationException($"Message at status {aggregate.DeliveryStatusList[aggregate.ResendCount]} cannot be set to rejected"); } } - private void CheckMessageCanBeSetToSpam() + private static void CheckMessageCanBeSetToSpam(this EmailAggregate aggregate) { - if (this.DeliveryStatusList[this.ResendCount] != MessageStatus.Sent) + if (aggregate.DeliveryStatusList[aggregate.ResendCount] != MessageStatus.Sent) { - throw new InvalidOperationException($"Message at status {this.DeliveryStatusList[this.ResendCount]} cannot be set to spam"); + throw new InvalidOperationException($"Message at status {aggregate.DeliveryStatusList[aggregate.ResendCount]} cannot be set to spam"); } } - private void PlayEvent(RequestSentToEmailProviderEvent domainEvent) + public static void PlayEvent(this EmailAggregate aggregate, RequestSentToEmailProviderEvent domainEvent) { - this.Body = domainEvent.Body; - this.Subject = domainEvent.Subject; - this.IsHtml = domainEvent.IsHtml; - this.FromAddress = domainEvent.FromAddress; - this.ToAddresses = domainEvent.ToAddresses; - this.ResendCount = 0; - this.DeliveryStatusList[this.ResendCount] =MessageStatus.InProgress; + aggregate.Body = domainEvent.Body; + aggregate.Subject = domainEvent.Subject; + aggregate.IsHtml = domainEvent.IsHtml; + aggregate.FromAddress = domainEvent.FromAddress; + aggregate.ToAddresses = domainEvent.ToAddresses; + aggregate.ResendCount = 0; + aggregate.DeliveryStatusList[aggregate.ResendCount] = MessageStatus.InProgress; foreach (String domainEventToAddress in domainEvent.ToAddresses) { MessageRecipient messageRecipient = new MessageRecipient(); messageRecipient.Create(domainEventToAddress); - this.Recipients.Add(messageRecipient); + aggregate.Recipients.Add(messageRecipient); } } - private void PlayEvent(ResponseReceivedFromEmailProviderEvent domainEvent) + public static void PlayEvent(this EmailAggregate aggregate, ResponseReceivedFromEmailProviderEvent domainEvent) { - this.ProviderEmailReference = domainEvent.ProviderEmailReference; - this.ProviderRequestReference = domainEvent.ProviderRequestReference; - this.DeliveryStatusList[this.ResendCount] = MessageStatus.Sent; + aggregate.ProviderEmailReference = domainEvent.ProviderEmailReference; + aggregate.ProviderRequestReference = domainEvent.ProviderRequestReference; + aggregate.DeliveryStatusList[aggregate.ResendCount] = MessageStatus.Sent; } - private void PlayEvent(BadResponseReceivedFromEmailProviderEvent domainEvent) + public static void PlayEvent(this EmailAggregate aggregate, BadResponseReceivedFromEmailProviderEvent domainEvent) { - this.Error = domainEvent.Error; - this.ErrorCode = domainEvent.ErrorCode; - this.DeliveryStatusList[this.ResendCount] = MessageStatus.Failed; + aggregate.Error = domainEvent.Error; + aggregate.ErrorCode = domainEvent.ErrorCode; + aggregate.DeliveryStatusList[aggregate.ResendCount] = MessageStatus.Failed; } - private void PlayEvent(EmailAttachmentRequestSentToProviderEvent domainEvent){ - this.Attachments.Add(new EmailAttachment{ - FileData = domainEvent.FileData, - FileType = (FileType)domainEvent.FileType, - Filename = domainEvent.Filename, - }); + public static void PlayEvent(this EmailAggregate aggregate, EmailAttachmentRequestSentToProviderEvent domainEvent) + { + aggregate.Attachments.Add(new EmailAttachment + { + FileData = domainEvent.FileData, + FileType = (FileType)domainEvent.FileType, + Filename = domainEvent.Filename, + }); } - private void PlayEvent(RequestResentToEmailProviderEvent domainEvent) { - this.ResendCount++; - this.DeliveryStatusList.Add(MessageStatus.InProgress); + public static void PlayEvent(this EmailAggregate aggregate, RequestResentToEmailProviderEvent domainEvent) + { + aggregate.ResendCount++; + aggregate.DeliveryStatusList.Add(MessageStatus.InProgress); } - private void PlayEvent(EmailMessageDeliveredEvent domainEvent) + public static void PlayEvent(this EmailAggregate aggregate, EmailMessageDeliveredEvent domainEvent) { - this.DeliveryStatusList[this.ResendCount] = MessageStatus.Delivered; + aggregate.DeliveryStatusList[aggregate.ResendCount] = MessageStatus.Delivered; } - public MessageStatus GetDeliveryStatus(Int32? resendAttempt = null) { - if (resendAttempt.HasValue == false) { - return this.DeliveryStatusList[this.ResendCount]; + public static MessageStatus GetDeliveryStatus(this EmailAggregate aggregate, Int32? resendAttempt = null) + { + if (resendAttempt.HasValue == false) + { + return aggregate.DeliveryStatusList[aggregate.ResendCount]; } - return this.DeliveryStatusList[resendAttempt.Value]; + return aggregate.DeliveryStatusList[resendAttempt.Value]; + } + + public static void PlayEvent(this EmailAggregate aggregate, EmailMessageFailedEvent domainEvent) + { + aggregate.DeliveryStatusList[aggregate.ResendCount] = MessageStatus.Failed; + } + + public static void PlayEvent(this EmailAggregate aggregate, EmailMessageRejectedEvent domainEvent) + { + aggregate.DeliveryStatusList[aggregate.ResendCount] = MessageStatus.Rejected; + } + + public static void PlayEvent(this EmailAggregate aggregate, EmailMessageBouncedEvent domainEvent) + { + aggregate.DeliveryStatusList[aggregate.ResendCount] = MessageStatus.Bounced; + } + + public static void PlayEvent(this EmailAggregate aggregate, EmailMessageMarkedAsSpamEvent domainEvent) + { + aggregate.DeliveryStatusList[aggregate.ResendCount] = MessageStatus.Spam; + } + + public static List GetToAddresses(this EmailAggregate aggregate) + { + return aggregate.ToAddresses; } - private void PlayEvent(EmailMessageFailedEvent domainEvent) + public static List GetAttachments(this EmailAggregate aggregate) { - this.DeliveryStatusList[this.ResendCount] = MessageStatus.Failed; + return aggregate.Attachments; } - private void PlayEvent(EmailMessageRejectedEvent domainEvent) + } + + public record EmailAggregate : Aggregate + { + #region Fields + + internal readonly List Recipients; + + internal readonly List Attachments; + + internal List ToAddresses; + + #endregion + + #region Constructors + + [ExcludeFromCodeCoverage] + public EmailAggregate() { - this.DeliveryStatusList[this.ResendCount] = MessageStatus.Rejected; + this.Recipients = new List(); + this.Attachments = new List(); + this.DeliveryStatusList = new List { + MessageStatus.NotSet + }; } - private void PlayEvent(EmailMessageBouncedEvent domainEvent) + private EmailAggregate(Guid aggregateId) { - this.DeliveryStatusList[this.ResendCount] = MessageStatus.Bounced; + Guard.ThrowIfInvalidGuid(aggregateId, "Aggregate Id cannot be an Empty Guid"); + + this.AggregateId = aggregateId; + this.MessageId = aggregateId; + this.Recipients = new List(); + this.Attachments = new List(); + this.DeliveryStatusList = new List { + MessageStatus.NotSet + }; } - private void PlayEvent(EmailMessageMarkedAsSpamEvent domainEvent) + #endregion + + #region Properties + + public String Body { get; internal set; } + + public String FromAddress { get; internal set; } + + public Boolean IsHtml { get; internal set; } + + public Guid MessageId { get; } + + public String ProviderEmailReference { get; internal set; } + + public String ProviderRequestReference { get; internal set; } + + public String Error { get; internal set; } + + public String ErrorCode { get; internal set; } + + public String Subject { get; internal set; } + + public Int32 ResendCount { get; internal set; } + + internal List DeliveryStatusList; + + #endregion + + #region Methods + + public static EmailAggregate Create(Guid aggregateId) { - this.DeliveryStatusList[this.ResendCount] = MessageStatus.Spam; + return new EmailAggregate(aggregateId); } + + [ExcludeFromCodeCoverage] + protected override Object GetMetadata() + { + return null; + } + + public override void PlayEvent(IDomainEvent domainEvent) => EmailAggregateExtensions.PlayEvent(this, (dynamic)domainEvent); #endregion } diff --git a/MessagingService.EmailMessageAggregate/MessagingService.EmailMessageAggregate.csproj b/MessagingService.EmailMessageAggregate/MessagingService.EmailMessageAggregate.csproj index 9fb441f..f9ee6af 100644 --- a/MessagingService.EmailMessageAggregate/MessagingService.EmailMessageAggregate.csproj +++ b/MessagingService.EmailMessageAggregate/MessagingService.EmailMessageAggregate.csproj @@ -5,9 +5,9 @@ - - - + + + diff --git a/MessagingService.IntegrationTests/MessagingService.IntegrationTests.csproj b/MessagingService.IntegrationTests/MessagingService.IntegrationTests.csproj index dd4a7fc..82cb7ef 100644 --- a/MessagingService.IntegrationTests/MessagingService.IntegrationTests.csproj +++ b/MessagingService.IntegrationTests/MessagingService.IntegrationTests.csproj @@ -6,12 +6,12 @@ - - - - - - + + + + + + @@ -19,7 +19,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/MessagingService.SMSAggregate.Tests/MessagingService.SMSAggregate.Tests.csproj b/MessagingService.SMSAggregate.Tests/MessagingService.SMSAggregate.Tests.csproj index 7d27b9d..1fe167e 100644 --- a/MessagingService.SMSAggregate.Tests/MessagingService.SMSAggregate.Tests.csproj +++ b/MessagingService.SMSAggregate.Tests/MessagingService.SMSAggregate.Tests.csproj @@ -7,14 +7,14 @@ - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/MessagingService.SMSMessage.DomainEvents/MessagingService.SMSMessage.DomainEvents.csproj b/MessagingService.SMSMessage.DomainEvents/MessagingService.SMSMessage.DomainEvents.csproj index 1342892..a689551 100644 --- a/MessagingService.SMSMessage.DomainEvents/MessagingService.SMSMessage.DomainEvents.csproj +++ b/MessagingService.SMSMessage.DomainEvents/MessagingService.SMSMessage.DomainEvents.csproj @@ -5,7 +5,7 @@ - + diff --git a/MessagingService.SMSMessageAggregate/MessagingService.SMSMessageAggregate.csproj b/MessagingService.SMSMessageAggregate/MessagingService.SMSMessageAggregate.csproj index b9dbf50..7be6d50 100644 --- a/MessagingService.SMSMessageAggregate/MessagingService.SMSMessageAggregate.csproj +++ b/MessagingService.SMSMessageAggregate/MessagingService.SMSMessageAggregate.csproj @@ -5,8 +5,8 @@ - - + + diff --git a/MessagingService.SMSMessageAggregate/SMSAggregate.cs b/MessagingService.SMSMessageAggregate/SMSAggregate.cs index d4e5eed..01b8a2f 100644 --- a/MessagingService.SMSMessageAggregate/SMSAggregate.cs +++ b/MessagingService.SMSMessageAggregate/SMSAggregate.cs @@ -1,360 +1,211 @@ -using System; - -namespace MessagingService.SMSMessageAggregate -{ +namespace MessagingService.SMSMessageAggregate{ + using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using Shared.DomainDrivenDesign.EventSourcing; using Shared.EventStore.Aggregate; using Shared.General; - using Shared.Logger; using SMSMessage.DomainEvents; - /// - /// - /// - /// - public class SMSAggregate : Aggregate - { - #region Constructors + public static class SMSAggregateExtensions{ + #region Methods - /// - /// Initializes a new instance of the class. - /// - [ExcludeFromCodeCoverage] - public SMSAggregate() - { - this.DeliveryStatusList = new List { - MessageStatus.NotSet - }; + public static MessageStatus GetDeliveryStatus(this SMSAggregate aggregate, Int32? resendAttempt = null){ + if (resendAttempt.HasValue == false){ + return aggregate.DeliveryStatusList[aggregate.ResendCount]; + } + + return aggregate.DeliveryStatusList[resendAttempt.Value]; } - /// - /// Initializes a new instance of the class. - /// - /// The aggregate identifier. - private SMSAggregate(Guid aggregateId) - { - Guard.ThrowIfInvalidGuid(aggregateId, "Aggregate Id cannot be an Empty Guid"); + public static void MarkMessageAsDelivered(this SMSAggregate aggregate, + String providerStatus, + DateTime failedDateTime){ + aggregate.CheckMessageCanBeSetToDelivered(); - this.AggregateId = aggregateId; - this.MessageId = aggregateId; - this.DeliveryStatusList = new List { - MessageStatus.NotSet - }; + SMSMessageDeliveredEvent messageDeliveredEvent = new SMSMessageDeliveredEvent(aggregate.AggregateId, providerStatus, failedDateTime); + + aggregate.ApplyAndAppend(messageDeliveredEvent); } - #endregion + public static void MarkMessageAsExpired(this SMSAggregate aggregate, + String providerStatus, + DateTime failedDateTime){ + aggregate.CheckMessageCanBeSetToExpired(); - /// - /// Gets the message identifier. - /// - /// - /// The message identifier. - /// - public Guid MessageId { get; private set; } - /// - /// Gets the sender. - /// - /// - /// The sender. - /// - public String Sender { get; private set; } - /// - /// Gets the destination. - /// - /// - /// The destination. - /// - public String Destination { get; private set; } - /// - /// Gets the message. - /// - /// - /// The message. - /// - public String Message { get; private set; } - /// - /// Gets the provider reference. - /// - /// - /// The provider reference. - /// - public String ProviderReference { get; private set; } - - /// - /// Gets the message status. - /// - /// - /// The message status. - /// - //public MessageStatus MessageStatus { get; private set; } - - /// - /// Creates the specified aggregate identifier. - /// - /// The aggregate identifier. - /// - public static SMSAggregate Create(Guid aggregateId) - { - return new SMSAggregate(aggregateId); + SMSMessageExpiredEvent messageExpiredEvent = new SMSMessageExpiredEvent(aggregate.AggregateId, providerStatus, failedDateTime); + + aggregate.ApplyAndAppend(messageExpiredEvent); } - /// - /// Messages the send to recipient failure. - /// - /// The provider SMS reference. - public void ReceiveResponseFromProvider(String providerSMSReference) - { - ResponseReceivedFromSMSProviderEvent responseReceivedFromProviderEvent = - new ResponseReceivedFromSMSProviderEvent(this.AggregateId, providerSMSReference); + public static void MarkMessageAsRejected(this SMSAggregate aggregate, + String providerStatus, + DateTime failedDateTime){ + aggregate.CheckMessageCanBeSetToRejected(); + + SMSMessageRejectedEvent messageRejectedEvent = new SMSMessageRejectedEvent(aggregate.AggregateId, providerStatus, failedDateTime); - this.ApplyAndAppend(responseReceivedFromProviderEvent); + aggregate.ApplyAndAppend(messageRejectedEvent); } - /// - /// Sends the request to provider. - /// - /// The sender. - /// The destination. - /// The message. - /// Cannot send a message to provider that has already been sent - public void SendRequestToProvider(String sender, - String destination, - String message) - { - if (this.DeliveryStatusList[this.ResendCount] != MessageStatus.NotSet) - { - throw new InvalidOperationException("Cannot send a message to provider that has already been sent"); - } + public static void MarkMessageAsUndeliverable(this SMSAggregate aggregate, + String providerStatus, + DateTime failedDateTime){ + aggregate.CheckMessageCanBeSetToUndeliverable(); - RequestSentToSMSProviderEvent requestSentToProviderEvent = new RequestSentToSMSProviderEvent(this.AggregateId, sender,destination,message); + SMSMessageUndeliveredEvent messageUndeliveredEvent = new SMSMessageUndeliveredEvent(aggregate.AggregateId, providerStatus, failedDateTime); - this.ApplyAndAppend(requestSentToProviderEvent); + aggregate.ApplyAndAppend(messageUndeliveredEvent); } - /// - /// Marks the message as failed. - /// - /// The provider status. - /// The failed date time. - public void MarkMessageAsExpired(String providerStatus, - DateTime failedDateTime) - { - this.CheckMessageCanBeSetToExpired(); + public static void PlayEvent(this SMSAggregate aggregate, RequestSentToSMSProviderEvent domainEvent){ + aggregate.Sender = domainEvent.Sender; + aggregate.Destination = domainEvent.Destination; + aggregate.Message = domainEvent.Message; + aggregate.DeliveryStatusList[aggregate.ResendCount] = MessageStatus.InProgress; + } - SMSMessageExpiredEvent messageExpiredEvent = new SMSMessageExpiredEvent(this.AggregateId, providerStatus, failedDateTime); + public static void PlayEvent(this SMSAggregate aggregate, ResponseReceivedFromSMSProviderEvent domainEvent){ + aggregate.ProviderReference = domainEvent.ProviderSMSReference; + aggregate.DeliveryStatusList[aggregate.ResendCount] = MessageStatus.Sent; + } - this.ApplyAndAppend(messageExpiredEvent); + public static void PlayEvent(this SMSAggregate aggregate, SMSMessageExpiredEvent domainEvent){ + aggregate.DeliveryStatusList[aggregate.ResendCount] = MessageStatus.Expired; } - /// - /// Marks the message as failed. - /// - /// The provider status. - /// The failed date time. - public void MarkMessageAsRejected(String providerStatus, - DateTime failedDateTime) - { - this.CheckMessageCanBeSetToRejected(); + public static void PlayEvent(this SMSAggregate aggregate, SMSMessageDeliveredEvent domainEvent){ + aggregate.DeliveryStatusList[aggregate.ResendCount] = MessageStatus.Delivered; + } - SMSMessageRejectedEvent messageRejectedEvent = new SMSMessageRejectedEvent(this.AggregateId, providerStatus, failedDateTime); + public static void PlayEvent(this SMSAggregate aggregate, SMSMessageRejectedEvent domainEvent){ + aggregate.DeliveryStatusList[aggregate.ResendCount] = MessageStatus.Rejected; + } - this.ApplyAndAppend(messageRejectedEvent); + public static void PlayEvent(this SMSAggregate aggregate, SMSMessageUndeliveredEvent domainEvent){ + aggregate.DeliveryStatusList[aggregate.ResendCount] = MessageStatus.Undeliverable; } - /// - /// Marks the message as delivered. - /// - /// The provider status. - /// The failed date time. - public void MarkMessageAsDelivered(String providerStatus, - DateTime failedDateTime) - { - this.CheckMessageCanBeSetToDelivered(); + public static void PlayEvent(this SMSAggregate aggregate, RequestResentToSMSProviderEvent domainEvent){ + aggregate.ResendCount++; + aggregate.DeliveryStatusList.Add(MessageStatus.InProgress); + } - SMSMessageDeliveredEvent messageDeliveredEvent = new SMSMessageDeliveredEvent(this.AggregateId, providerStatus, failedDateTime); + public static void ReceiveResponseFromProvider(this SMSAggregate aggregate, String providerSMSReference){ + ResponseReceivedFromSMSProviderEvent responseReceivedFromProviderEvent = + new ResponseReceivedFromSMSProviderEvent(aggregate.AggregateId, providerSMSReference); - this.ApplyAndAppend(messageDeliveredEvent); + aggregate.ApplyAndAppend(responseReceivedFromProviderEvent); } + public static void ResendRequestToProvider(this SMSAggregate aggregate){ + if (aggregate.DeliveryStatusList[aggregate.ResendCount] != MessageStatus.Sent && + aggregate.DeliveryStatusList[aggregate.ResendCount] != MessageStatus.Delivered){ + throw new InvalidOperationException($"Cannot re-send a message to provider that has not already been sent. Current Status [{aggregate.DeliveryStatusList[aggregate.ResendCount]}]"); + } - /// - /// Marks the message as undeliverable. - /// - /// The provider status. - /// The failed date time. - public void MarkMessageAsUndeliverable(String providerStatus, - DateTime failedDateTime) - { - this.CheckMessageCanBeSetToUndeliverable(); - - SMSMessageUndeliveredEvent messageUndeliveredEvent = new SMSMessageUndeliveredEvent(this.AggregateId, providerStatus, failedDateTime); + RequestResentToSMSProviderEvent requestResentToSMSProviderEvent = new RequestResentToSMSProviderEvent(aggregate.AggregateId); - this.ApplyAndAppend(messageUndeliveredEvent); + aggregate.ApplyAndAppend(requestResentToSMSProviderEvent); } - /// - /// Checks the message can be set to expired. - /// - /// Message at status {this.MessageStatus} cannot be set to expired - private void CheckMessageCanBeSetToExpired() - { - if (this.DeliveryStatusList[this.ResendCount] != MessageStatus.Sent) - { - throw new InvalidOperationException($"Message at status {this.DeliveryStatusList[this.ResendCount]} cannot be set to expired"); + public static void SendRequestToProvider(this SMSAggregate aggregate, + String sender, + String destination, + String message){ + if (aggregate.DeliveryStatusList[aggregate.ResendCount] != MessageStatus.NotSet){ + throw new InvalidOperationException("Cannot send a message to provider that has already been sent"); } + + RequestSentToSMSProviderEvent requestSentToProviderEvent = new RequestSentToSMSProviderEvent(aggregate.AggregateId, sender, destination, message); + + aggregate.ApplyAndAppend(requestSentToProviderEvent); } - /// - /// Checks the message can be set to rejected. - /// - /// Message at status {this.MessageStatus} cannot be set to rejected - private void CheckMessageCanBeSetToRejected() - { - if (this.DeliveryStatusList[this.ResendCount] != MessageStatus.Sent) - { - throw new InvalidOperationException($"Message at status {this.DeliveryStatusList[this.ResendCount]} cannot be set to rejected"); + private static void CheckMessageCanBeSetToDelivered(this SMSAggregate aggregate){ + if (aggregate.DeliveryStatusList[aggregate.ResendCount] != MessageStatus.Sent){ + throw new InvalidOperationException($"Message at status {aggregate.DeliveryStatusList[aggregate.ResendCount]} cannot be set to delivered"); } } - /// - /// Checks the message can be set to delivered. - /// - /// Message at status {this.MessageStatus} cannot be set to delivered - private void CheckMessageCanBeSetToDelivered() - { - if (this.DeliveryStatusList[this.ResendCount] != MessageStatus.Sent) - { - throw new InvalidOperationException($"Message at status {this.DeliveryStatusList[this.ResendCount]} cannot be set to delivered"); + + private static void CheckMessageCanBeSetToExpired(this SMSAggregate aggregate){ + if (aggregate.DeliveryStatusList[aggregate.ResendCount] != MessageStatus.Sent){ + throw new InvalidOperationException($"Message at status {aggregate.DeliveryStatusList[aggregate.ResendCount]} cannot be set to expired"); } } - /// - /// Checks the message can be set to undeliverable. - /// - /// Message at status {this.MessageStatus} cannot be set to undeliverable - private void CheckMessageCanBeSetToUndeliverable() - { - if (this.DeliveryStatusList[this.ResendCount] != MessageStatus.Sent) - { - throw new InvalidOperationException($"Message at status {this.DeliveryStatusList[this.ResendCount]} cannot be set to undeliverable"); + private static void CheckMessageCanBeSetToRejected(this SMSAggregate aggregate){ + if (aggregate.DeliveryStatusList[aggregate.ResendCount] != MessageStatus.Sent){ + throw new InvalidOperationException($"Message at status {aggregate.DeliveryStatusList[aggregate.ResendCount]} cannot be set to rejected"); } } - /// - /// Gets the metadata. - /// - /// - [ExcludeFromCodeCoverage] - protected override Object GetMetadata() - { - return null; + private static void CheckMessageCanBeSetToUndeliverable(this SMSAggregate aggregate){ + if (aggregate.DeliveryStatusList[aggregate.ResendCount] != MessageStatus.Sent){ + throw new InvalidOperationException($"Message at status {aggregate.DeliveryStatusList[aggregate.ResendCount]} cannot be set to undeliverable"); + } } - /// - /// Plays the event. - /// - /// The domain event. - public override void PlayEvent(IDomainEvent domainEvent) - { - this.PlayEvent((dynamic)domainEvent); - } + #endregion + } - private void PlayEvent(Object @event) - { - Exception ex = new Exception($"Failed to apply event {@event.GetType()} to Aggregate {this.GetType().Name}"); + public record SMSAggregate : Aggregate{ + #region Fields - Logger.LogCritical(ex); - throw ex; - } + internal List DeliveryStatusList; - /// - /// Plays the event. - /// - /// The domain event. - private void PlayEvent(RequestSentToSMSProviderEvent domainEvent) - { - this.Sender = domainEvent.Sender; - this.Destination = domainEvent.Destination; - this.Message = domainEvent.Message; - this.DeliveryStatusList[this.ResendCount] = MessageStatus.InProgress; - } + #endregion - /// - /// Plays the event. - /// - /// The domain event. - private void PlayEvent(ResponseReceivedFromSMSProviderEvent domainEvent) - { - this.ProviderReference = domainEvent.ProviderSMSReference; - this.DeliveryStatusList[this.ResendCount] = MessageStatus.Sent; - } + #region Constructors - /// - /// Plays the event. - /// - /// The domain event. - private void PlayEvent(SMSMessageExpiredEvent domainEvent) - { - this.DeliveryStatusList[this.ResendCount] = MessageStatus.Expired; + [ExcludeFromCodeCoverage] + public SMSAggregate(){ + this.DeliveryStatusList = new List{ + MessageStatus.NotSet + }; } - /// - /// Plays the event. - /// - /// The domain event. - private void PlayEvent(SMSMessageDeliveredEvent domainEvent) - { - this.DeliveryStatusList[this.ResendCount] = MessageStatus.Delivered; - } + private SMSAggregate(Guid aggregateId){ + Guard.ThrowIfInvalidGuid(aggregateId, "Aggregate Id cannot be an Empty Guid"); - /// - /// Plays the event. - /// - /// The domain event. - private void PlayEvent(SMSMessageRejectedEvent domainEvent) - { - this.DeliveryStatusList[this.ResendCount] = MessageStatus.Rejected; + this.AggregateId = aggregateId; + this.MessageId = aggregateId; + this.DeliveryStatusList = new List{ + MessageStatus.NotSet + }; } - /// - /// Plays the event. - /// - /// The domain event. - private void PlayEvent(SMSMessageUndeliveredEvent domainEvent) - { - this.DeliveryStatusList[this.ResendCount] = MessageStatus.Undeliverable; - } + #endregion - public Int32 ResendCount { get; private set; } - private List DeliveryStatusList; + #region Properties - public void ResendRequestToProvider() - { - if (this.DeliveryStatusList[this.ResendCount] != MessageStatus.Sent && - this.DeliveryStatusList[this.ResendCount] != MessageStatus.Delivered) - { - throw new InvalidOperationException($"Cannot re-send a message to provider that has not already been sent. Current Status [{this.DeliveryStatusList[this.ResendCount]}]"); - } + public String Destination{ get; internal set; } - RequestResentToSMSProviderEvent requestResentToSMSProviderEvent = new RequestResentToSMSProviderEvent(this.AggregateId); + public String Message{ get; internal set; } - this.ApplyAndAppend(requestResentToSMSProviderEvent); - } + public Guid MessageId{ get; internal set; } - public MessageStatus GetDeliveryStatus(Int32? resendAttempt = null) - { - if (resendAttempt.HasValue == false) - { - return this.DeliveryStatusList[this.ResendCount]; - } - return this.DeliveryStatusList[resendAttempt.Value]; + public String ProviderReference{ get; internal set; } + + public Int32 ResendCount{ get; internal set; } + + public String Sender{ get; internal set; } + + #endregion + + #region Methods + + public static SMSAggregate Create(Guid aggregateId){ + return new SMSAggregate(aggregateId); } - private void PlayEvent(RequestResentToSMSProviderEvent domainEvent) - { - this.ResendCount++; - this.DeliveryStatusList.Add(MessageStatus.InProgress); + public override void PlayEvent(IDomainEvent domainEvent) => SMSAggregateExtensions.PlayEvent(this, (dynamic)domainEvent); + + [ExcludeFromCodeCoverage] + protected override Object GetMetadata(){ + return null; } + + #endregion } -} +} \ No newline at end of file diff --git a/MessagingService.Tests/MessagingService.Tests.csproj b/MessagingService.Tests/MessagingService.Tests.csproj index a2a8012..70e8370 100644 --- a/MessagingService.Tests/MessagingService.Tests.csproj +++ b/MessagingService.Tests/MessagingService.Tests.csproj @@ -7,17 +7,17 @@ - + - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/MessagingService/Bootstrapper/MediatorRegistry.cs b/MessagingService/Bootstrapper/MediatorRegistry.cs index d7cf363..e6d9f96 100644 --- a/MessagingService/Bootstrapper/MediatorRegistry.cs +++ b/MessagingService/Bootstrapper/MediatorRegistry.cs @@ -24,11 +24,5 @@ public MediatorRegistry() { return ConfigurationReader.GetBaseServerUri(serviceName).OriginalString; }); - - // request & notification handlers - this.AddTransient(context => - { - return t => context.GetService(t); - }); } } \ No newline at end of file diff --git a/MessagingService/MessagingService.csproj b/MessagingService/MessagingService.csproj index 7bb8aa8..eaac880 100644 --- a/MessagingService/MessagingService.csproj +++ b/MessagingService/MessagingService.csproj @@ -10,24 +10,24 @@ - - + + - - + + - - + + - - - + + + - - - + + +