mirror of https://github.com/Squidex/squidex.git
35 changed files with 662 additions and 243 deletions
@ -1,11 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Threading.Tasks; |
|
||||
|
|
||||
namespace Squidex.Infrastructure.MongoDb.EventStore |
|
||||
{ |
|
||||
public class MongoStreamsRepository |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,19 @@ |
|||||
|
// ==========================================================================
|
||||
|
// InfrastructureErrors.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Microsoft.Extensions.Logging; |
||||
|
|
||||
|
namespace Squidex.Infrastructure.Redis |
||||
|
{ |
||||
|
public class InfrastructureErrors |
||||
|
{ |
||||
|
public static readonly EventId InvalidatingReceivedFailed = new EventId(10001, "InvalidingReceivedFailed"); |
||||
|
|
||||
|
public static readonly EventId InvalidatingPublishedFailed = new EventId(10002, "InvalidatingPublishedFailed"); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,63 @@ |
|||||
|
// ==========================================================================
|
||||
|
// RedisEventNotifier.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Squidex.Infrastructure.CQRS.Events; |
||||
|
using StackExchange.Redis; |
||||
|
|
||||
|
namespace Squidex.Infrastructure.Redis |
||||
|
{ |
||||
|
public sealed class RedisEventNotifier : IEventNotifier |
||||
|
{ |
||||
|
private const string Channel = "SquidexEventNotifications"; |
||||
|
private readonly InMemoryEventNotifier inMemoryNotifier = new InMemoryEventNotifier(); |
||||
|
private readonly ISubscriber subscriber; |
||||
|
private readonly ILogger<RedisEventNotifier> logger; |
||||
|
|
||||
|
public RedisEventNotifier(IConnectionMultiplexer redis, ILogger<RedisEventNotifier> logger) |
||||
|
{ |
||||
|
Guard.NotNull(redis, nameof(redis)); |
||||
|
Guard.NotNull(logger, nameof(logger)); |
||||
|
|
||||
|
subscriber = redis.GetSubscriber(); |
||||
|
subscriber.Subscribe(Channel, (channel, value) => HandleInvalidation()); |
||||
|
|
||||
|
this.logger = logger; |
||||
|
} |
||||
|
|
||||
|
private void HandleInvalidation() |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
inMemoryNotifier.NotifyEventsStored(); |
||||
|
} |
||||
|
catch (Exception e) |
||||
|
{ |
||||
|
logger.LogError(InfrastructureErrors.InvalidatingReceivedFailed, e, "Failed to receive invalidation message."); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void NotifyEventsStored() |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
subscriber.Publish(Channel, RedisValue.Null); |
||||
|
} |
||||
|
catch (Exception e) |
||||
|
{ |
||||
|
logger.LogError(InfrastructureErrors.InvalidatingReceivedFailed, e, "Failed to send invalidation message"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void Subscribe(Action handler) |
||||
|
{ |
||||
|
inMemoryNotifier.Subscribe(handler); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,37 @@ |
|||||
|
// ==========================================================================
|
||||
|
// RedisExternalSystem.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using StackExchange.Redis; |
||||
|
|
||||
|
namespace Squidex.Infrastructure.Redis |
||||
|
{ |
||||
|
public class RedisExternalSystem |
||||
|
{ |
||||
|
private readonly IConnectionMultiplexer redis; |
||||
|
|
||||
|
public RedisExternalSystem(IConnectionMultiplexer redis) |
||||
|
{ |
||||
|
Guard.NotNull(redis, nameof(redis)); |
||||
|
|
||||
|
this.redis = redis; |
||||
|
} |
||||
|
|
||||
|
public void CheckConnection() |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
redis.GetStatus(); |
||||
|
} |
||||
|
catch (Exception e) |
||||
|
{ |
||||
|
throw new ConfigurationException($"Redis connection failed to connect to database {redis.Configuration}", e); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,56 @@ |
|||||
|
// ==========================================================================
|
||||
|
// RedisInvalidatingCache.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Microsoft.Extensions.Caching.Memory; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using StackExchange.Redis; |
||||
|
|
||||
|
namespace Squidex.Infrastructure.Redis |
||||
|
{ |
||||
|
public class RedisInvalidatingCache : IMemoryCache |
||||
|
{ |
||||
|
private readonly IMemoryCache inner; |
||||
|
private readonly RedisInvalidator invalidator; |
||||
|
|
||||
|
public RedisInvalidatingCache(IMemoryCache inner, IConnectionMultiplexer redis, ILogger<RedisInvalidatingCache> logger) |
||||
|
{ |
||||
|
Guard.NotNull(redis, nameof(redis)); |
||||
|
Guard.NotNull(inner, nameof(inner)); |
||||
|
Guard.NotNull(logger, nameof(logger)); |
||||
|
|
||||
|
this.inner = inner; |
||||
|
|
||||
|
invalidator = new RedisInvalidator(redis, inner, logger); |
||||
|
} |
||||
|
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
inner.Dispose(); |
||||
|
} |
||||
|
|
||||
|
public bool TryGetValue(object key, out object value) |
||||
|
{ |
||||
|
return inner.TryGetValue(key, out value); |
||||
|
} |
||||
|
|
||||
|
public void Remove(object key) |
||||
|
{ |
||||
|
inner.Remove(key); |
||||
|
|
||||
|
if (key is string) |
||||
|
{ |
||||
|
invalidator.Invalidate(key.ToString()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public ICacheEntry CreateEntry(object key) |
||||
|
{ |
||||
|
return new WrapperCacheEntry(inner.CreateEntry(key), invalidator); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,96 @@ |
|||||
|
// ==========================================================================
|
||||
|
// RedisInvalidator.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using Microsoft.Extensions.Caching.Memory; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using StackExchange.Redis; |
||||
|
|
||||
|
// ReSharper disable InvertIf
|
||||
|
// ReSharper disable ArrangeThisQualifier
|
||||
|
|
||||
|
namespace Squidex.Infrastructure.Redis |
||||
|
{ |
||||
|
internal sealed class RedisInvalidator |
||||
|
{ |
||||
|
private const string Channel = "SquidexChannelInvalidations"; |
||||
|
private readonly Guid instanceId = Guid.NewGuid(); |
||||
|
private readonly ISubscriber subscriber; |
||||
|
private readonly IMemoryCache cache; |
||||
|
private readonly ILogger<RedisInvalidatingCache> logger; |
||||
|
private int invalidationsReceived; |
||||
|
|
||||
|
public int InvalidationsReceived |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return invalidationsReceived; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public RedisInvalidator(IConnectionMultiplexer redis, IMemoryCache cache, ILogger<RedisInvalidatingCache> logger) |
||||
|
{ |
||||
|
this.cache = cache; |
||||
|
|
||||
|
subscriber = redis.GetSubscriber(); |
||||
|
subscriber.Subscribe(Channel, (channel, value) => HandleInvalidation(value)); |
||||
|
|
||||
|
this.logger = logger; |
||||
|
} |
||||
|
|
||||
|
private void HandleInvalidation(string value) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
if (string.IsNullOrWhiteSpace(value)) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
var parts = value.Split('#'); |
||||
|
|
||||
|
if (parts.Length != 2) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
Guid sender; |
||||
|
|
||||
|
if (!Guid.TryParse(parts[0], out sender)) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (sender != instanceId) |
||||
|
{ |
||||
|
invalidationsReceived++; |
||||
|
|
||||
|
cache.Remove(parts[1]); |
||||
|
} |
||||
|
} |
||||
|
catch (Exception e) |
||||
|
{ |
||||
|
logger.LogError(InfrastructureErrors.InvalidatingReceivedFailed, e, "Failed to receive invalidation message."); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void Invalidate(string key) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
var message = string.Join("#", instanceId.ToString()); |
||||
|
|
||||
|
subscriber.Publish(Channel, message); |
||||
|
} |
||||
|
catch (Exception e) |
||||
|
{ |
||||
|
logger.LogError(InfrastructureErrors.InvalidatingReceivedFailed, e, "Failed to send invalidation message {0}", key); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
|
<PropertyGroup> |
||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion> |
||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" /> |
||||
|
<PropertyGroup Label="Globals"> |
||||
|
<ProjectGuid>d7166c56-178a-4457-b56a-c615c7450dee</ProjectGuid> |
||||
|
<RootNamespace>Squidex.Infrastructure.Redis</RootNamespace> |
||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath> |
||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath> |
||||
|
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<SchemaVersion>2.0</SchemaVersion> |
||||
|
</PropertyGroup> |
||||
|
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" /> |
||||
|
</Project> |
||||
@ -0,0 +1,83 @@ |
|||||
|
// ==========================================================================
|
||||
|
// WrapperCacheEntry.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using Microsoft.Extensions.Caching.Memory; |
||||
|
using Microsoft.Extensions.Primitives; |
||||
|
|
||||
|
namespace Squidex.Infrastructure.Redis |
||||
|
{ |
||||
|
internal sealed class WrapperCacheEntry : ICacheEntry |
||||
|
{ |
||||
|
private readonly ICacheEntry inner; |
||||
|
private readonly RedisInvalidator invalidator; |
||||
|
|
||||
|
public object Key |
||||
|
{ |
||||
|
get { return inner.Key; } |
||||
|
} |
||||
|
|
||||
|
public IList<IChangeToken> ExpirationTokens |
||||
|
{ |
||||
|
get { return inner.ExpirationTokens; } |
||||
|
} |
||||
|
|
||||
|
public IList<PostEvictionCallbackRegistration> PostEvictionCallbacks |
||||
|
{ |
||||
|
get { return inner.PostEvictionCallbacks; } |
||||
|
} |
||||
|
|
||||
|
public DateTimeOffset? AbsoluteExpiration |
||||
|
{ |
||||
|
get { return inner.AbsoluteExpiration; } |
||||
|
set { inner.AbsoluteExpiration = value; } |
||||
|
} |
||||
|
|
||||
|
public TimeSpan? AbsoluteExpirationRelativeToNow |
||||
|
{ |
||||
|
get { return inner.AbsoluteExpirationRelativeToNow; } |
||||
|
set { inner.AbsoluteExpirationRelativeToNow = value; } |
||||
|
} |
||||
|
|
||||
|
public TimeSpan? SlidingExpiration |
||||
|
{ |
||||
|
get { return inner.SlidingExpiration; } |
||||
|
set { inner.SlidingExpiration = value; } |
||||
|
} |
||||
|
|
||||
|
public CacheItemPriority Priority |
||||
|
{ |
||||
|
get { return inner.Priority; } |
||||
|
set { inner.Priority = value; } |
||||
|
} |
||||
|
|
||||
|
public object Value |
||||
|
{ |
||||
|
get { return inner.Value; } |
||||
|
set { inner.Value = value; } |
||||
|
} |
||||
|
|
||||
|
public WrapperCacheEntry(ICacheEntry inner, RedisInvalidator invalidator) |
||||
|
{ |
||||
|
this.inner = inner; |
||||
|
|
||||
|
this.invalidator = invalidator; |
||||
|
} |
||||
|
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
if (Key is string) |
||||
|
{ |
||||
|
invalidator.Invalidate(Key?.ToString()); |
||||
|
} |
||||
|
|
||||
|
inner.Dispose(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
{ |
||||
|
"version": "1.0.0-*", |
||||
|
"dependencies": { |
||||
|
"Autofac": "4.3.0", |
||||
|
"Microsoft.Extensions.Caching.Abstractions": "1.1.0", |
||||
|
"Microsoft.Extensions.Logging": "1.1.0", |
||||
|
"Newtonsoft.Json": "9.0.2-beta2", |
||||
|
"NodaTime": "2.0.0-beta20170123", |
||||
|
"Squidex.Infrastructure": "1.0.0-*", |
||||
|
"StackExchange.Redis.StrongName": "1.2.0", |
||||
|
"System.Linq": "4.3.0", |
||||
|
"System.Reactive": "3.1.1", |
||||
|
"System.Reflection.TypeExtensions": "4.3.0", |
||||
|
"System.Security.Claims": "4.3.0" |
||||
|
}, |
||||
|
"frameworks": { |
||||
|
"netstandard1.6": { |
||||
|
"dependencies": { |
||||
|
"NETStandard.Library": "1.6.1" |
||||
|
}, |
||||
|
"imports": "dnxcore50" |
||||
|
} |
||||
|
}, |
||||
|
"tooling": { |
||||
|
"defaultNamespace": "Squidex.Infrastructure.Redis" |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,28 @@ |
|||||
|
// ==========================================================================
|
||||
|
// InMemoryEventNotifier.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Reactive.Subjects; |
||||
|
|
||||
|
namespace Squidex.Infrastructure.CQRS.Events |
||||
|
{ |
||||
|
public sealed class InMemoryEventNotifier : IEventNotifier |
||||
|
{ |
||||
|
private readonly Subject<object> subject = new Subject<object>(); |
||||
|
|
||||
|
public void NotifyEventsStored() |
||||
|
{ |
||||
|
subject.OnNext(null); |
||||
|
} |
||||
|
|
||||
|
public void Subscribe(Action handler) |
||||
|
{ |
||||
|
subject.Subscribe(_ => handler()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,38 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// MongoDbStoresExternalSystem.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System; |
|
||||
using MongoDB.Driver; |
|
||||
using Squidex.Infrastructure; |
|
||||
|
|
||||
namespace Squidex.Read.MongoDb |
|
||||
{ |
|
||||
public sealed class MongoDbStoresExternalSystem : IExternalSystem |
|
||||
{ |
|
||||
private readonly IMongoDatabase database; |
|
||||
|
|
||||
public MongoDbStoresExternalSystem(IMongoDatabase database) |
|
||||
{ |
|
||||
Guard.NotNull(database, nameof(database)); |
|
||||
|
|
||||
this.database = database; |
|
||||
} |
|
||||
|
|
||||
public void CheckConnection() |
|
||||
{ |
|
||||
try |
|
||||
{ |
|
||||
database.ListCollections(); |
|
||||
} |
|
||||
catch (Exception e) |
|
||||
{ |
|
||||
throw new ConfigurationException($"MongoDb Event Store failed to connect to database {database.DatabaseNamespace.DatabaseName}", e); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,87 @@ |
|||||
|
// ==========================================================================
|
||||
|
// ClusterModule.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using Autofac; |
||||
|
using Microsoft.Extensions.Caching.Memory; |
||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.CQRS.Events; |
||||
|
using Squidex.Infrastructure.Redis; |
||||
|
using StackExchange.Redis; |
||||
|
|
||||
|
namespace Squidex.Config.Domain |
||||
|
{ |
||||
|
public class ClusterModule : Module |
||||
|
{ |
||||
|
public IConfiguration Configuration { get; } |
||||
|
|
||||
|
public ClusterModule(IConfiguration configuration) |
||||
|
{ |
||||
|
Configuration = configuration; |
||||
|
} |
||||
|
|
||||
|
protected override void Load(ContainerBuilder builder) |
||||
|
{ |
||||
|
var canCatch = Configuration.GetValue<bool>("squidex:catch"); |
||||
|
|
||||
|
if (canCatch) |
||||
|
{ |
||||
|
builder.RegisterType<EventReceiver>() |
||||
|
.AsSelf() |
||||
|
.InstancePerDependency(); |
||||
|
} |
||||
|
|
||||
|
var clustererType = Configuration.GetValue<string>("squidex:clusterer:type"); |
||||
|
|
||||
|
if (string.IsNullOrWhiteSpace(clustererType)) |
||||
|
{ |
||||
|
throw new ConfigurationException("You must specify the clusterer type in the 'squidex:clusterer:type' configuration section."); |
||||
|
} |
||||
|
|
||||
|
if (string.Equals(clustererType, "Slack", StringComparison.OrdinalIgnoreCase)) |
||||
|
{ |
||||
|
var connectionString = Configuration.GetValue<string>("squidex:clusterer:redis:connectionString"); |
||||
|
|
||||
|
if (string.IsNullOrWhiteSpace(connectionString) || !Uri.IsWellFormedUriString(connectionString, UriKind.Absolute)) |
||||
|
{ |
||||
|
throw new ConfigurationException("You must specify the Redis connection string in the 'squidex:clusterer:redis:connectionString' configuration section."); |
||||
|
} |
||||
|
|
||||
|
builder.Register(c => ConnectionMultiplexer.Connect(connectionString)) |
||||
|
.As<IConnectionMultiplexer>() |
||||
|
.SingleInstance(); |
||||
|
|
||||
|
builder.RegisterType<RedisEventNotifier>() |
||||
|
.As<IEventNotifier>() |
||||
|
.SingleInstance(); |
||||
|
|
||||
|
builder.RegisterType<RedisExternalSystem>() |
||||
|
.As<IExternalSystem>() |
||||
|
.SingleInstance(); |
||||
|
|
||||
|
builder.Register(c => |
||||
|
{ |
||||
|
var inner = new MemoryCache(c.Resolve<IOptions<MemoryCacheOptions>>()); |
||||
|
|
||||
|
return new RedisInvalidatingCache(inner, |
||||
|
c.Resolve<IConnectionMultiplexer>(), |
||||
|
c.Resolve<ILogger<RedisInvalidatingCache>>()); |
||||
|
}) |
||||
|
.As<IMemoryCache>() |
||||
|
.SingleInstance(); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
throw new ConfigurationException($"Unsupported clusterer type '{clustererType}' for key 'squidex:clusterer:type', supported: Redis."); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,81 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// EventStoreModule.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System; |
|
||||
using Autofac; |
|
||||
using Microsoft.Extensions.Configuration; |
|
||||
using RabbitMQ.Client; |
|
||||
using Squidex.Infrastructure; |
|
||||
using Squidex.Infrastructure.CQRS.Events; |
|
||||
using Squidex.Infrastructure.RabbitMq; |
|
||||
|
|
||||
namespace Squidex.Config.Domain |
|
||||
{ |
|
||||
public class EventBusModule : Module |
|
||||
{ |
|
||||
public IConfiguration Configuration { get; } |
|
||||
|
|
||||
public EventBusModule(IConfiguration configuration) |
|
||||
{ |
|
||||
Configuration = configuration; |
|
||||
} |
|
||||
|
|
||||
protected override void Load(ContainerBuilder builder) |
|
||||
{ |
|
||||
var eventBusType = Configuration.GetValue<string>("squidex:eventBus:type"); |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(eventBusType)) |
|
||||
{ |
|
||||
throw new ConfigurationException("You must specify the event bus type in the 'squidex:eventBus:type' configuration section."); |
|
||||
} |
|
||||
|
|
||||
var canCatch = Configuration.GetValue<bool>("squidex:eventBus:catch"); |
|
||||
|
|
||||
builder.RegisterType<EventReceiver>() |
|
||||
.WithParameter(new NamedParameter("canCatch", canCatch)) |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
if (string.Equals(eventBusType, "Memory", StringComparison.OrdinalIgnoreCase)) |
|
||||
{ |
|
||||
builder.RegisterType<InMemoryEventBus>() |
|
||||
.As<IEventStream>() |
|
||||
.As<IEventPublisher>() |
|
||||
.SingleInstance(); |
|
||||
} |
|
||||
else if (string.Equals(eventBusType, "RabbitMq", StringComparison.OrdinalIgnoreCase)) |
|
||||
{ |
|
||||
var connectionString = Configuration.GetValue<string>("squidex:eventBus:rabbitMq:connectionString"); |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(connectionString) || !Uri.IsWellFormedUriString(connectionString, UriKind.Absolute)) |
|
||||
{ |
|
||||
throw new ConfigurationException("You must specify the RabbitMq connection string in the 'squidex:eventBus:rabbitMq:connectionString' configuration section."); |
|
||||
} |
|
||||
|
|
||||
var queueName = Configuration.GetValue<string>("squidex:eventBus:rabbitMq:queueName"); |
|
||||
|
|
||||
builder.Register(c => |
|
||||
{ |
|
||||
var connectionFactory = new ConnectionFactory(); |
|
||||
|
|
||||
connectionFactory.SetUri(new Uri(connectionString)); |
|
||||
|
|
||||
return new RabbitMqEventBus(connectionFactory, canCatch, queueName); |
|
||||
}) |
|
||||
.As<IEventStream>() |
|
||||
.As<IEventPublisher>() |
|
||||
.As<IExternalSystem>() |
|
||||
.SingleInstance(); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
throw new ConfigurationException($"Unsupported store type '{eventBusType}' for key 'squidex:eventStore:type', supported: Memory, RabbmitMq."); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
Loading…
Reference in new issue