Skip to content

Commit a7ef5f4

Browse files
Message delivery status handling added
1 parent fa3fd14 commit a7ef5f4

32 files changed

+2178
-93
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
namespace MessagingService.BusinessLogic.Tests.DomainEventHanders
2+
{
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using EmailMessage.DomainEvents;
7+
using EventHandling;
8+
using Moq;
9+
using Shouldly;
10+
using Testing;
11+
using Xunit;
12+
13+
public class DomainEventHandlerResolverTests
14+
{
15+
[Fact]
16+
public void DomainEventHandlerResolver_CanBeCreated_IsCreated()
17+
{
18+
Dictionary<String, String[]> eventHandlerConfiguration = new Dictionary<String, String[]>();
19+
20+
eventHandlerConfiguration.Add("TestEventType1", new String[] { "MessagingService.BusinessLogic.EventHandling.EmailDomainEventHandler" });
21+
22+
Mock<IDomainEventHandler> domainEventHandler = new Mock<IDomainEventHandler>();
23+
Func<Type, IDomainEventHandler> createDomainEventHandlerFunc = (type) => { return domainEventHandler.Object; };
24+
DomainEventHandlerResolver resolver = new DomainEventHandlerResolver(eventHandlerConfiguration, createDomainEventHandlerFunc);
25+
26+
resolver.ShouldNotBeNull();
27+
}
28+
29+
[Fact]
30+
public void DomainEventHandlerResolver_CanBeCreated_InvalidEventHandlerType_ErrorThrown()
31+
{
32+
Dictionary<String, String[]> eventHandlerConfiguration = new Dictionary<String, String[]>();
33+
34+
eventHandlerConfiguration.Add("TestEventType1", new String[] { "MessagingService.BusinessLogic.EventHandling.NonExistantDomainEventHandler" });
35+
36+
Mock<IDomainEventHandler> domainEventHandler = new Mock<IDomainEventHandler>();
37+
Func<Type, IDomainEventHandler> createDomainEventHandlerFunc = (type) => { return domainEventHandler.Object; };
38+
39+
Should.Throw<NotSupportedException>(() => new DomainEventHandlerResolver(eventHandlerConfiguration, createDomainEventHandlerFunc));
40+
}
41+
42+
[Fact]
43+
public void DomainEventHandlerResolver_GetDomainEventHandlers_ResponseReceivedFromProviderEvent_EventHandlersReturned()
44+
{
45+
String handlerTypeName = "MessagingService.BusinessLogic.EventHandling.EmailDomainEventHandler";
46+
Dictionary<String, String[]> eventHandlerConfiguration = new Dictionary<String, String[]>();
47+
48+
ResponseReceivedFromProviderEvent responseReceivedFromProviderEvent = TestData.ResponseReceivedFromProviderEvent;
49+
50+
eventHandlerConfiguration.Add(responseReceivedFromProviderEvent.GetType().FullName, new String[] { handlerTypeName });
51+
52+
Mock<IDomainEventHandler> domainEventHandler = new Mock<IDomainEventHandler>();
53+
Func<Type, IDomainEventHandler> createDomainEventHandlerFunc = (type) => { return domainEventHandler.Object; };
54+
55+
DomainEventHandlerResolver resolver = new DomainEventHandlerResolver(eventHandlerConfiguration, createDomainEventHandlerFunc);
56+
57+
List<IDomainEventHandler> handlers = resolver.GetDomainEventHandlers(responseReceivedFromProviderEvent);
58+
59+
handlers.ShouldNotBeNull();
60+
handlers.Any().ShouldBeTrue();
61+
handlers.Count.ShouldBe(1);
62+
}
63+
64+
[Fact]
65+
public void DomainEventHandlerResolver_GetDomainEventHandlers_ResponseReceivedFromProviderEvent_EventNotConfigured_EventHandlersReturned()
66+
{
67+
String handlerTypeName = "MessagingService.BusinessLogic.EventHandling.EmailDomainEventHandler";
68+
Dictionary<String, String[]> eventHandlerConfiguration = new Dictionary<String, String[]>();
69+
70+
ResponseReceivedFromProviderEvent responseReceivedFromProviderEvent = TestData.ResponseReceivedFromProviderEvent;
71+
72+
eventHandlerConfiguration.Add("RandomEvent", new String[] { handlerTypeName });
73+
Mock<IDomainEventHandler> domainEventHandler = new Mock<IDomainEventHandler>();
74+
Func<Type, IDomainEventHandler> createDomainEventHandlerFunc = (type) => { return domainEventHandler.Object; };
75+
76+
DomainEventHandlerResolver resolver = new DomainEventHandlerResolver(eventHandlerConfiguration, createDomainEventHandlerFunc);
77+
78+
List<IDomainEventHandler> handlers = resolver.GetDomainEventHandlers(responseReceivedFromProviderEvent);
79+
80+
handlers.ShouldBeNull();
81+
}
82+
83+
[Fact]
84+
public void DomainEventHandlerResolver_GetDomainEventHandlers_ResponseReceivedFromProviderEvent_NoHandlersConfigured_EventHandlersReturned()
85+
{
86+
Dictionary<String, String[]> eventHandlerConfiguration = new Dictionary<String, String[]>();
87+
88+
ResponseReceivedFromProviderEvent responseReceivedFromProviderEvent = TestData.ResponseReceivedFromProviderEvent;
89+
Mock<IDomainEventHandler> domainEventHandler = new Mock<IDomainEventHandler>();
90+
91+
Func<Type, IDomainEventHandler> createDomainEventHandlerFunc = (type) => { return domainEventHandler.Object; };
92+
93+
DomainEventHandlerResolver resolver = new DomainEventHandlerResolver(eventHandlerConfiguration, createDomainEventHandlerFunc);
94+
95+
List<IDomainEventHandler> handlers = resolver.GetDomainEventHandlers(responseReceivedFromProviderEvent);
96+
97+
handlers.ShouldBeNull();
98+
}
99+
100+
}
101+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
using System;
2+
using System.Text;
3+
4+
namespace MessagingService.BusinessLogic.Tests.DomainEventHanders
5+
{
6+
using System.Threading;
7+
using BusinessLogic.Services.EmailServices;
8+
using EmailMessageAggregate;
9+
using EventHandling;
10+
using Moq;
11+
using Shared.EventStore.EventStore;
12+
using System.Threading.Tasks;
13+
using Testing;
14+
using Xunit;
15+
16+
public class EmailDomainEventHandlerTests
17+
{
18+
[Fact]
19+
public async Task EmailDomainEventHandler_Handle_ResponseReceivedFromProviderEvent_Delivered_EventIsHandled()
20+
{
21+
Mock<IAggregateRepository<EmailAggregate>> aggregateRepository = new Mock<IAggregateRepository<EmailAggregate>>();
22+
aggregateRepository.Setup(a => a.GetLatestVersion(It.IsAny<Guid>(), It.IsAny<CancellationToken>())).ReturnsAsync(TestData.GetSentEmailAggregate);
23+
Mock<IEmailServiceProxy> emailServiceProxy = new Mock<IEmailServiceProxy>();
24+
emailServiceProxy.Setup(e => e.GetMessageStatus(It.IsAny<String>(), It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()))
25+
.ReturnsAsync(TestData.MessageStatusResponseDelivered);
26+
27+
EmailDomainEventHandler emailDomainEventHandler = new EmailDomainEventHandler(aggregateRepository.Object,
28+
emailServiceProxy.Object);
29+
30+
await emailDomainEventHandler.Handle(TestData.ResponseReceivedFromProviderEvent, CancellationToken.None);
31+
}
32+
33+
[Fact]
34+
public async Task EmailDomainEventHandler_Handle_ResponseReceivedFromProviderEvent_Failed_EventIsHandled()
35+
{
36+
Mock<IAggregateRepository<EmailAggregate>> aggregateRepository = new Mock<IAggregateRepository<EmailAggregate>>();
37+
aggregateRepository.Setup(a => a.GetLatestVersion(It.IsAny<Guid>(), It.IsAny<CancellationToken>())).ReturnsAsync(TestData.GetSentEmailAggregate);
38+
Mock<IEmailServiceProxy> emailServiceProxy = new Mock<IEmailServiceProxy>();
39+
emailServiceProxy.Setup(e => e.GetMessageStatus(It.IsAny<String>(), It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()))
40+
.ReturnsAsync(TestData.MessageStatusResponseFailed);
41+
42+
EmailDomainEventHandler emailDomainEventHandler = new EmailDomainEventHandler(aggregateRepository.Object,
43+
emailServiceProxy.Object);
44+
45+
await emailDomainEventHandler.Handle(TestData.ResponseReceivedFromProviderEvent, CancellationToken.None);
46+
}
47+
48+
[Fact]
49+
public async Task EmailDomainEventHandler_Handle_ResponseReceivedFromProviderEvent_Rejected_EventIsHandled()
50+
{
51+
Mock<IAggregateRepository<EmailAggregate>> aggregateRepository = new Mock<IAggregateRepository<EmailAggregate>>();
52+
aggregateRepository.Setup(a => a.GetLatestVersion(It.IsAny<Guid>(), It.IsAny<CancellationToken>())).ReturnsAsync(TestData.GetSentEmailAggregate);
53+
Mock<IEmailServiceProxy> emailServiceProxy = new Mock<IEmailServiceProxy>();
54+
emailServiceProxy.Setup(e => e.GetMessageStatus(It.IsAny<String>(), It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()))
55+
.ReturnsAsync(TestData.MessageStatusResponseRejected);
56+
57+
EmailDomainEventHandler emailDomainEventHandler = new EmailDomainEventHandler(aggregateRepository.Object,
58+
emailServiceProxy.Object);
59+
60+
await emailDomainEventHandler.Handle(TestData.ResponseReceivedFromProviderEvent, CancellationToken.None);
61+
}
62+
63+
[Fact]
64+
public async Task EmailDomainEventHandler_Handle_ResponseReceivedFromProviderEvent_Bounced_EventIsHandled()
65+
{
66+
Mock<IAggregateRepository<EmailAggregate>> aggregateRepository = new Mock<IAggregateRepository<EmailAggregate>>();
67+
aggregateRepository.Setup(a => a.GetLatestVersion(It.IsAny<Guid>(), It.IsAny<CancellationToken>())).ReturnsAsync(TestData.GetSentEmailAggregate);
68+
Mock<IEmailServiceProxy> emailServiceProxy = new Mock<IEmailServiceProxy>();
69+
emailServiceProxy.Setup(e => e.GetMessageStatus(It.IsAny<String>(), It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()))
70+
.ReturnsAsync(TestData.MessageStatusResponseBounced);
71+
72+
EmailDomainEventHandler emailDomainEventHandler = new EmailDomainEventHandler(aggregateRepository.Object,
73+
emailServiceProxy.Object);
74+
75+
await emailDomainEventHandler.Handle(TestData.ResponseReceivedFromProviderEvent, CancellationToken.None);
76+
}
77+
78+
[Fact]
79+
public async Task EmailDomainEventHandler_Handle_ResponseReceivedFromProviderEvent_Spam_EventIsHandled()
80+
{
81+
Mock<IAggregateRepository<EmailAggregate>> aggregateRepository = new Mock<IAggregateRepository<EmailAggregate>>();
82+
aggregateRepository.Setup(a => a.GetLatestVersion(It.IsAny<Guid>(), It.IsAny<CancellationToken>())).ReturnsAsync(TestData.GetSentEmailAggregate);
83+
Mock<IEmailServiceProxy> emailServiceProxy = new Mock<IEmailServiceProxy>();
84+
emailServiceProxy.Setup(e => e.GetMessageStatus(It.IsAny<String>(), It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()))
85+
.ReturnsAsync(TestData.MessageStatusResponseSpam);
86+
87+
EmailDomainEventHandler emailDomainEventHandler = new EmailDomainEventHandler(aggregateRepository.Object,
88+
emailServiceProxy.Object);
89+
90+
await emailDomainEventHandler.Handle(TestData.ResponseReceivedFromProviderEvent, CancellationToken.None);
91+
}
92+
93+
[Fact]
94+
public async Task EmailDomainEventHandler_Handle_ResponseReceivedFromProviderEvent_Unknown_EventIsHandled()
95+
{
96+
Mock<IAggregateRepository<EmailAggregate>> aggregateRepository = new Mock<IAggregateRepository<EmailAggregate>>();
97+
aggregateRepository.Setup(a => a.GetLatestVersion(It.IsAny<Guid>(), It.IsAny<CancellationToken>())).ReturnsAsync(TestData.GetSentEmailAggregate);
98+
Mock<IEmailServiceProxy> emailServiceProxy = new Mock<IEmailServiceProxy>();
99+
emailServiceProxy.Setup(e => e.GetMessageStatus(It.IsAny<String>(), It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()))
100+
.ReturnsAsync(TestData.MessageStatusResponseUnknown);
101+
102+
EmailDomainEventHandler emailDomainEventHandler = new EmailDomainEventHandler(aggregateRepository.Object,
103+
emailServiceProxy.Object);
104+
105+
await emailDomainEventHandler.Handle(TestData.ResponseReceivedFromProviderEvent, CancellationToken.None);
106+
}
107+
}
108+
}

MessagingService.BusinessLogic.Tests/Services/EmailDomainServiceTests.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace MessagingService.BusinessLogic.Tests.Services
1717
public class EmailDomainServiceTests
1818
{
1919
[Fact]
20-
public async Task TransactionDomainService_ProcessLogonTransaction_TransactionIsProcessed()
20+
public async Task EmailDomainService_SendEmailMessage_MessageSent()
2121
{
2222
Mock<IAggregateRepository<EmailAggregate>> aggregateRepository = new Mock<IAggregateRepository<EmailAggregate>>();
2323
aggregateRepository.Setup(a => a.GetLatestVersion(It.IsAny<Guid>(), It.IsAny<CancellationToken>())).ReturnsAsync(TestData.GetEmptyEmailAggregate());
@@ -30,11 +30,7 @@ public async Task TransactionDomainService_ProcessLogonTransaction_TransactionIs
3030
It.IsAny<String>(),
3131
It.IsAny<Boolean>(),
3232
It.IsAny<CancellationToken>())).ReturnsAsync(TestData.SuccessfulEmailServiceProxyResponse);
33-
//IConfigurationRoot configurationRoot = new ConfigurationBuilder().AddInMemoryCollection(TestData.DefaultAppSettings).Build();
34-
//ConfigurationReader.Initialise(configurationRoot);
35-
36-
//Logger.Initialise(NullLogger.Instance);
37-
33+
3834
EmailDomainService emailDomainService =
3935
new EmailDomainService(aggregateRepository.Object, emailServiceProxy.Object);
4036

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
namespace MessagingService.BusinessLogic.EventHandling
2+
{
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using Shared.DomainDrivenDesign.EventSourcing;
7+
8+
public class DomainEventHandlerResolver : IDomainEventHandlerResolver
9+
{
10+
#region Fields
11+
12+
/// <summary>
13+
/// The domain event handlers
14+
/// </summary>
15+
private readonly Dictionary<String, IDomainEventHandler> DomainEventHandlers;
16+
17+
/// <summary>
18+
/// The event handler configuration
19+
/// </summary>
20+
private readonly Dictionary<String, String[]> EventHandlerConfiguration;
21+
22+
#endregion
23+
24+
#region Constructors
25+
26+
/// <summary>
27+
/// Initializes a new instance of the <see cref="DomainEventHandlerResolver" /> class.
28+
/// </summary>
29+
/// <param name="eventHandlerConfiguration">The event handler configuration.</param>
30+
public DomainEventHandlerResolver(Dictionary<String, String[]> eventHandlerConfiguration, Func<Type, IDomainEventHandler> createEventHandlerResolver)
31+
{
32+
this.EventHandlerConfiguration = eventHandlerConfiguration;
33+
34+
this.DomainEventHandlers = new Dictionary<String, IDomainEventHandler>();
35+
36+
List<String> handlers = new List<String>();
37+
38+
// Precreate the Event Handlers here
39+
foreach (KeyValuePair<String, String[]> handlerConfig in eventHandlerConfiguration)
40+
{
41+
handlers.AddRange(handlerConfig.Value);
42+
}
43+
44+
IEnumerable<String> distinctHandlers = handlers.Distinct();
45+
46+
foreach (String handlerTypeString in distinctHandlers)
47+
{
48+
Type handlerType = Type.GetType(handlerTypeString);
49+
50+
if (handlerType == null)
51+
{
52+
throw new NotSupportedException("Event handler configuration is not for a valid type");
53+
}
54+
55+
IDomainEventHandler eventHandler = createEventHandlerResolver(handlerType);
56+
this.DomainEventHandlers.Add(handlerTypeString, eventHandler);
57+
}
58+
}
59+
60+
#endregion
61+
62+
#region Methods
63+
64+
/// <summary>
65+
/// Gets the domain event handlers.
66+
/// </summary>
67+
/// <param name="domainEvent">The domain event.</param>
68+
/// <returns></returns>
69+
public List<IDomainEventHandler> GetDomainEventHandlers(DomainEvent domainEvent)
70+
{
71+
// Get the type of the event passed in
72+
String typeString = domainEvent.GetType().FullName;
73+
74+
// Lookup the list
75+
Boolean eventIsConfigured = this.EventHandlerConfiguration.ContainsKey(typeString);
76+
77+
if (!eventIsConfigured)
78+
{
79+
// No handlers setup, return null and let the caller decide what to do next
80+
return null;
81+
}
82+
83+
String[] handlers = this.EventHandlerConfiguration[typeString];
84+
85+
List<IDomainEventHandler> handlersToReturn = new List<IDomainEventHandler>();
86+
87+
foreach (String handler in handlers)
88+
{
89+
List<KeyValuePair<String, IDomainEventHandler>> foundHandlers = this.DomainEventHandlers.Where(h => h.Key == handler).ToList();
90+
91+
handlersToReturn.AddRange(foundHandlers.Select(x => x.Value));
92+
}
93+
94+
return handlersToReturn;
95+
}
96+
97+
#endregion
98+
}
99+
}

0 commit comments

Comments
 (0)