Skip to content

Commit 031bfd9

Browse files
Merge pull request #139 from TransactionProcessing/task/#105_storeemailattachments
Fix failed Email Proxy call and record error better
2 parents 0eb0482 + de0a74e commit 031bfd9

File tree

25 files changed

+215
-950
lines changed

25 files changed

+215
-950
lines changed

MessagingService.BusinessLogic.Tests/Services/MessagingDomainServiceTests.cs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,70 @@ await messagingDomainService.SendEmailMessage(TestData.ConnectionIdentifier,
5252
CancellationToken.None);
5353
}
5454

55+
[Fact]
56+
public async Task MessagingDomainService_SendEmailMessage_EmailSentFailed_APICallFailed_MessageFailed()
57+
{
58+
Mock<IAggregateRepository<EmailAggregate, DomainEvent>> emailAggregateRepository = new Mock<IAggregateRepository<EmailAggregate, DomainEvent>>();
59+
emailAggregateRepository.Setup(a => a.GetLatestVersion(It.IsAny<Guid>(), It.IsAny<CancellationToken>())).ReturnsAsync(TestData.GetEmptyEmailAggregate());
60+
Mock<IAggregateRepository<SMSAggregate, DomainEvent>> smsAggregateRepository = new Mock<IAggregateRepository<SMSAggregate, DomainEvent>>();
61+
Mock<IEmailServiceProxy> emailServiceProxy = new Mock<IEmailServiceProxy>();
62+
emailServiceProxy
63+
.Setup(e => e.SendEmail(It.IsAny<Guid>(),
64+
It.IsAny<String>(),
65+
It.IsAny<List<String>>(),
66+
It.IsAny<String>(),
67+
It.IsAny<String>(),
68+
It.IsAny<Boolean>(),
69+
It.IsAny<List<EmailAttachment>>(),
70+
It.IsAny<CancellationToken>())).ReturnsAsync(TestData.FailedAPICallEmailServiceProxyResponse);
71+
Mock<ISMSServiceProxy> smsServiceProxy = new Mock<ISMSServiceProxy>();
72+
73+
MessagingDomainService messagingDomainService =
74+
new MessagingDomainService(emailAggregateRepository.Object, smsAggregateRepository.Object, emailServiceProxy.Object, smsServiceProxy.Object);
75+
76+
await messagingDomainService.SendEmailMessage(TestData.ConnectionIdentifier,
77+
TestData.MessageId,
78+
TestData.FromAddress,
79+
TestData.ToAddresses,
80+
TestData.Subject,
81+
TestData.Body,
82+
TestData.IsHtmlTrue,
83+
TestData.EmailAttachmentModels,
84+
CancellationToken.None);
85+
}
86+
87+
[Fact]
88+
public async Task MessagingDomainService_SendEmailMessage_EmailSentFailed_APIResponseError_MessageFailed()
89+
{
90+
Mock<IAggregateRepository<EmailAggregate, DomainEvent>> emailAggregateRepository = new Mock<IAggregateRepository<EmailAggregate, DomainEvent>>();
91+
emailAggregateRepository.Setup(a => a.GetLatestVersion(It.IsAny<Guid>(), It.IsAny<CancellationToken>())).ReturnsAsync(TestData.GetEmptyEmailAggregate());
92+
Mock<IAggregateRepository<SMSAggregate, DomainEvent>> smsAggregateRepository = new Mock<IAggregateRepository<SMSAggregate, DomainEvent>>();
93+
Mock<IEmailServiceProxy> emailServiceProxy = new Mock<IEmailServiceProxy>();
94+
emailServiceProxy
95+
.Setup(e => e.SendEmail(It.IsAny<Guid>(),
96+
It.IsAny<String>(),
97+
It.IsAny<List<String>>(),
98+
It.IsAny<String>(),
99+
It.IsAny<String>(),
100+
It.IsAny<Boolean>(),
101+
It.IsAny<List<EmailAttachment>>(),
102+
It.IsAny<CancellationToken>())).ReturnsAsync(TestData.FailedEmailServiceProxyResponse);
103+
Mock<ISMSServiceProxy> smsServiceProxy = new Mock<ISMSServiceProxy>();
104+
105+
MessagingDomainService messagingDomainService =
106+
new MessagingDomainService(emailAggregateRepository.Object, smsAggregateRepository.Object, emailServiceProxy.Object, smsServiceProxy.Object);
107+
108+
await messagingDomainService.SendEmailMessage(TestData.ConnectionIdentifier,
109+
TestData.MessageId,
110+
TestData.FromAddress,
111+
TestData.ToAddresses,
112+
TestData.Subject,
113+
TestData.Body,
114+
TestData.IsHtmlTrue,
115+
TestData.EmailAttachmentModels,
116+
CancellationToken.None);
117+
}
118+
55119
[Fact]
56120
public async Task MessagingDomainService_ResendEmailMessage_MessageSent()
57121
{

MessagingService.BusinessLogic/Services/EmailServices/EmailServiceProxyResponse.cs

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,44 +10,14 @@
1010
[ExcludeFromCodeCoverage]
1111
public class EmailServiceProxyResponse
1212
{
13-
/// <summary>
14-
/// Gets or sets the API status code.
15-
/// </summary>
16-
/// <value>
17-
/// The API status code.
18-
/// </value>
19-
public HttpStatusCode ApiStatusCode { get; set; }
13+
public Boolean ApiCallSuccessful { get; set; }
2014

21-
/// <summary>
22-
/// Gets or sets the request identifier.
23-
/// </summary>
24-
/// <value>
25-
/// The request identifier.
26-
/// </value>
2715
public String RequestIdentifier { get; set; }
2816

29-
/// <summary>
30-
/// Gets or sets the email identifier.
31-
/// </summary>
32-
/// <value>
33-
/// The email identifier.
34-
/// </value>
3517
public String EmailIdentifier { get; set; }
3618

37-
/// <summary>
38-
/// Gets or sets the error code.
39-
/// </summary>
40-
/// <value>
41-
/// The error code.
42-
/// </value>
4319
public String ErrorCode { get; set; }
4420

45-
/// <summary>
46-
/// Gets or sets the error.
47-
/// </summary>
48-
/// <value>
49-
/// The error.
50-
/// </value>
5121
public String Error { get; set; }
5222
}
5323
}

