mirror of https://github.com/Squidex/squidex.git
24 changed files with 342 additions and 260 deletions
@ -0,0 +1,23 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Singletons.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Collections.Concurrent; |
||||
|
|
||||
|
namespace Squidex.Infrastructure |
||||
|
{ |
||||
|
public static class Singletons<T> |
||||
|
{ |
||||
|
private static readonly ConcurrentDictionary<string, T> instances = new ConcurrentDictionary<string, T>(StringComparer.OrdinalIgnoreCase); |
||||
|
|
||||
|
public static T GetOrAdd(string key, Func<string, T> factory) |
||||
|
{ |
||||
|
return instances.GetOrAdd(key, factory); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,85 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// ClusterModule.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System; |
|
||||
using Autofac; |
|
||||
using Microsoft.Extensions.Configuration; |
|
||||
using Squidex.Infrastructure; |
|
||||
using Squidex.Infrastructure.CQRS.Events; |
|
||||
using Squidex.Infrastructure.Redis; |
|
||||
using StackExchange.Redis; |
|
||||
|
|
||||
namespace Squidex.Config.Domain |
|
||||
{ |
|
||||
public class ClusterModule : Module |
|
||||
{ |
|
||||
private IConfiguration Configuration { get; } |
|
||||
|
|
||||
public ClusterModule(IConfiguration configuration) |
|
||||
{ |
|
||||
Configuration = configuration; |
|
||||
} |
|
||||
|
|
||||
protected override void Load(ContainerBuilder builder) |
|
||||
{ |
|
||||
var handleEvents = Configuration.GetValue<bool>("squidex:handleEvents"); |
|
||||
|
|
||||
if (handleEvents) |
|
||||
{ |
|
||||
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, "Redis", StringComparison.OrdinalIgnoreCase)) |
|
||||
{ |
|
||||
var connectionString = Configuration.GetValue<string>("squidex:clusterer:redis:connectionString"); |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(connectionString)) |
|
||||
{ |
|
||||
throw new ConfigurationException("You must specify the Redis connection string in the 'squidex:clusterer:redis:connectionString' configuration section."); |
|
||||
} |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
var connectionMultiplexer = ConnectionMultiplexer.Connect(connectionString); |
|
||||
|
|
||||
builder.RegisterInstance(connectionMultiplexer) |
|
||||
.As<IConnectionMultiplexer>() |
|
||||
.SingleInstance(); |
|
||||
} |
|
||||
catch (Exception ex) |
|
||||
{ |
|
||||
throw new ConfigurationException($"Redis connection failed to connect to database {connectionString}", ex); |
|
||||
} |
|
||||
|
|
||||
builder.RegisterType<RedisPubSub>() |
|
||||
.As<IPubSub>() |
|
||||
.As<IExternalSystem>() |
|
||||
.SingleInstance(); |
|
||||
} |
|
||||
else if (string.Equals(clustererType, "None", StringComparison.OrdinalIgnoreCase)) |
|
||||
{ |
|
||||
builder.RegisterType<InMemoryPubSub>() |
|
||||
.As<IPubSub>() |
|
||||
.SingleInstance(); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
throw new ConfigurationException($"Unsupported clusterer type '{clustererType}' for key 'squidex:clusterer:type', supported: Redis, None."); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,80 @@ |
|||||
|
// ==========================================================================
|
||||
|
// RabbitMqModule.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using Autofac; |
||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using Newtonsoft.Json; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.CQRS.Events; |
||||
|
using Squidex.Infrastructure.RabbitMq; |
||||
|
|
||||
|
// ReSharper disable InvertIf
|
||||
|
|
||||
|
namespace Squidex.Config.Domain |
||||
|
{ |
||||
|
public sealed class EventPublishersModule : Module |
||||
|
{ |
||||
|
private IConfiguration Configuration { get; } |
||||
|
|
||||
|
public EventPublishersModule(IConfiguration configuration) |
||||
|
{ |
||||
|
Configuration = configuration; |
||||
|
} |
||||
|
|
||||
|
protected override void Load(ContainerBuilder builder) |
||||
|
{ |
||||
|
var eventPublishers = Configuration.GetSection("eventPublishers"); |
||||
|
|
||||
|
foreach (var child in eventPublishers.GetChildren()) |
||||
|
{ |
||||
|
var eventPublisherType = child.GetValue<string>("type"); |
||||
|
|
||||
|
if (string.IsNullOrWhiteSpace(eventPublisherType)) |
||||
|
{ |
||||
|
throw new ConfigurationException($"Configure EventPublisher type with 'eventPublishers:{child.Key}:type'."); |
||||
|
} |
||||
|
|
||||
|
var eventsFilter = Configuration.GetValue<string>("eventsFilter"); |
||||
|
|
||||
|
var enabled = child.GetValue<bool>("enabled"); |
||||
|
|
||||
|
if (string.Equals(eventPublisherType, "RabbitMq", StringComparison.OrdinalIgnoreCase)) |
||||
|
{ |
||||
|
var configuration = child.GetValue<string>("configuration"); |
||||
|
|
||||
|
if (string.IsNullOrWhiteSpace(configuration)) |
||||
|
{ |
||||
|
throw new ConfigurationException($"Configure EventPublisher RabbitMq configuration with 'eventPublishers:{child.Key}:configuration'."); |
||||
|
} |
||||
|
|
||||
|
var exchange = child.GetValue<string>("exchange"); |
||||
|
|
||||
|
if (string.IsNullOrWhiteSpace(exchange)) |
||||
|
{ |
||||
|
throw new ConfigurationException($"Configure EventPublisher RabbitMq exchange with 'eventPublishers:{child.Key}:configuration'."); |
||||
|
} |
||||
|
|
||||
|
var name = $"EventPublishers_{child.Key}"; |
||||
|
|
||||
|
if (enabled) |
||||
|
{ |
||||
|
builder.Register(c => new RabbitMqEventConsumer(c.Resolve<JsonSerializerSettings>(), name, configuration, exchange, eventsFilter)) |
||||
|
.As<IEventConsumer>() |
||||
|
.As<IExternalSystem>() |
||||
|
.SingleInstance(); |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
throw new ConfigurationException($"Unsupported value '{child.Key}' for 'eventPublishers:{child.Key}:type', supported: RabbitMq."); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,70 @@ |
|||||
|
// ==========================================================================
|
||||
|
// ClusterModule.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using Autofac; |
||||
|
using Autofac.Core; |
||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.Redis; |
||||
|
using StackExchange.Redis; |
||||
|
|
||||
|
namespace Squidex.Config.Domain |
||||
|
{ |
||||
|
public sealed class PubSubModule : Module |
||||
|
{ |
||||
|
private const string RedisRegistration = "PubSubRedis"; |
||||
|
|
||||
|
private IConfiguration Configuration { get; } |
||||
|
|
||||
|
public PubSubModule(IConfiguration configuration) |
||||
|
{ |
||||
|
Configuration = configuration; |
||||
|
} |
||||
|
|
||||
|
protected override void Load(ContainerBuilder builder) |
||||
|
{ |
||||
|
var pubSubType = Configuration.GetValue<string>("pubSub:type"); |
||||
|
|
||||
|
if (string.IsNullOrWhiteSpace(pubSubType)) |
||||
|
{ |
||||
|
throw new ConfigurationException("Configure the PubSub type with 'pubSub:type'."); |
||||
|
} |
||||
|
|
||||
|
if (string.Equals(pubSubType, "Redis", StringComparison.OrdinalIgnoreCase)) |
||||
|
{ |
||||
|
var configuration = Configuration.GetValue<string>("pubsub:redis:configuration"); |
||||
|
|
||||
|
if (string.IsNullOrWhiteSpace(configuration)) |
||||
|
{ |
||||
|
throw new ConfigurationException("Configure PubSub Redis configuration with pubSub:redis:configuration'."); |
||||
|
} |
||||
|
|
||||
|
builder.Register(c => Singletons<IConnectionMultiplexer>.GetOrAdd(configuration, s => ConnectionMultiplexer.Connect(s))) |
||||
|
.Named<IConnectionMultiplexer>(RedisRegistration) |
||||
|
.SingleInstance(); |
||||
|
|
||||
|
builder.RegisterType<RedisPubSub>() |
||||
|
.WithParameter(ResolvedParameter.ForNamed<IConnectionMultiplexer>(RedisRegistration)) |
||||
|
.As<IPubSub>() |
||||
|
.As<IExternalSystem>() |
||||
|
.SingleInstance(); |
||||
|
} |
||||
|
else if (string.Equals(pubSubType, "InMemory", StringComparison.OrdinalIgnoreCase)) |
||||
|
{ |
||||
|
builder.RegisterType<InMemoryPubSub>() |
||||
|
.As<IPubSub>() |
||||
|
.SingleInstance(); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
throw new ConfigurationException($"Unsupported value '{pubSubType}' for 'pubSub:type', supported: Redis, InMemory."); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,48 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// RabbitMqModule.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Autofac; |
|
||||
using Microsoft.Extensions.Configuration; |
|
||||
using Newtonsoft.Json; |
|
||||
using Squidex.Infrastructure; |
|
||||
using Squidex.Infrastructure.CQRS.Events; |
|
||||
using Squidex.Infrastructure.RabbitMq; |
|
||||
|
|
||||
// ReSharper disable InvertIf
|
|
||||
|
|
||||
namespace Squidex.Config.Domain |
|
||||
{ |
|
||||
public sealed class RabbitMqModule : Module |
|
||||
{ |
|
||||
private IConfiguration Configuration { get; } |
|
||||
|
|
||||
public RabbitMqModule(IConfiguration configuration) |
|
||||
{ |
|
||||
Configuration = configuration; |
|
||||
} |
|
||||
|
|
||||
protected override void Load(ContainerBuilder builder) |
|
||||
{ |
|
||||
var connectionString = Configuration.GetValue<string>("squidex:eventPublishers:rabbitMq:connectionString"); |
|
||||
var exchange = Configuration.GetValue<string>("squidex:eventPublishers:rabbitMq:exchange"); |
|
||||
var enabled = Configuration.GetValue<bool>("squidex:eventPublishers:rabbitMq:enabled"); |
|
||||
|
|
||||
if (!string.IsNullOrWhiteSpace(connectionString) && |
|
||||
!string.IsNullOrWhiteSpace(exchange) && |
|
||||
enabled) |
|
||||
{ |
|
||||
var streamFilter = Configuration.GetValue<string>("squidex:eventPublishers:rabbitMq:streamFilter"); |
|
||||
|
|
||||
builder.Register(c => new RabbitMqEventConsumer(c.Resolve<JsonSerializerSettings>(), connectionString, exchange, streamFilter)) |
|
||||
.As<IEventConsumer>() |
|
||||
.As<IExternalSystem>() |
|
||||
.SingleInstance(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,45 +1,53 @@ |
|||||
{ |
{ |
||||
"squidex": { |
|
||||
"urls": { |
"urls": { |
||||
"baseUrl": "http://localhost:5000" |
"baseUrl": "http://localhost:5000" |
||||
}, |
}, |
||||
"logging": { |
"logging": { |
||||
"human": false |
"human": false |
||||
}, |
}, |
||||
"clusterer": { |
"pubSub": { |
||||
"type": "none", |
"type": "InMemory", |
||||
"redis": { |
"redis": { |
||||
"connectionString": "localhost:6379,resolveDns=1" |
"configuration": "localhost:6379,resolveDns=1" |
||||
} |
} |
||||
}, |
}, |
||||
"eventStore": { |
"eventStore": { |
||||
"type": "mongoDb", |
"type": "MongoDb", |
||||
"mongoDb": { |
"mongoDb": { |
||||
"connectionString": "mongodb://localhost", |
"configuration": "mongodb://localhost", |
||||
"databaseName": "Squidex" |
"database": "Squidex" |
||||
} |
}, |
||||
|
"consume": true |
||||
}, |
}, |
||||
"eventPublishers": { |
"eventPublishers": { |
||||
"rabbitMq": { |
"allToRabbitMq": { |
||||
"connectionString": "amqp://guest:guest@localhost/", |
"type": "RabbitMq", |
||||
|
"configuration": "amqp://guest:guest@localhost/", |
||||
"exchange": "squidex", |
"exchange": "squidex", |
||||
"enabled": false, |
"enabled": false, |
||||
"streamFilter": "*" |
"eventsFilter": "*" |
||||
} |
} |
||||
}, |
}, |
||||
"stores": { |
"store": { |
||||
"type": "mongoDb", |
"type": "MongoDb", |
||||
"mongoDb": { |
"mongoDb": { |
||||
"connectionString": "mongodb://localhost", |
"configuration": "mongodb://localhost", |
||||
"databaseName": "Squidex", |
"contentDatabase": "SquidexContent", |
||||
"databaseNameContent": "SquidexContent" |
"database": "Squidex" |
||||
} |
} |
||||
}, |
}, |
||||
"identity": { |
"identity": { |
||||
"googleClient": "1006817248705-t3lb3ge808m9am4t7upqth79hulk456l.apps.googleusercontent.com", |
"googleClient": "1006817248705-t3lb3ge808m9am4t7upqth79hulk456l.apps.googleusercontent.com", |
||||
"googleSecret": "QsEi-fHqkGw2_PjJmtNHf2wg", |
"googleSecret": "QsEi-fHqkGw2_PjJmtNHf2wg", |
||||
"lockAutomatically": true |
"lockAutomatically": true, |
||||
|
"keysStore": { |
||||
|
"type": "InMemory", |
||||
|
"redis": { |
||||
|
"configuration": "localhost:6379,resolveDns=1" |
||||
}, |
}, |
||||
"handleEvents": true |
"folder": { |
||||
|
"path": "keys" |
||||
|
} |
||||
|
} |
||||
} |
} |
||||
} |
} |
||||
Loading…
Reference in new issue