Skip to content

Commit

Permalink
Merge pull request #32 from marcwittke/hotfix/3.2.4
Browse files Browse the repository at this point in the history
Hotfix/3.2.4
  • Loading branch information
marcwittke committed Jun 6, 2018
2 parents 7f00952 + 3d584ae commit c3b7cc7
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 64 deletions.
9 changes: 6 additions & 3 deletions src/Backend.Fx.Bootstrapping/Modules/DomainModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@ public abstract class DomainModule : SimpleInjectorModule
private static readonly ILogger Logger = LogManager.Create<DomainModule>();
private readonly Assembly[] assemblies;
private IDomainEventAggregator domainEventAggregator;
private readonly string assembliesForLogging;

protected DomainModule(params Assembly[] domainAssemblies)
{
assemblies = domainAssemblies.Concat(new[] {
typeof(Entity).GetTypeInfo().Assembly,
}).ToArray();

assembliesForLogging = string.Join(",", assemblies.Select(ass => ass.GetName().Name));
}

public override void Register(ICompositionRoot compositionRoot)
Expand All @@ -54,13 +57,13 @@ protected override void Register(Container container, ScopedLifestyle scopedLife
RegisterAuthorization(container);

// domain event subsystem
Logger.Debug($"Registering domain event handlers from {string.Join(",", assemblies.Select(ass => ass.GetName().Name))}");
Logger.Debug($"Registering domain event handlers from {assembliesForLogging}");
container.Collection.Register(typeof(IDomainEventHandler<>), assemblies);
Logger.Debug("Registering singleton event aggregator instance");
container.RegisterInstance(domainEventAggregator);

// initial data generation subsystem
Logger.Debug($"Registering initial data generators from {string.Join(",", assemblies.Select(ass => ass.GetName().Name))}");
Logger.Debug($"Registering initial data generators from {assembliesForLogging}");
container.Collection.Register<InitialDataGenerator>(assemblies);

// all jobs are dynamically registered
Expand All @@ -81,7 +84,7 @@ protected override void Register(Container container, ScopedLifestyle scopedLife
/// </summary>
private void RegisterAuthorization(Container container)
{
Logger.Debug($"Registering authorization services from {string.Join(",", assemblies.Select(ass => ass.GetName().Name))}");
Logger.Debug($"Registering authorization services from {assembliesForLogging}");
var aggregateRootAuthorizationTypes = container.GetTypesToRegister(typeof(IAggregateAuthorization<>), assemblies).ToArray();
foreach (var aggregateAuthorizationType in aggregateRootAuthorizationTypes)
{
Expand Down
39 changes: 39 additions & 0 deletions src/Backend.Fx.Bootstrapping/Modules/EventBusModule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
namespace Backend.Fx.Bootstrapping.Modules
{
using System.Linq;
using System.Reflection;
using Logging;
using Patterns.EventAggregation.Integration;
using SimpleInjector;

public class EventBusModule : SimpleInjectorModule
{
private static readonly ILogger Logger = LogManager.Create<EventBusModule>();

private readonly IEventBus eventBus;
private readonly Assembly[] assemblies;
private readonly string assembliesForLogging;

public EventBusModule(IEventBus eventBus, params Assembly[] assemblies)
{
this.eventBus = eventBus;
this.assemblies = assemblies;
assembliesForLogging = string.Join(",", assemblies.Select(ass => ass.GetName().Name));
}

protected override void Register(Container container, ScopedLifestyle scopedLifestyle)
{
container.RegisterInstance(eventBus);

Logger.Debug($"Registering generic integration event handlers from {assembliesForLogging}");
container.Register(typeof(IIntegrationEventHandler<>), assemblies);

Logger.Debug($"Registering dynamic integration event handlers from {assembliesForLogging}");
foreach (var dynamicHandlerType in container.GetTypesToRegister(typeof(IIntegrationEventHandler), assemblies))
{
Logger.Debug($"Registering dynamic integration event {dynamicHandlerType.Name} as transient");
container.Register(dynamicHandlerType);
}
}
}
}
4 changes: 3 additions & 1 deletion src/Backend.Fx.RabbitMq/RabbitMQEventBus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{
using System;
using System.Text;
using System.Threading.Tasks;
using Environment.MultiTenancy;
using Logging;
using Newtonsoft.Json;
Expand Down Expand Up @@ -40,11 +41,12 @@ private void ChannelOnMessageReceived(object sender, BasicDeliverEventArgs args)
Process(args.RoutingKey, new RabbitMqEventProcessingContext(args.Body));
}

public override void Publish(IIntegrationEvent integrationEvent)
public override Task Publish(IIntegrationEvent integrationEvent)
{
Logger.Info($"Publishing {integrationEvent.GetType().Name}");
channel.EnsureOpen();
channel.PublishEvent(integrationEvent);
return Task.CompletedTask;
}

protected override void Subscribe(string eventName)
Expand Down
56 changes: 25 additions & 31 deletions src/Backend.Fx/Patterns/EventAggregation/Integration/IEventBus.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
namespace Backend.Fx.Patterns.EventAggregation.Integration
{
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using DependencyInjection;
using Environment.Authentication;
using Environment.MultiTenancy;
Expand All @@ -18,7 +18,7 @@ public interface IEventBus : IDisposable
{
void Connect();

void Publish(IIntegrationEvent integrationEvent);
Task Publish(IIntegrationEvent integrationEvent);

/// <summary>
/// Subscribes to an integration event with a dynamic event handler
Expand Down Expand Up @@ -66,7 +66,7 @@ protected EventBus(IScopeManager scopeManager, IExceptionLogger exceptionLogger)
}

public abstract void Connect();
public abstract void Publish(IIntegrationEvent integrationEvent);
public abstract Task Publish(IIntegrationEvent integrationEvent);


/// <inheritdoc />
Expand Down Expand Up @@ -154,41 +154,35 @@ protected virtual void Process(string eventName, EventProcessingContext context)
MethodInfo handleMethod = handlerType.GetRuntimeMethod("Handle", new[] { eventType });
Debug.Assert(handleMethod != null, $"No method with signature `Handle({eventName} event)` found on {handlerType.Name}");

IEnumerable handlerInstances = scope.GetAllInstances(handlerType);
foreach (var handlerInstance in handlerInstances)
object handlerInstance = scope.GetInstance(handlerType);

try
{
handleMethod.Invoke(handlerInstance, new object[] { integrationEvent });
}
catch (TargetInvocationException ex)
{
Logger.Info(ex, $"Handling of {eventName} by typed handler {handlerType} failed: {(ex.InnerException ?? ex).Message}");
exceptionLogger.LogException(ex.InnerException ?? ex);
}
catch (Exception ex)
{
try
{
handleMethod.Invoke(handlerInstance, new object[] { integrationEvent });
}
catch(TargetInvocationException ex)
{
Logger.Info(ex, $"Handling of {eventName} by typed handler {handlerType} failed: {(ex.InnerException ?? ex).Message}");
exceptionLogger.LogException(ex.InnerException ?? ex);
}
catch (Exception ex)
{
Logger.Info(ex, $"Handling of {eventName} by typed handler {handlerType} failed: {ex.Message}");
exceptionLogger.LogException(ex);
}
Logger.Info(ex, $"Handling of {eventName} by typed handler {handlerType} failed: {ex.Message}");
exceptionLogger.LogException(ex);
}
}
else
{
IEnumerable handlerInstances = scope.GetAllInstances(handlerType);
foreach (var handlerInstance in handlerInstances)
object handlerInstance = scope.GetInstance(handlerType);
try
{
try
{
((IIntegrationEventHandler)handlerInstance).Handle(context.DynamicEvent);
}
catch (Exception ex)
{
Logger.Info(ex, $"Handling of {eventName} by dynamic handler {handlerType} failed: {ex.Message}");
exceptionLogger.LogException(ex);
}
((IIntegrationEventHandler)handlerInstance).Handle(context.DynamicEvent);
}
catch (Exception ex)
{
Logger.Info(ex, $"Handling of {eventName} by dynamic handler {handlerType} failed: {ex.Message}");
exceptionLogger.LogException(ex);
}

}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace Backend.Fx.Patterns.EventAggregation.Integration
{
using System;
using System.Threading.Tasks;
using DependencyInjection;
using Environment.MultiTenancy;
using Logging;
Expand All @@ -14,9 +15,10 @@ public InMemoryEventBus(IScopeManager scopeManager, IExceptionLogger exceptionLo
public override void Connect()
{ }

public override void Publish(IIntegrationEvent integrationEvent)
public override Task Publish(IIntegrationEvent integrationEvent)
{
Process(integrationEvent.GetType().FullName, new InMemoryProcessingContext(integrationEvent));
return Task.Run(
() => Process(integrationEvent.GetType().FullName, new InMemoryProcessingContext(integrationEvent)));
}

protected override void Subscribe(string eventName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

public interface IIntegrationEvent
{
Guid Id { get; }
DateTime CreationDate { get; }
int TenantId { get; }
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace Backend.Fx.Tests.Patterns.EventAggregation.Integration
{
using System;
using System.Threading.Tasks;
using Fx.Environment.MultiTenancy;
using Fx.Logging;
using Fx.Patterns.DependencyInjection;
Expand All @@ -16,10 +17,10 @@ public SerializingEventBus(IScopeManager scopeManager, IExceptionLogger exceptio
public override void Connect()
{ }

public override void Publish(IIntegrationEvent integrationEvent)
public override Task Publish(IIntegrationEvent integrationEvent)
{
var jsonString = JsonConvert.SerializeObject(integrationEvent);
Process(integrationEvent.GetType().FullName, new SerializingProcessingContext(jsonString));
return Task.Run(() => Process(integrationEvent.GetType().FullName, new SerializingProcessingContext(jsonString)));
}

protected override void Subscribe(string eventName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,16 @@
{
using Fx.Patterns.EventAggregation.Integration;

public class TestIntegrationEvent : IIntegrationEvent
public class TestIntegrationEvent : IntegrationEvent
{
public int IntParam { get; }

public string StringParam { get; }

public TestIntegrationEvent(int intParam, string stringParam)
public TestIntegrationEvent(int intParam, string stringParam) : base(55)
{
IntParam = intParam;
StringParam = stringParam;
}

public int TenantId
{
get { return 55; }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{
using System;
using System.Security.Principal;
using System.Threading.Tasks;
using FakeItEasy;
using Fx.Environment.MultiTenancy;
using Fx.Logging;
Expand Down Expand Up @@ -39,10 +40,10 @@ protected TheEventBus()
protected abstract IEventBus Create(IScopeManager scopeManager, IExceptionLogger exceptionLogger);

[Fact]
public void CallsTypedEventHandler()
public async Task CallsTypedEventHandler()
{
sut.Subscribe<TypedEventHandler, TestIntegrationEvent>();
sut.Publish(new TestIntegrationEvent(34, "gaga"));
await sut.Publish(new TestIntegrationEvent(34, "gaga"));

A.CallTo(() => inj.TypedHandler.Handle(A<TestIntegrationEvent>
.That
Expand All @@ -53,10 +54,10 @@ public void CallsTypedEventHandler()
}

[Fact]
public void HandlesExceptionFromTypedEventHandler()
public async void HandlesExceptionFromTypedEventHandler()
{
sut.Subscribe<ThrowingTypedEventHandler, TestIntegrationEvent>();
sut.Publish(new TestIntegrationEvent(34, "gaga"));
await sut.Publish(new TestIntegrationEvent(34, "gaga"));

A.CallTo(() => inj.ExceptionLogger.LogException(A<InvalidOperationException>
.That
Expand All @@ -65,19 +66,19 @@ public void HandlesExceptionFromTypedEventHandler()
}

[Fact]
public void CallsDynamicEventHandler()
public async void CallsDynamicEventHandler()
{
sut.Subscribe<DynamicEventHandler>(typeof(TestIntegrationEvent).FullName);
sut.Publish(new TestIntegrationEvent(34, "gaga"));
await sut.Publish(new TestIntegrationEvent(34, "gaga"));
A.CallTo(() => inj.TypedHandler.Handle(A<TestIntegrationEvent>._)).MustNotHaveHappened();
A.CallTo(() => inj.DynamicHandler.Handle(A<object>._)).MustHaveHappenedOnceExactly();
}

[Fact]
public void HandlesExceptionFromDynamicEventHandler()
public async void HandlesExceptionFromDynamicEventHandler()
{
sut.Subscribe<ThrowingDynamicEventHandler>(typeof(TestIntegrationEvent).FullName);
sut.Publish(new TestIntegrationEvent(34, "gaga"));
await sut.Publish(new TestIntegrationEvent(34, "gaga"));

A.CallTo(() => inj.ExceptionLogger.LogException(A<InvalidOperationException>
.That
Expand All @@ -86,11 +87,11 @@ public void HandlesExceptionFromDynamicEventHandler()
}

[Fact]
public void CallsMixedEventHandlers()
public async void CallsMixedEventHandlers()
{
sut.Subscribe<DynamicEventHandler>(typeof(TestIntegrationEvent).FullName);
sut.Subscribe<TypedEventHandler, TestIntegrationEvent>();
sut.Publish(new TestIntegrationEvent(34, "gaga"));
await sut.Publish(new TestIntegrationEvent(34, "gaga"));
A.CallTo(() => inj.TypedHandler.Handle(A<TestIntegrationEvent>
.That
.Matches(evt => evt.IntParam == 34 && evt.StringParam == "gaga")))
Expand All @@ -112,17 +113,17 @@ public EventBusFakeInjection()
A.CallTo(() => ScopeManager.BeginScope(A<IIdentity>._, A<TenantId>._))
.Returns(Scope);

A.CallTo(() => Scope.GetAllInstances(A<Type>.That.IsEqualTo(typeof(TypedEventHandler))))
.Returns(new object[] { new TypedEventHandler(TypedHandler) });
A.CallTo(() => Scope.GetInstance(A<Type>.That.IsEqualTo(typeof(TypedEventHandler))))
.Returns(new TypedEventHandler(TypedHandler));

A.CallTo(() => Scope.GetAllInstances(A<Type>.That.IsEqualTo(typeof(ThrowingTypedEventHandler))))
.Returns(new object[] { new ThrowingTypedEventHandler() });
A.CallTo(() => Scope.GetInstance(A<Type>.That.IsEqualTo(typeof(ThrowingTypedEventHandler))))
.Returns(new ThrowingTypedEventHandler());

A.CallTo(() => Scope.GetAllInstances(A<Type>.That.IsEqualTo(typeof(DynamicEventHandler))))
.Returns(new object[] { new DynamicEventHandler(DynamicHandler) });
A.CallTo(() => Scope.GetInstance(A<Type>.That.IsEqualTo(typeof(DynamicEventHandler))))
.Returns(new DynamicEventHandler(DynamicHandler));

A.CallTo(() => Scope.GetAllInstances(A<Type>.That.IsEqualTo(typeof(ThrowingDynamicEventHandler))))
.Returns(new object[] { new ThrowingDynamicEventHandler() });
A.CallTo(() => Scope.GetInstance(A<Type>.That.IsEqualTo(typeof(ThrowingDynamicEventHandler))))
.Returns(new ThrowingDynamicEventHandler());
}
}
}
Expand Down

0 comments on commit c3b7cc7

Please sign in to comment.