MessagingService.BusinessLogic/Services/EmailServices/IntegrationTest/IntegrationTestEmailServiceProxy.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public async Task<EmailServiceProxyResponse> SendEmail(Guid messageId,
6262
{
6363
RequestIdentifier = "requestid",
6464
EmailIdentifier = "emailid",
65-
ApiStatusCode = HttpStatusCode.OK,
65+
ApiCallSuccessful = true,
6666
Error = string.Empty,
6767
ErrorCode = string.Empty
6868
};

MessagingService.BusinessLogic/Services/EmailServices/Smtp2Go/Smtp2GoProxy.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,20 +102,31 @@ public async Task<EmailServiceProxyResponse> SendEmail(Guid messageId,
102102

103103
StringContent content = new StringContent(requestSerialised, Encoding.UTF8, "application/json");
104104

105-
String requestUri = $"{ConfigurationReader.GetValue("SMTP2GoBaseAddress")}/email/send";
105+
String requestUri = $"{ConfigurationReader.GetValue("SMTP2GoBaseAddress")}email/send";
106106
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, requestUri);
107107
requestMessage.Content = content;
108108

109109
HttpResponseMessage httpResponse = await this.HttpClient.SendAsync(requestMessage, cancellationToken);
110110

111-
Smtp2GoSendEmailResponse apiResponse = JsonConvert.DeserializeObject<Smtp2GoSendEmailResponse>(await httpResponse.Content.ReadAsStringAsync());
111+
Smtp2GoSendEmailResponse apiResponse = new Smtp2GoSendEmailResponse(){
112+
Data = new Smtp2GoSendEmailResponseData()
113+
};
114+
if (httpResponse.IsSuccessStatusCode){
115+
apiResponse = JsonConvert.DeserializeObject<Smtp2GoSendEmailResponse>(await httpResponse.Content.ReadAsStringAsync());
116+
}
117+
else{
118+
apiResponse = new Smtp2GoSendEmailResponse();
119+
apiResponse.Data = new Smtp2GoSendEmailResponseData();
120+
apiResponse.Data.Error = httpResponse.StatusCode.ToString();
121+
apiResponse.Data.ErrorCode = ((Int32)httpResponse.StatusCode).ToString();
122+
}
112123

113124
Logger.LogDebug($"Response Message Received from Email Provider [SMTP2Go] {JsonConvert.SerializeObject(apiResponse)}");
114125

115126
// Translate the Response
116127
response = new EmailServiceProxyResponse
117128
{
118-
ApiStatusCode = httpResponse.StatusCode,
129+
ApiCallSuccessful = httpResponse.IsSuccessStatusCode && String.IsNullOrEmpty(apiResponse.Data.ErrorCode),
119130
EmailIdentifier = apiResponse.Data.EmailId,
120131
Error = apiResponse.Data.Error,
121132
ErrorCode = apiResponse.Data.ErrorCode,

MessagingService.BusinessLogic/Services/MessagingDomainService.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,13 @@ public async Task SendEmailMessage(Guid connectionIdentifier,
7171
EmailServiceProxyResponse emailResponse =
7272
await this.EmailServiceProxy.SendEmail(messageId, fromAddress, toAddresses, subject, body, isHtml, attachments, cancellationToken);
7373

74-
// response message from provider (record event)
75-
emailAggregate.ReceiveResponseFromProvider(emailResponse.RequestIdentifier, emailResponse.EmailIdentifier);
74+
if (emailResponse.ApiCallSuccessful){
75+
// response message from provider (record event)
76+
emailAggregate.ReceiveResponseFromProvider(emailResponse.RequestIdentifier, emailResponse.EmailIdentifier);
77+
}
78+
else{
79+
emailAggregate.ReceiveBadResponseFromProvider(emailResponse.Error,emailResponse.ErrorCode);
80+
}
7681

7782
// Save Changes to persistance
7883
await this.EmailAggregateRepository.SaveChanges(emailAggregate, cancellationToken);

MessagingService.EmailAggregate.Tests/EmailAggregateTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,20 @@ public void EmailAggregate_ReceiveResponseFromProvider_ResponseReceived() {
6565
messageStatus.ShouldBe(MessageStatus.Sent);
6666
}
6767

68+
[Fact]
69+
public void EmailAggregate_ReceiveBadResponseFromProvider_ResponseReceived()
70+
{
71+
EmailAggregate emailAggregate = EmailAggregate.Create(TestData.MessageId);
72+
73+
emailAggregate.SendRequestToProvider(TestData.FromAddress, TestData.ToAddresses, TestData.Subject, TestData.Body, TestData.IsHtmlTrue, TestData.EmailAttachmentModels);
74+
emailAggregate.ReceiveBadResponseFromProvider(TestData.EmailError, TestData.EmailErrorCode);
75+
76+
emailAggregate.Error.ShouldBe(TestData.EmailError);
77+
emailAggregate.ErrorCode.ShouldBe(TestData.EmailErrorCode);
78+
MessageStatus messageStatus = emailAggregate.GetDeliveryStatus();
79+
messageStatus.ShouldBe(MessageStatus.Failed);
80+
}
81+
6882
[Fact]
6983
public void EmailAggregate_MarkMessageAsDelivered_MessageMarkedAsDelivered() {
7084
EmailAggregate emailAggregate = EmailAggregate.Create(TestData.MessageId);
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
namespace MessagingService.EmailMessage.DomainEvents;
2+
3+
using System;
4+
using System.Collections.Generic;
5+
using Shared.DomainDrivenDesign.EventSourcing;
6+
7+
public record ResponseReceivedFromEmailProviderEvent(Guid MessageId,
8+
String ProviderRequestReference,
9+
String ProviderEmailReference) : DomainEvent(MessageId, Guid.NewGuid());
10+
11+
public record BadResponseReceivedFromEmailProviderEvent(Guid MessageId,
12+
String ErrorCode,
13+
String Error) : DomainEvent(MessageId, Guid.NewGuid());
14+
15+
public record EmailMessageBouncedEvent(Guid MessageId,
16+
String ProviderStatus,
17+
DateTime BouncedDateTime) : DomainEvent(MessageId, Guid.NewGuid());
18+
19+
public record EmailMessageDeliveredEvent(Guid MessageId,
20+
String ProviderStatus,
21+
DateTime DeliveredDateTime) : DomainEvent(MessageId, Guid.NewGuid());
22+
23+
public record EmailMessageFailedEvent(Guid MessageId,
24+
String ProviderStatus,
25+
DateTime FailedDateTime) : DomainEvent(MessageId, Guid.NewGuid());
26+
27+
public record EmailMessageMarkedAsSpamEvent(Guid MessageId,
28+
String ProviderStatus,
29+
DateTime SpamDateTime) : DomainEvent(MessageId, Guid.NewGuid());
30+
31+
public record EmailMessageRejectedEvent(Guid MessageId,
32+
String ProviderStatus,
33+
DateTime RejectedDateTime) : DomainEvent(MessageId, Guid.NewGuid());
34+
35+
public record RequestResentToEmailProviderEvent(Guid MessageId) : DomainEvent(MessageId, Guid.NewGuid());
36+
37+
public record EmailAttachmentRequestSentToProviderEvent(Guid MessageId, String Filename, String FileData, Int32 FileType) : DomainEvent(MessageId, Guid.NewGuid());
38+
39+
public record RequestSentToEmailProviderEvent(Guid MessageId,
40+
String FromAddress,
41+
List<String> ToAddresses,
42+
String Subject,
43+
String Body,
44+
Boolean IsHtml) : DomainEvent(MessageId, Guid.NewGuid());

MessagingService.EmailMessage.DomainEvents/EmailMessageBouncedEvent.cs

Lines changed: 0 additions & 55 deletions
This file was deleted.

MessagingService.EmailMessage.DomainEvents/EmailMessageDeliveredEvent.cs

Lines changed: 0 additions & 55 deletions
This file was deleted.

0 commit comments

Comments
 (0)