mirror of https://github.com/Squidex/squidex.git
42 changed files with 978 additions and 1176 deletions
@ -0,0 +1,16 @@ |
|||||
|
// ==========================================================================
|
||||
|
// IAppEventConsumer.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Infrastructure.CQRS.Events; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Read.Apps |
||||
|
{ |
||||
|
public interface IAppEventConsumer : IEventConsumer |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
// ==========================================================================
|
||||
|
// IAssetEventConsumer.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Infrastructure.CQRS.Events; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Read.Assets |
||||
|
{ |
||||
|
public interface IAssetEventConsumer : IEventConsumer |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
// ==========================================================================
|
||||
|
// ISchemaEventConsumer.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Infrastructure.CQRS.Events; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Read.Schemas |
||||
|
{ |
||||
|
public interface ISchemaEventConsumer : IEventConsumer |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,51 @@ |
|||||
|
// ==========================================================================
|
||||
|
// AssetServices.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.Assets; |
||||
|
using Squidex.Infrastructure.Log; |
||||
|
|
||||
|
namespace Squidex.Config.Domain |
||||
|
{ |
||||
|
public static class AssetServices |
||||
|
{ |
||||
|
public static void AddMyAssetServices(this IServiceCollection services, IConfiguration config) |
||||
|
{ |
||||
|
config.ConfigureByOption("assetStore:type", new Options |
||||
|
{ |
||||
|
["Folder"] = () => |
||||
|
{ |
||||
|
var path = config.GetRequiredValue("assetStore:folder:path"); |
||||
|
|
||||
|
services.AddSingleton(c => new FolderAssetStore(path, c.GetRequiredService<ISemanticLog>())) |
||||
|
.As<IAssetStore>() |
||||
|
.As<IExternalSystem>(); |
||||
|
}, |
||||
|
["GoogleCloud"] = () => |
||||
|
{ |
||||
|
var bucketName = config.GetRequiredValue("assetStore:googleCloud:bucket"); |
||||
|
|
||||
|
services.AddSingleton(c => new GoogleCloudAssetStore(bucketName)) |
||||
|
.As<IAssetStore>() |
||||
|
.As<IExternalSystem>(); |
||||
|
}, |
||||
|
["AzureBlob"] = () => |
||||
|
{ |
||||
|
var connectionString = config.GetRequiredValue("assetStore:azureBlob:connectionString"); |
||||
|
var containerName = config.GetRequiredValue("assetStore:azureBlob:containerName"); |
||||
|
|
||||
|
services.AddSingleton(c => new AzureBlobAssetStore(connectionString, containerName)) |
||||
|
.As<IAssetStore>() |
||||
|
.As<IExternalSystem>(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,91 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// AssetStoreModule.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.Assets; |
|
||||
using Squidex.Infrastructure.Log; |
|
||||
|
|
||||
namespace Squidex.Config.Domain |
|
||||
{ |
|
||||
public sealed class AssetStoreModule : Module |
|
||||
{ |
|
||||
private IConfiguration Configuration { get; } |
|
||||
|
|
||||
public AssetStoreModule(IConfiguration configuration) |
|
||||
{ |
|
||||
Configuration = configuration; |
|
||||
} |
|
||||
|
|
||||
protected override void Load(ContainerBuilder builder) |
|
||||
{ |
|
||||
var assetStoreType = Configuration.GetValue<string>("assetStore:type"); |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(assetStoreType)) |
|
||||
{ |
|
||||
throw new ConfigurationException("Configure the AssetStore type with 'assetStore:type'."); |
|
||||
} |
|
||||
|
|
||||
if (string.Equals(assetStoreType, "Folder", StringComparison.OrdinalIgnoreCase)) |
|
||||
{ |
|
||||
var path = Configuration.GetValue<string>("assetStore:folder:path"); |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(path)) |
|
||||
{ |
|
||||
throw new ConfigurationException("Configure AssetStore Folder path with 'assetStore:folder:path'."); |
|
||||
} |
|
||||
|
|
||||
builder.Register(c => new FolderAssetStore(path, c.Resolve<ISemanticLog>())) |
|
||||
.As<IAssetStore>() |
|
||||
.As<IExternalSystem>() |
|
||||
.SingleInstance(); |
|
||||
} |
|
||||
else if (string.Equals(assetStoreType, "GoogleCloud", StringComparison.OrdinalIgnoreCase)) |
|
||||
{ |
|
||||
var bucketName = Configuration.GetValue<string>("assetStore:googleCloud:bucket"); |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(bucketName)) |
|
||||
{ |
|
||||
throw new ConfigurationException("Configure AssetStore GoogleCloud bucket with 'assetStore:googleCloud:bucket'."); |
|
||||
} |
|
||||
|
|
||||
builder.Register(c => new GoogleCloudAssetStore(bucketName)) |
|
||||
.As<IAssetStore>() |
|
||||
.As<IExternalSystem>() |
|
||||
.SingleInstance(); |
|
||||
} |
|
||||
else if (string.Equals(assetStoreType, "AzureBlob", StringComparison.OrdinalIgnoreCase)) |
|
||||
{ |
|
||||
var connectionString = Configuration.GetValue<string>("assetStore:azureBlob:connectionString"); |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(connectionString)) |
|
||||
{ |
|
||||
throw new ConfigurationException("Configure AssetStore AzureBlob connection string with 'assetStore:azureBlob:connectionString'."); |
|
||||
} |
|
||||
|
|
||||
var containerName = Configuration.GetValue<string>("assetStore:azureBlob:containerName"); |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(containerName)) |
|
||||
{ |
|
||||
throw new ConfigurationException("Configure AssetStore AzureBlob container with 'assetStore:azureBlob:containerName'."); |
|
||||
} |
|
||||
|
|
||||
builder.Register(c => new AzureBlobAssetStore(connectionString, containerName)) |
|
||||
.As<IAssetStore>() |
|
||||
.As<IExternalSystem>() |
|
||||
.SingleInstance(); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
throw new ConfigurationException($"Unsupported value '{assetStoreType}' for 'assetStore:type', supported: AzureBlob, Folder, GoogleCloud."); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,112 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// EventStoreModule.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System; |
|
||||
using Autofac; |
|
||||
using Autofac.Core; |
|
||||
using EventStore.ClientAPI; |
|
||||
using Microsoft.Extensions.Configuration; |
|
||||
using MongoDB.Driver; |
|
||||
using Squidex.Infrastructure; |
|
||||
using Squidex.Infrastructure.CQRS.Events; |
|
||||
using Squidex.Infrastructure.CQRS.Events.Actors; |
|
||||
|
|
||||
namespace Squidex.Config.Domain |
|
||||
{ |
|
||||
public sealed class EventStoreModule : Module |
|
||||
{ |
|
||||
private const string MongoClientRegistration = "EventStoreMongoClient"; |
|
||||
private const string MongoDatabaseRegistration = "EventStoreMongoDatabase"; |
|
||||
|
|
||||
private IConfiguration Configuration { get; } |
|
||||
|
|
||||
public EventStoreModule(IConfiguration configuration) |
|
||||
{ |
|
||||
Configuration = configuration; |
|
||||
} |
|
||||
|
|
||||
protected override void Load(ContainerBuilder builder) |
|
||||
{ |
|
||||
var consumeEvents = Configuration.GetValue<bool>("eventStore:consume"); |
|
||||
|
|
||||
if (consumeEvents) |
|
||||
{ |
|
||||
builder.RegisterType<EventConsumerActor>() |
|
||||
.AsSelf() |
|
||||
.InstancePerDependency(); |
|
||||
} |
|
||||
|
|
||||
var eventStoreType = Configuration.GetValue<string>("eventStore:type"); |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(eventStoreType)) |
|
||||
{ |
|
||||
throw new ConfigurationException("Configure EventStore type with 'eventStore:type'."); |
|
||||
} |
|
||||
|
|
||||
if (string.Equals(eventStoreType, "MongoDb", StringComparison.OrdinalIgnoreCase)) |
|
||||
{ |
|
||||
var configuration = Configuration.GetValue<string>("eventStore:mongoDb:configuration"); |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(configuration)) |
|
||||
{ |
|
||||
throw new ConfigurationException("Configure EventStore MongoDb configuration with 'eventStore:mongoDb:configuration'."); |
|
||||
} |
|
||||
|
|
||||
var database = Configuration.GetValue<string>("eventStore:mongoDb:database"); |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(database)) |
|
||||
{ |
|
||||
throw new ConfigurationException("Configure EventStore MongoDb Database name with 'eventStore:mongoDb:database'."); |
|
||||
} |
|
||||
|
|
||||
builder.Register(c => Singletons<IMongoClient>.GetOrAdd(configuration, s => new MongoClient(s))) |
|
||||
.Named<IMongoClient>(MongoClientRegistration) |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.Register(c => c.ResolveNamed<IMongoClient>(MongoClientRegistration).GetDatabase(database)) |
|
||||
.Named<IMongoDatabase>(MongoDatabaseRegistration) |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<MongoEventStore>() |
|
||||
.WithParameter(ResolvedParameter.ForNamed<IMongoDatabase>(MongoDatabaseRegistration)) |
|
||||
.As<IExternalSystem>() |
|
||||
.As<IEventStore>() |
|
||||
.SingleInstance(); |
|
||||
} |
|
||||
else if (string.Equals(eventStoreType, "GetEventStore", StringComparison.OrdinalIgnoreCase)) |
|
||||
{ |
|
||||
var configuration = Configuration.GetValue<string>("eventStore:getEventStore:configuration"); |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(configuration)) |
|
||||
{ |
|
||||
throw new ConfigurationException("Configure GetEventStore EventStore configuration with 'eventStore:getEventStore:configuration'."); |
|
||||
} |
|
||||
|
|
||||
var projectionHost = Configuration.GetValue<string>("eventStore:getEventStore:projectionHost"); |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(projectionHost)) |
|
||||
{ |
|
||||
throw new ConfigurationException("Configure GetEventStore EventStore projection host with 'eventStore:getEventStore:projectionHost'."); |
|
||||
} |
|
||||
|
|
||||
var prefix = Configuration.GetValue<string>("eventStore:getEventStore:prefix"); |
|
||||
|
|
||||
var connection = EventStoreConnection.Create(configuration); |
|
||||
|
|
||||
builder.Register(c => new GetEventStore(connection, prefix, projectionHost)) |
|
||||
.As<IExternalSystem>() |
|
||||
.As<IEventStore>() |
|
||||
.SingleInstance(); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
throw new ConfigurationException($"Unsupported value '{eventStoreType}' for 'eventStore:type', supported: MongoDb, GetEventStore."); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,64 @@ |
|||||
|
// ==========================================================================
|
||||
|
// EventStoreServices.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using EventStore.ClientAPI; |
||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using MongoDB.Driver; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.CQRS.Events; |
||||
|
using Squidex.Infrastructure.CQRS.Events.Actors; |
||||
|
|
||||
|
namespace Squidex.Config.Domain |
||||
|
{ |
||||
|
public static class EventStoreServices |
||||
|
{ |
||||
|
public static void AddMyEventStoreServices(this IServiceCollection services, IConfiguration config) |
||||
|
{ |
||||
|
var consumeEvents = config.GetOptionalValue("eventStore:consume", false); |
||||
|
|
||||
|
if (!consumeEvents) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
config.ConfigureByOption("eventStore:type", new Options |
||||
|
{ |
||||
|
["MongoDb"] = () => |
||||
|
{ |
||||
|
var mongoConfiguration = config.GetRequiredValue("eventStore:mongoDb:configuration"); |
||||
|
var mongoDatabaseName = config.GetRequiredValue("eventStore:mongoDb:database"); |
||||
|
|
||||
|
services.AddSingleton(c => |
||||
|
{ |
||||
|
var mongoClient = Singletons<IMongoClient>.GetOrAdd(mongoConfiguration, s => new MongoClient(s)); |
||||
|
var mongDatabase = mongoClient.GetDatabase(mongoDatabaseName); |
||||
|
|
||||
|
return new MongoEventStore(mongDatabase, c.GetRequiredService<IEventNotifier>()); |
||||
|
}) |
||||
|
.As<IExternalSystem>() |
||||
|
.As<IEventStore>(); |
||||
|
}, |
||||
|
["GetEventStore"] = () => |
||||
|
{ |
||||
|
var eventStoreConfiguration = config.GetRequiredValue("eventStore:getEventStore:configuration"); |
||||
|
var eventStoreProjectionHost = config.GetRequiredValue("eventStore:getEventStore:projectionHost"); |
||||
|
var eventStorePrefix = config.GetValue<string>("eventStore:getEventStore:prefix"); |
||||
|
|
||||
|
var connection = EventStoreConnection.Create(eventStoreConfiguration); |
||||
|
|
||||
|
services.AddSingleton(c => new GetEventStore(connection, eventStorePrefix, eventStoreProjectionHost)) |
||||
|
.As<IExternalSystem>() |
||||
|
.As<IEventStore>(); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
services.AddSingleton<EventConsumerActor>(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,155 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// InfrastructureModule.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System; |
|
||||
using Autofac; |
|
||||
using Microsoft.AspNetCore.Http; |
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure; |
|
||||
using Microsoft.Extensions.Caching.Memory; |
|
||||
using Microsoft.Extensions.Configuration; |
|
||||
using Microsoft.Extensions.Options; |
|
||||
using Newtonsoft.Json; |
|
||||
using NodaTime; |
|
||||
using Squidex.Infrastructure; |
|
||||
using Squidex.Infrastructure.Actors; |
|
||||
using Squidex.Infrastructure.Assets; |
|
||||
using Squidex.Infrastructure.Assets.ImageSharp; |
|
||||
using Squidex.Infrastructure.Caching; |
|
||||
using Squidex.Infrastructure.CQRS.Commands; |
|
||||
using Squidex.Infrastructure.CQRS.Events; |
|
||||
using Squidex.Infrastructure.Log; |
|
||||
using Squidex.Infrastructure.UsageTracking; |
|
||||
using Squidex.Pipeline; |
|
||||
|
|
||||
namespace Squidex.Config.Domain |
|
||||
{ |
|
||||
public sealed class InfrastructureModule : Module |
|
||||
{ |
|
||||
private IConfiguration Configuration { get; } |
|
||||
|
|
||||
public InfrastructureModule(IConfiguration configuration) |
|
||||
{ |
|
||||
Configuration = configuration; |
|
||||
} |
|
||||
|
|
||||
protected override void Load(ContainerBuilder builder) |
|
||||
{ |
|
||||
if (Configuration.GetValue<bool>("logging:human")) |
|
||||
{ |
|
||||
builder.Register(c => new Func<IObjectWriter>(() => new JsonLogWriter(Formatting.Indented, true))) |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
builder.Register(c => new Func<IObjectWriter>(() => new JsonLogWriter())) |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
} |
|
||||
|
|
||||
var loggingFile = Configuration.GetValue<string>("logging:file"); |
|
||||
|
|
||||
if (!string.IsNullOrWhiteSpace(loggingFile)) |
|
||||
{ |
|
||||
builder.RegisterInstance(new FileChannel(loggingFile)) |
|
||||
.As<ILogChannel>() |
|
||||
.As<IExternalSystem>() |
|
||||
.SingleInstance(); |
|
||||
} |
|
||||
|
|
||||
builder.Register(c => new ApplicationInfoLogAppender(GetType(), Guid.NewGuid())) |
|
||||
.As<ILogAppender>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<ActionContextLogAppender>() |
|
||||
.As<ILogAppender>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<TimestampLogAppender>() |
|
||||
.As<ILogAppender>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<DebugLogChannel>() |
|
||||
.As<ILogChannel>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<ConsoleLogChannel>() |
|
||||
.As<ILogChannel>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<SemanticLog>() |
|
||||
.As<ISemanticLog>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.Register(c => SystemClock.Instance) |
|
||||
.As<IClock>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<BackgroundUsageTracker>() |
|
||||
.As<IUsageTracker>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<HttpContextAccessor>() |
|
||||
.As<IHttpContextAccessor>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<ActionContextAccessor>() |
|
||||
.As<IActionContextAccessor>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<DefaultDomainObjectRepository>() |
|
||||
.As<IDomainObjectRepository>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<DefaultDomainObjectFactory>() |
|
||||
.As<IDomainObjectFactory>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<AggregateHandler>() |
|
||||
.As<IAggregateHandler>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<InMemoryCommandBus>() |
|
||||
.As<ICommandBus>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<DefaultEventNotifier>() |
|
||||
.As<IEventNotifier>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<DefaultStreamNameResolver>() |
|
||||
.As<IStreamNameResolver>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<ImageSharpAssetThumbnailGenerator>() |
|
||||
.As<IAssetThumbnailGenerator>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.Register(c => new InvalidatingMemoryCache(new MemoryCache(c.Resolve<IOptions<MemoryCacheOptions>>()), c.Resolve<IPubSub>())) |
|
||||
.As<IMemoryCache>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<DefaultRemoteActorChannel>() |
|
||||
.As<IRemoteActorChannel>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<RemoteActors>() |
|
||||
.As<IActors>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<EventConsumerCleaner>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<EventDataFormatter>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,116 @@ |
|||||
|
// ==========================================================================
|
||||
|
// InfrastructureServices.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using Microsoft.AspNetCore.Http; |
||||
|
using Microsoft.AspNetCore.Mvc.Infrastructure; |
||||
|
using Microsoft.Extensions.Caching.Memory; |
||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Newtonsoft.Json; |
||||
|
using NodaTime; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.Actors; |
||||
|
using Squidex.Infrastructure.Assets; |
||||
|
using Squidex.Infrastructure.Assets.ImageSharp; |
||||
|
using Squidex.Infrastructure.Caching; |
||||
|
using Squidex.Infrastructure.CQRS.Commands; |
||||
|
using Squidex.Infrastructure.CQRS.Events; |
||||
|
using Squidex.Infrastructure.Log; |
||||
|
using Squidex.Infrastructure.UsageTracking; |
||||
|
using Squidex.Pipeline; |
||||
|
|
||||
|
namespace Squidex.Config.Domain |
||||
|
{ |
||||
|
public static class InfrastructureServices |
||||
|
{ |
||||
|
public static void AddMyInfrastructureServices(this IServiceCollection services, IConfiguration config) |
||||
|
{ |
||||
|
if (config.GetValue<bool>("logging:human")) |
||||
|
{ |
||||
|
services.AddSingleton(c => new Func<IObjectWriter>(() => new JsonLogWriter(Formatting.Indented, true))); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
services.AddSingleton(c => new Func<IObjectWriter>(() => new JsonLogWriter())); |
||||
|
} |
||||
|
|
||||
|
var loggingFile = config.GetValue<string>("logging:file"); |
||||
|
|
||||
|
if (!string.IsNullOrWhiteSpace(loggingFile)) |
||||
|
{ |
||||
|
services.AddSingleton(new FileChannel(loggingFile)) |
||||
|
.As<ILogChannel>() |
||||
|
.As<IExternalSystem>(); |
||||
|
} |
||||
|
|
||||
|
services.AddSingleton(c => new ApplicationInfoLogAppender(typeof(Startup).Assembly, Guid.NewGuid())) |
||||
|
.As<ILogAppender>(); |
||||
|
|
||||
|
services.AddSingleton<ActionContextLogAppender>() |
||||
|
.As<ILogAppender>(); |
||||
|
|
||||
|
services.AddSingleton<TimestampLogAppender>() |
||||
|
.As<ILogAppender>(); |
||||
|
|
||||
|
services.AddSingleton<DebugLogChannel>() |
||||
|
.As<ILogChannel>(); |
||||
|
|
||||
|
services.AddSingleton<ConsoleLogChannel>() |
||||
|
.As<ILogChannel>(); |
||||
|
|
||||
|
services.AddSingleton<SemanticLog>() |
||||
|
.As<ISemanticLog>(); |
||||
|
|
||||
|
services.AddSingleton(SystemClock.Instance) |
||||
|
.As<IClock>(); |
||||
|
|
||||
|
services.AddSingleton<BackgroundUsageTracker>() |
||||
|
.As<IUsageTracker>(); |
||||
|
|
||||
|
services.AddSingleton<HttpContextAccessor>() |
||||
|
.As<IHttpContextAccessor>(); |
||||
|
|
||||
|
services.AddSingleton<ActionContextAccessor>() |
||||
|
.As<IActionContextAccessor>(); |
||||
|
|
||||
|
services.AddSingleton<DefaultDomainObjectRepository>() |
||||
|
.As<IDomainObjectRepository>(); |
||||
|
|
||||
|
services.AddSingleton<DefaultDomainObjectFactory>() |
||||
|
.As<IDomainObjectFactory>(); |
||||
|
|
||||
|
services.AddSingleton<AggregateHandler>() |
||||
|
.As<IAggregateHandler>(); |
||||
|
|
||||
|
services.AddSingleton<InMemoryCommandBus>() |
||||
|
.As<ICommandBus>(); |
||||
|
|
||||
|
services.AddSingleton<DefaultEventNotifier>() |
||||
|
.As<IEventNotifier>(); |
||||
|
|
||||
|
services.AddSingleton<DefaultStreamNameResolver>() |
||||
|
.As<IStreamNameResolver>(); |
||||
|
|
||||
|
services.AddSingleton<ImageSharpAssetThumbnailGenerator>() |
||||
|
.As<IAssetThumbnailGenerator>(); |
||||
|
|
||||
|
services.AddSingleton<InvalidatingMemoryCache>() |
||||
|
.As<IMemoryCache>(); |
||||
|
|
||||
|
services.AddSingleton<DefaultRemoteActorChannel>() |
||||
|
.As<IRemoteActorChannel>(); |
||||
|
|
||||
|
services.AddSingleton<RemoteActors>() |
||||
|
.As<IActors>(); |
||||
|
|
||||
|
services.AddSingleton<EventConsumerCleaner>(); |
||||
|
services.AddSingleton<EventDataFormatter>(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,69 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// PubSubModule.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 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>.GetOrAddLazy(configuration, s => ConnectionMultiplexer.Connect(s))) |
|
||||
.Named<Lazy<IConnectionMultiplexer>>(RedisRegistration) |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<RedisPubSub>() |
|
||||
.WithParameter(ResolvedParameter.ForNamed<Lazy<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."); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,41 @@ |
|||||
|
// ==========================================================================
|
||||
|
// PubSubServices.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.Log; |
||||
|
using StackExchange.Redis; |
||||
|
|
||||
|
namespace Squidex.Config.Domain |
||||
|
{ |
||||
|
public static class PubSubServices |
||||
|
{ |
||||
|
public static void AddMyPubSubServices(this IServiceCollection services, IConfiguration config) |
||||
|
{ |
||||
|
config.ConfigureByOption("pubSub:type", new Options |
||||
|
{ |
||||
|
["InMemory"] = () => |
||||
|
{ |
||||
|
services.AddSingleton<InMemoryPubSub>() |
||||
|
.As<IPubSub>(); |
||||
|
}, |
||||
|
["Redis"] = () => |
||||
|
{ |
||||
|
var configuration = config.GetRequiredValue("pubsub:redis:configuration"); |
||||
|
|
||||
|
var redis = Singletons<IConnectionMultiplexer>.GetOrAddLazy(configuration, s => ConnectionMultiplexer.Connect(s)); |
||||
|
|
||||
|
services.AddSingleton(c => new RedisPubSub(redis, c.GetRequiredService<ISemanticLog>())) |
||||
|
.As<IPubSub>() |
||||
|
.As<IExternalSystem>(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,139 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// ReadModule.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using Autofac; |
|
||||
using Microsoft.Extensions.Configuration; |
|
||||
using Microsoft.Extensions.Options; |
|
||||
using Squidex.Domain.Apps.Core.HandleRules; |
|
||||
using Squidex.Domain.Apps.Core.HandleRules.ActionHandlers; |
|
||||
using Squidex.Domain.Apps.Core.HandleRules.Triggers; |
|
||||
using Squidex.Domain.Apps.Read.Apps; |
|
||||
using Squidex.Domain.Apps.Read.Apps.Services; |
|
||||
using Squidex.Domain.Apps.Read.Apps.Services.Implementations; |
|
||||
using Squidex.Domain.Apps.Read.Contents; |
|
||||
using Squidex.Domain.Apps.Read.Contents.Edm; |
|
||||
using Squidex.Domain.Apps.Read.Contents.GraphQL; |
|
||||
using Squidex.Domain.Apps.Read.History; |
|
||||
using Squidex.Domain.Apps.Read.Rules; |
|
||||
using Squidex.Domain.Apps.Read.Schemas; |
|
||||
using Squidex.Domain.Apps.Read.Schemas.Services; |
|
||||
using Squidex.Domain.Apps.Read.Schemas.Services.Implementations; |
|
||||
using Squidex.Domain.Users; |
|
||||
using Squidex.Infrastructure; |
|
||||
using Squidex.Infrastructure.Assets; |
|
||||
using Squidex.Infrastructure.CQRS.Events; |
|
||||
using Squidex.Pipeline; |
|
||||
|
|
||||
namespace Squidex.Config.Domain |
|
||||
{ |
|
||||
public sealed class ReadModule : Module |
|
||||
{ |
|
||||
private IConfiguration Configuration { get; } |
|
||||
|
|
||||
public ReadModule(IConfiguration configuration) |
|
||||
{ |
|
||||
Configuration = configuration; |
|
||||
} |
|
||||
|
|
||||
protected override void Load(ContainerBuilder builder) |
|
||||
{ |
|
||||
builder.Register(c => c.Resolve<IOptions<MyUsageOptions>>().Value?.Plans ?? Enumerable.Empty<ConfigAppLimitsPlan>()) |
|
||||
.As<IEnumerable<ConfigAppLimitsPlan>>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.Register(c => new GraphQLUrlGenerator( |
|
||||
c.Resolve<IOptions<MyUrlsOptions>>(), |
|
||||
c.Resolve<IAssetStore>(), |
|
||||
Configuration.GetValue<bool>("assetStore:exposeSourceUrl"))) |
|
||||
.As<IGraphQLUrlGenerator>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<CachingGraphQLService>() |
|
||||
.As<IGraphQLService>() |
|
||||
.AsSelf() |
|
||||
.InstancePerDependency(); |
|
||||
|
|
||||
builder.RegisterType<ContentQueryService>() |
|
||||
.As<IContentQueryService>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<CachingAppProvider>() |
|
||||
.As<IAppProvider>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<ConfigAppPlansProvider>() |
|
||||
.As<IAppPlansProvider>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<CachingSchemaProvider>() |
|
||||
.As<ISchemaProvider>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<AssetUserPictureStore>() |
|
||||
.As<IUserPictureStore>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<AppHistoryEventsCreator>() |
|
||||
.As<IHistoryEventsCreator>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<ContentHistoryEventsCreator>() |
|
||||
.As<IHistoryEventsCreator>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<SchemaHistoryEventsCreator>() |
|
||||
.As<IHistoryEventsCreator>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<NoopAppPlanBillingManager>() |
|
||||
.As<IAppPlanBillingManager>() |
|
||||
.AsSelf() |
|
||||
.InstancePerDependency(); |
|
||||
|
|
||||
builder.RegisterType<RuleDequeuer>() |
|
||||
.As<IExternalSystem>() |
|
||||
.AsSelf() |
|
||||
.InstancePerDependency(); |
|
||||
|
|
||||
builder.RegisterType<RuleEnqueuer>() |
|
||||
.As<IEventConsumer>() |
|
||||
.AsSelf() |
|
||||
.InstancePerDependency(); |
|
||||
|
|
||||
builder.RegisterType<ContentChangedTriggerHandler>() |
|
||||
.As<IRuleTriggerHandler>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<WebhookActionHandler>() |
|
||||
.As<IRuleActionHandler>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<RuleService>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<EdmModelBuilder>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,114 @@ |
|||||
|
// ==========================================================================
|
||||
|
// ReadServices.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Squidex.Domain.Apps.Core.HandleRules; |
||||
|
using Squidex.Domain.Apps.Core.HandleRules.ActionHandlers; |
||||
|
using Squidex.Domain.Apps.Core.HandleRules.Triggers; |
||||
|
using Squidex.Domain.Apps.Read.Apps; |
||||
|
using Squidex.Domain.Apps.Read.Apps.Services; |
||||
|
using Squidex.Domain.Apps.Read.Apps.Services.Implementations; |
||||
|
using Squidex.Domain.Apps.Read.Assets; |
||||
|
using Squidex.Domain.Apps.Read.Contents; |
||||
|
using Squidex.Domain.Apps.Read.Contents.Edm; |
||||
|
using Squidex.Domain.Apps.Read.Contents.GraphQL; |
||||
|
using Squidex.Domain.Apps.Read.History; |
||||
|
using Squidex.Domain.Apps.Read.Rules; |
||||
|
using Squidex.Domain.Apps.Read.Schemas; |
||||
|
using Squidex.Domain.Apps.Read.Schemas.Services; |
||||
|
using Squidex.Domain.Apps.Read.Schemas.Services.Implementations; |
||||
|
using Squidex.Domain.Users; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.Assets; |
||||
|
using Squidex.Infrastructure.CQRS.Events; |
||||
|
using Squidex.Pipeline; |
||||
|
|
||||
|
namespace Squidex.Config.Domain |
||||
|
{ |
||||
|
public static class ReadServices |
||||
|
{ |
||||
|
public static void AddMyReadServices(this IServiceCollection services, IConfiguration config) |
||||
|
{ |
||||
|
var exposeSourceUrl = config.GetOptionalValue("assetStore:exposeSourceUrl", true); |
||||
|
|
||||
|
services.AddSingleton(c => new GraphQLUrlGenerator( |
||||
|
c.GetRequiredService<IOptions<MyUrlsOptions>>(), |
||||
|
c.GetRequiredService<IAssetStore>(), |
||||
|
exposeSourceUrl)) |
||||
|
.As<IGraphQLUrlGenerator>(); |
||||
|
|
||||
|
services.AddSingleton(c => c.GetService<IOptions<MyUsageOptions>>()?.Value?.Plans.OrEmpty()) |
||||
|
.As<IEnumerable<ConfigAppLimitsPlan>>(); |
||||
|
|
||||
|
services.AddSingleton<CachingGraphQLService>() |
||||
|
.As<IGraphQLService>(); |
||||
|
|
||||
|
services.AddSingleton<ContentQueryService>() |
||||
|
.As<IContentQueryService>(); |
||||
|
|
||||
|
services.AddSingleton<CachingAppProvider>() |
||||
|
.As<IAppProvider>(); |
||||
|
|
||||
|
services.AddSingleton<ConfigAppPlansProvider>() |
||||
|
.As<IAppPlansProvider>(); |
||||
|
|
||||
|
services.AddSingleton<CachingSchemaProvider>() |
||||
|
.As<ISchemaProvider>(); |
||||
|
|
||||
|
services.AddSingleton<AssetUserPictureStore>() |
||||
|
.As<IUserPictureStore>(); |
||||
|
|
||||
|
services.AddSingleton<AppHistoryEventsCreator>() |
||||
|
.As<IHistoryEventsCreator>(); |
||||
|
|
||||
|
services.AddSingleton<ContentHistoryEventsCreator>() |
||||
|
.As<IHistoryEventsCreator>(); |
||||
|
|
||||
|
services.AddSingleton<SchemaHistoryEventsCreator>() |
||||
|
.As<IHistoryEventsCreator>(); |
||||
|
|
||||
|
services.AddSingleton<NoopAppPlanBillingManager>() |
||||
|
.As<IAppPlanBillingManager>(); |
||||
|
|
||||
|
services.AddSingleton<RuleDequeuer>() |
||||
|
.As<IExternalSystem>(); |
||||
|
|
||||
|
services.AddSingleton<RuleEnqueuer>() |
||||
|
.As<IEventConsumer>(); |
||||
|
|
||||
|
services.AddSingleton<ContentChangedTriggerHandler>() |
||||
|
.As<IRuleTriggerHandler>(); |
||||
|
|
||||
|
services.AddSingleton<WebhookActionHandler>() |
||||
|
.As<IRuleActionHandler>(); |
||||
|
|
||||
|
services.AddSingleton(c => new CompoundEventConsumer(c.GetServices<IAssetEventConsumer>().ToArray())) |
||||
|
.As<IEventConsumer>(); |
||||
|
|
||||
|
services.AddSingleton(c => |
||||
|
new CompoundEventConsumer( |
||||
|
c.GetServices<IAppEventConsumer>().OfType<IEventConsumer>() |
||||
|
.Concat(c.GetRequiredService<CachingAppProvider>()).ToArray())) |
||||
|
.As<IEventConsumer>(); |
||||
|
|
||||
|
services.AddSingleton(c => |
||||
|
new CompoundEventConsumer( |
||||
|
c.GetServices<ISchemaEventConsumer>().OfType<IEventConsumer>() |
||||
|
.Concat(c.GetRequiredService<CachingGraphQLService>()) |
||||
|
.Concat(c.GetRequiredService<CachingSchemaProvider>()).ToArray())) |
||||
|
.As<IEventConsumer>(); |
||||
|
|
||||
|
services.AddSingleton<RuleService>(); |
||||
|
services.AddSingleton<EdmModelBuilder>(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,44 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// StoreModule.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System; |
|
||||
using Autofac; |
|
||||
using Microsoft.Extensions.Configuration; |
|
||||
using Squidex.Infrastructure; |
|
||||
|
|
||||
namespace Squidex.Config.Domain |
|
||||
{ |
|
||||
public class StoreModule : Module |
|
||||
{ |
|
||||
private IConfiguration Configuration { get; } |
|
||||
|
|
||||
public StoreModule(IConfiguration configuration) |
|
||||
{ |
|
||||
Configuration = configuration; |
|
||||
} |
|
||||
|
|
||||
protected override void Load(ContainerBuilder builder) |
|
||||
{ |
|
||||
var storeType = Configuration.GetValue<string>("store:type"); |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(storeType)) |
|
||||
{ |
|
||||
throw new ConfigurationException("Configure the Store type with 'store:type'."); |
|
||||
} |
|
||||
|
|
||||
if (string.Equals(storeType, "MongoDB", StringComparison.OrdinalIgnoreCase)) |
|
||||
{ |
|
||||
builder.RegisterModule(new StoreMongoDbModule(Configuration)); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
throw new ConfigurationException($"Unsupported value '{storeType}' for 'stores:type', supported: MongoDb."); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,208 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// StoreMongoDbModule.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Autofac; |
|
||||
using Autofac.Core; |
|
||||
using IdentityServer4.Stores; |
|
||||
using Microsoft.AspNetCore.Identity; |
|
||||
using Microsoft.Extensions.Configuration; |
|
||||
using MongoDB.Driver; |
|
||||
using Squidex.Domain.Apps.Read.Apps.Repositories; |
|
||||
using Squidex.Domain.Apps.Read.Apps.Services.Implementations; |
|
||||
using Squidex.Domain.Apps.Read.Assets.Repositories; |
|
||||
using Squidex.Domain.Apps.Read.Contents.GraphQL; |
|
||||
using Squidex.Domain.Apps.Read.Contents.Repositories; |
|
||||
using Squidex.Domain.Apps.Read.History.Repositories; |
|
||||
using Squidex.Domain.Apps.Read.MongoDb.Apps; |
|
||||
using Squidex.Domain.Apps.Read.MongoDb.Assets; |
|
||||
using Squidex.Domain.Apps.Read.MongoDb.Contents; |
|
||||
using Squidex.Domain.Apps.Read.MongoDb.History; |
|
||||
using Squidex.Domain.Apps.Read.MongoDb.Rules; |
|
||||
using Squidex.Domain.Apps.Read.MongoDb.Schemas; |
|
||||
using Squidex.Domain.Apps.Read.Rules.Repositories; |
|
||||
using Squidex.Domain.Apps.Read.Schemas.Repositories; |
|
||||
using Squidex.Domain.Apps.Read.Schemas.Services.Implementations; |
|
||||
using Squidex.Domain.Users; |
|
||||
using Squidex.Domain.Users.MongoDb; |
|
||||
using Squidex.Domain.Users.MongoDb.Infrastructure; |
|
||||
using Squidex.Infrastructure; |
|
||||
using Squidex.Infrastructure.CQRS.Events; |
|
||||
using Squidex.Infrastructure.UsageTracking; |
|
||||
using Squidex.Shared.Users; |
|
||||
|
|
||||
namespace Squidex.Config.Domain |
|
||||
{ |
|
||||
public class StoreMongoDbModule : Module |
|
||||
{ |
|
||||
private const string MongoClientRegistration = "StoreMongoClient"; |
|
||||
private const string MongoDatabaseRegistration = "StoreMongoDatabaseName"; |
|
||||
private const string MongoContentDatabaseRegistration = "StoreMongoDatabaseNameContent"; |
|
||||
|
|
||||
private IConfiguration Configuration { get; } |
|
||||
|
|
||||
public StoreMongoDbModule(IConfiguration configuration) |
|
||||
{ |
|
||||
Configuration = configuration; |
|
||||
} |
|
||||
|
|
||||
protected override void Load(ContainerBuilder builder) |
|
||||
{ |
|
||||
var configuration = Configuration.GetValue<string>("store:mongoDb:configuration"); |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(configuration)) |
|
||||
{ |
|
||||
throw new ConfigurationException("Configure the Store MongoDb configuration with 'store:mongoDb:configuration'."); |
|
||||
} |
|
||||
|
|
||||
var database = Configuration.GetValue<string>("store:mongoDb:database"); |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(database)) |
|
||||
{ |
|
||||
throw new ConfigurationException("Configure the Store MongoDb database with 'store:mongoDb:database'."); |
|
||||
} |
|
||||
|
|
||||
var contentDatabase = Configuration.GetValue<string>("store:mongoDb:contentDatabase"); |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(contentDatabase)) |
|
||||
{ |
|
||||
contentDatabase = database; |
|
||||
} |
|
||||
|
|
||||
builder.Register(c => Singletons<IMongoClient>.GetOrAdd(configuration, s => new MongoClient(s))) |
|
||||
.Named<IMongoClient>(MongoClientRegistration) |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.Register(c => c.ResolveNamed<IMongoClient>(MongoClientRegistration).GetDatabase(database)) |
|
||||
.Named<IMongoDatabase>(MongoDatabaseRegistration) |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.Register(c => c.ResolveNamed<IMongoClient>(MongoClientRegistration).GetDatabase(contentDatabase)) |
|
||||
.Named<IMongoDatabase>(MongoContentDatabaseRegistration) |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<MongoUserStore>() |
|
||||
.WithParameter(ResolvedParameter.ForNamed<IMongoDatabase>(MongoDatabaseRegistration)) |
|
||||
.As<IUserStore<IUser>>() |
|
||||
.As<IUserFactory>() |
|
||||
.As<IUserResolver>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<MongoRoleStore>() |
|
||||
.WithParameter(ResolvedParameter.ForNamed<IMongoDatabase>(MongoDatabaseRegistration)) |
|
||||
.As<IRoleStore<IRole>>() |
|
||||
.As<IRoleFactory>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<MongoPersistedGrantStore>() |
|
||||
.WithParameter(ResolvedParameter.ForNamed<IMongoDatabase>(MongoDatabaseRegistration)) |
|
||||
.As<IPersistedGrantStore>() |
|
||||
.As<IExternalSystem>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<MongoUsageStore>() |
|
||||
.WithParameter(ResolvedParameter.ForNamed<IMongoDatabase>(MongoDatabaseRegistration)) |
|
||||
.As<IUsageStore>() |
|
||||
.As<IExternalSystem>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<MongoHistoryEventRepository>() |
|
||||
.WithParameter(ResolvedParameter.ForNamed<IMongoDatabase>(MongoDatabaseRegistration)) |
|
||||
.As<IHistoryEventRepository>() |
|
||||
.As<IEventConsumer>() |
|
||||
.As<IExternalSystem>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<MongoEventConsumerInfoRepository>() |
|
||||
.WithParameter(ResolvedParameter.ForNamed<IMongoDatabase>(MongoDatabaseRegistration)) |
|
||||
.As<IEventConsumerInfoRepository>() |
|
||||
.As<IExternalSystem>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<MongoContentRepository>() |
|
||||
.WithParameter(ResolvedParameter.ForNamed<IMongoDatabase>(MongoContentDatabaseRegistration)) |
|
||||
.As<IContentRepository>() |
|
||||
.As<IEventConsumer>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<MongoRuleEventRepository>() |
|
||||
.WithParameter(ResolvedParameter.ForNamed<IMongoDatabase>(MongoDatabaseRegistration)) |
|
||||
.As<IRuleEventRepository>() |
|
||||
.As<IExternalSystem>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<MongoAppRepository>() |
|
||||
.WithParameter(ResolvedParameter.ForNamed<IMongoDatabase>(MongoDatabaseRegistration)) |
|
||||
.As<IAppRepository>() |
|
||||
.As<IExternalSystem>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<MongoSchemaRepository>() |
|
||||
.WithParameter(ResolvedParameter.ForNamed<IMongoDatabase>(MongoDatabaseRegistration)) |
|
||||
.As<ISchemaRepository>() |
|
||||
.As<IExternalSystem>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<MongoAssetStatsRepository>() |
|
||||
.WithParameter(ResolvedParameter.ForNamed<IMongoDatabase>(MongoDatabaseRegistration)) |
|
||||
.As<IAssetStatsRepository>() |
|
||||
.As<IExternalSystem>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<MongoAssetRepository>() |
|
||||
.WithParameter(ResolvedParameter.ForNamed<IMongoDatabase>(MongoDatabaseRegistration)) |
|
||||
.As<IAssetRepository>() |
|
||||
.As<IExternalSystem>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<MongoRuleRepository>() |
|
||||
.WithParameter(ResolvedParameter.ForNamed<IMongoDatabase>(MongoDatabaseRegistration)) |
|
||||
.As<IRuleRepository>() |
|
||||
.As<IEventConsumer>() |
|
||||
.As<IExternalSystem>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.Register(c => |
|
||||
new CompoundEventConsumer( |
|
||||
c.Resolve<MongoAssetRepository>(), |
|
||||
c.Resolve<MongoAssetStatsRepository>())) |
|
||||
.As<IEventConsumer>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.Register(c => |
|
||||
new CompoundEventConsumer( |
|
||||
c.Resolve<MongoSchemaRepository>(), |
|
||||
c.Resolve<CachingGraphQLService>(), |
|
||||
c.Resolve<CachingSchemaProvider>())) |
|
||||
.As<IEventConsumer>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.Register(c => |
|
||||
new CompoundEventConsumer( |
|
||||
c.Resolve<MongoAppRepository>(), |
|
||||
c.Resolve<CachingAppProvider>())) |
|
||||
.As<IEventConsumer>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,122 @@ |
|||||
|
// ==========================================================================
|
||||
|
// StoreServices.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using IdentityServer4.Stores; |
||||
|
using Microsoft.AspNetCore.Identity; |
||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using MongoDB.Driver; |
||||
|
using Squidex.Domain.Apps.Core.Schemas; |
||||
|
using Squidex.Domain.Apps.Read.Apps; |
||||
|
using Squidex.Domain.Apps.Read.Apps.Repositories; |
||||
|
using Squidex.Domain.Apps.Read.Assets; |
||||
|
using Squidex.Domain.Apps.Read.Assets.Repositories; |
||||
|
using Squidex.Domain.Apps.Read.Contents.Repositories; |
||||
|
using Squidex.Domain.Apps.Read.History; |
||||
|
using Squidex.Domain.Apps.Read.History.Repositories; |
||||
|
using Squidex.Domain.Apps.Read.MongoDb.Apps; |
||||
|
using Squidex.Domain.Apps.Read.MongoDb.Assets; |
||||
|
using Squidex.Domain.Apps.Read.MongoDb.Contents; |
||||
|
using Squidex.Domain.Apps.Read.MongoDb.History; |
||||
|
using Squidex.Domain.Apps.Read.MongoDb.Rules; |
||||
|
using Squidex.Domain.Apps.Read.MongoDb.Schemas; |
||||
|
using Squidex.Domain.Apps.Read.Rules.Repositories; |
||||
|
using Squidex.Domain.Apps.Read.Schemas; |
||||
|
using Squidex.Domain.Apps.Read.Schemas.Repositories; |
||||
|
using Squidex.Domain.Apps.Read.Schemas.Services; |
||||
|
using Squidex.Domain.Users; |
||||
|
using Squidex.Domain.Users.MongoDb; |
||||
|
using Squidex.Domain.Users.MongoDb.Infrastructure; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.CQRS.Events; |
||||
|
using Squidex.Infrastructure.UsageTracking; |
||||
|
using Squidex.Shared.Users; |
||||
|
|
||||
|
namespace Squidex.Config.Domain |
||||
|
{ |
||||
|
public static class StoreServices |
||||
|
{ |
||||
|
public static void AddMyStoreServices(this IServiceCollection services, IConfiguration config) |
||||
|
{ |
||||
|
config.ConfigureByOption("store:type", new Options |
||||
|
{ |
||||
|
["MongoDB"] = () => |
||||
|
{ |
||||
|
var mongoConfiguration = config.GetRequiredValue("store:mongoDb:configuration"); |
||||
|
var mongoDatabaseName = config.GetRequiredValue("store:mongoDb:database"); |
||||
|
var mongoContentDatabaseName = config.GetOptionalValue("store:mongoDb:contentDatabase", mongoDatabaseName); |
||||
|
|
||||
|
var mongoClient = Singletons<IMongoClient>.GetOrAdd(mongoConfiguration, s => new MongoClient(s)); |
||||
|
var mongoDatabase = mongoClient.GetDatabase(mongoDatabaseName); |
||||
|
var mongoContentDatabase = mongoClient.GetDatabase(mongoContentDatabaseName); |
||||
|
|
||||
|
services.AddSingleton(c => new MongoUserStore(mongoDatabase)) |
||||
|
.As<IUserStore<IUser>>() |
||||
|
.As<IUserFactory>() |
||||
|
.As<IUserResolver>() |
||||
|
.As<IExternalSystem>(); |
||||
|
|
||||
|
services.AddSingleton(c => new MongoRoleStore(mongoDatabase)) |
||||
|
.As<IRoleStore<IRole>>() |
||||
|
.As<IRoleFactory>() |
||||
|
.As<IExternalSystem>(); |
||||
|
|
||||
|
services.AddSingleton(c => new MongoPersistedGrantStore(mongoDatabase)) |
||||
|
.As<IPersistedGrantStore>() |
||||
|
.As<IExternalSystem>(); |
||||
|
|
||||
|
services.AddSingleton(c => new MongoUsageStore(mongoDatabase)) |
||||
|
.As<IUsageStore>() |
||||
|
.As<IExternalSystem>(); |
||||
|
|
||||
|
services.AddSingleton(c => new MongoEventConsumerInfoRepository(mongoDatabase)) |
||||
|
.As<IEventConsumerInfoRepository>() |
||||
|
.As<IExternalSystem>(); |
||||
|
|
||||
|
services.AddSingleton(c => new MongoContentRepository(mongoContentDatabase, c.GetService<ISchemaProvider>())) |
||||
|
.As<IContentRepository>() |
||||
|
.As<IEventConsumer>(); |
||||
|
|
||||
|
services.AddSingleton(c => new MongoRuleEventRepository(mongoDatabase)) |
||||
|
.As<IRuleEventRepository>() |
||||
|
.As<IExternalSystem>(); |
||||
|
|
||||
|
services.AddSingleton(c => new MongoHistoryEventRepository(mongoDatabase, c.GetServices<IHistoryEventsCreator>())) |
||||
|
.As<IHistoryEventRepository>() |
||||
|
.As<IEventConsumer>() |
||||
|
.As<IExternalSystem>(); |
||||
|
|
||||
|
services.AddSingleton(c => new MongoAppRepository(mongoDatabase)) |
||||
|
.As<IAppRepository>() |
||||
|
.As<IAppEventConsumer>() |
||||
|
.As<IExternalSystem>(); |
||||
|
|
||||
|
services.AddSingleton(c => new MongoSchemaRepository(mongoDatabase, c.GetRequiredService<FieldRegistry>())) |
||||
|
.As<ISchemaRepository>() |
||||
|
.As<ISchemaEventConsumer>() |
||||
|
.As<IExternalSystem>(); |
||||
|
|
||||
|
services.AddSingleton(c => new MongoAssetStatsRepository(mongoDatabase)) |
||||
|
.As<IAssetStatsRepository>() |
||||
|
.As<IAssetEventConsumer>() |
||||
|
.As<IExternalSystem>(); |
||||
|
|
||||
|
services.AddSingleton(c => new MongoAssetRepository(mongoDatabase)) |
||||
|
.As<IAssetRepository>() |
||||
|
.As<IAssetEventConsumer>() |
||||
|
.As<IExternalSystem>(); |
||||
|
|
||||
|
services.AddSingleton(c => new MongoAssetRepository(mongoDatabase)) |
||||
|
.As<IRuleRepository>() |
||||
|
.As<IEventConsumer>() |
||||
|
.As<IExternalSystem>(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
// ==========================================================================
|
||||
|
// SystemExtensions.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Collections.Generic; |
||||
|
using Microsoft.AspNetCore.Builder; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Squidex.Infrastructure; |
||||
|
|
||||
|
namespace Squidex.Config.Domain |
||||
|
{ |
||||
|
public static class SystemExtensions |
||||
|
{ |
||||
|
public static IApplicationBuilder TestExternalSystems(this IApplicationBuilder app) |
||||
|
{ |
||||
|
var systems = app.ApplicationServices.GetRequiredService<IEnumerable<IExternalSystem>>(); |
||||
|
|
||||
|
foreach (var system in systems) |
||||
|
{ |
||||
|
system.Connect(); |
||||
|
} |
||||
|
|
||||
|
return app; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,113 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// WriteModule.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Autofac; |
|
||||
using Microsoft.Extensions.Configuration; |
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Domain.Apps.Core.Scripting; |
|
||||
using Squidex.Domain.Apps.Write.Apps; |
|
||||
using Squidex.Domain.Apps.Write.Assets; |
|
||||
using Squidex.Domain.Apps.Write.Contents; |
|
||||
using Squidex.Domain.Apps.Write.Rules; |
|
||||
using Squidex.Domain.Apps.Write.Schemas; |
|
||||
using Squidex.Domain.Users; |
|
||||
using Squidex.Infrastructure.CQRS.Commands; |
|
||||
using Squidex.Pipeline.CommandMiddlewares; |
|
||||
|
|
||||
namespace Squidex.Config.Domain |
|
||||
{ |
|
||||
public class WriteModule : Module |
|
||||
{ |
|
||||
private IConfiguration Configuration { get; } |
|
||||
|
|
||||
public WriteModule(IConfiguration configuration) |
|
||||
{ |
|
||||
Configuration = configuration; |
|
||||
} |
|
||||
|
|
||||
protected override void Load(ContainerBuilder builder) |
|
||||
{ |
|
||||
builder.RegisterType<NoopUserEvents>() |
|
||||
.As<IUserEvents>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<JintScriptEngine>() |
|
||||
.As<IScriptEngine>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<ContentVersionLoader>() |
|
||||
.As<IContentVersionLoader>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<ETagCommandMiddleware>() |
|
||||
.As<ICommandMiddleware>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<EnrichWithTimestampCommandMiddleware>() |
|
||||
.As<ICommandMiddleware>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<EnrichWithActorCommandMiddleware>() |
|
||||
.As<ICommandMiddleware>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<EnrichWithAppIdCommandMiddleware>() |
|
||||
.As<ICommandMiddleware>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<EnrichWithSchemaIdCommandMiddleware>() |
|
||||
.As<ICommandMiddleware>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<AppCommandMiddleware>() |
|
||||
.As<ICommandMiddleware>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<AssetCommandMiddleware>() |
|
||||
.As<ICommandMiddleware>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<ContentCommandMiddleware>() |
|
||||
.As<ICommandMiddleware>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<SchemaCommandMiddleware>() |
|
||||
.As<ICommandMiddleware>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<RuleCommandMiddleware>() |
|
||||
.As<ICommandMiddleware>() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.Register<DomainObjectFactoryFunction<AppDomainObject>>(c => (id => new AppDomainObject(id, -1))) |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.Register<DomainObjectFactoryFunction<AssetDomainObject>>(c => (id => new AssetDomainObject(id, -1))) |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.Register<DomainObjectFactoryFunction<ContentDomainObject>>(c => (id => new ContentDomainObject(id, -1))) |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.Register<DomainObjectFactoryFunction<RuleDomainObject>>(c => (id => new RuleDomainObject(id, -1))) |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.Register<DomainObjectFactoryFunction<SchemaDomainObject>>(c => |
|
||||
{ |
|
||||
var fieldRegistry = c.Resolve<FieldRegistry>(); |
|
||||
|
|
||||
return id => new SchemaDomainObject(id, -1, fieldRegistry); |
|
||||
}) |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,79 @@ |
|||||
|
// ==========================================================================
|
||||
|
// WriteServices.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Squidex.Domain.Apps.Core.Schemas; |
||||
|
using Squidex.Domain.Apps.Core.Scripting; |
||||
|
using Squidex.Domain.Apps.Write.Apps; |
||||
|
using Squidex.Domain.Apps.Write.Assets; |
||||
|
using Squidex.Domain.Apps.Write.Contents; |
||||
|
using Squidex.Domain.Apps.Write.Rules; |
||||
|
using Squidex.Domain.Apps.Write.Schemas; |
||||
|
using Squidex.Domain.Users; |
||||
|
using Squidex.Infrastructure.CQRS.Commands; |
||||
|
using Squidex.Pipeline.CommandMiddlewares; |
||||
|
|
||||
|
namespace Squidex.Config.Domain |
||||
|
{ |
||||
|
public static class WriteServices |
||||
|
{ |
||||
|
public static void AddMyWriteServices(this IServiceCollection services) |
||||
|
{ |
||||
|
services.AddSingleton<NoopUserEvents>() |
||||
|
.As<IUserEvents>(); |
||||
|
|
||||
|
services.AddSingleton<JintScriptEngine>() |
||||
|
.As<IScriptEngine>(); |
||||
|
|
||||
|
services.AddSingleton<ContentVersionLoader>() |
||||
|
.As<IContentVersionLoader>(); |
||||
|
|
||||
|
services.AddSingleton<ETagCommandMiddleware>() |
||||
|
.As<ICommandMiddleware>(); |
||||
|
|
||||
|
services.AddSingleton<EnrichWithTimestampCommandMiddleware>() |
||||
|
.As<ICommandMiddleware>(); |
||||
|
|
||||
|
services.AddSingleton<EnrichWithActorCommandMiddleware>() |
||||
|
.As<ICommandMiddleware>(); |
||||
|
|
||||
|
services.AddSingleton<EnrichWithAppIdCommandMiddleware>() |
||||
|
.As<ICommandMiddleware>(); |
||||
|
|
||||
|
services.AddSingleton<EnrichWithSchemaIdCommandMiddleware>() |
||||
|
.As<ICommandMiddleware>(); |
||||
|
|
||||
|
services.AddSingleton<AppCommandMiddleware>() |
||||
|
.As<ICommandMiddleware>(); |
||||
|
|
||||
|
services.AddSingleton<AssetCommandMiddleware>() |
||||
|
.As<ICommandMiddleware>(); |
||||
|
|
||||
|
services.AddSingleton<ContentCommandMiddleware>() |
||||
|
.As<ICommandMiddleware>(); |
||||
|
|
||||
|
services.AddSingleton<SchemaCommandMiddleware>() |
||||
|
.As<ICommandMiddleware>(); |
||||
|
|
||||
|
services.AddSingleton<RuleCommandMiddleware>() |
||||
|
.As<ICommandMiddleware>(); |
||||
|
|
||||
|
services.AddSingleton<DomainObjectFactoryFunction<AppDomainObject>>(c => (id => new AppDomainObject(id, -1))); |
||||
|
services.AddSingleton<DomainObjectFactoryFunction<RuleDomainObject>>(c => (id => new RuleDomainObject(id, -1))); |
||||
|
services.AddSingleton<DomainObjectFactoryFunction<AssetDomainObject>>(c => (id => new AssetDomainObject(id, -1))); |
||||
|
services.AddSingleton<DomainObjectFactoryFunction<ContentDomainObject>>(c => (id => new ContentDomainObject(id, -1))); |
||||
|
|
||||
|
services.AddSingleton<DomainObjectFactoryFunction<SchemaDomainObject>>(c => |
||||
|
{ |
||||
|
var fieldRegistry = c.GetRequiredService<FieldRegistry>(); |
||||
|
|
||||
|
return id => new SchemaDomainObject(id, -1, fieldRegistry); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,103 @@ |
|||||
|
// ==========================================================================
|
||||
|
// IdentityServerServices.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Collections.Generic; |
||||
|
using System.Reflection; |
||||
|
using System.Security.Cryptography.X509Certificates; |
||||
|
using IdentityModel; |
||||
|
using IdentityServer4.Models; |
||||
|
using IdentityServer4.Stores; |
||||
|
using Microsoft.AspNetCore.Identity; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Squidex.Domain.Users; |
||||
|
using Squidex.Shared.Identity; |
||||
|
using Squidex.Shared.Users; |
||||
|
|
||||
|
namespace Squidex.Config.Identity |
||||
|
{ |
||||
|
public static class IdentityServerServices |
||||
|
{ |
||||
|
public static IServiceCollection AddMyIdentityServer(this IServiceCollection services) |
||||
|
{ |
||||
|
X509Certificate2 certificate; |
||||
|
|
||||
|
var assembly = typeof(IdentityServices).GetTypeInfo().Assembly; |
||||
|
|
||||
|
using (var certStream = assembly.GetManifestResourceStream("Squidex.Config.Identity.Cert.IdentityCert.pfx")) |
||||
|
{ |
||||
|
var certData = new byte[certStream.Length]; |
||||
|
|
||||
|
certStream.Read(certData, 0, certData.Length); |
||||
|
certificate = new X509Certificate2(certData, "password", |
||||
|
X509KeyStorageFlags.MachineKeySet | |
||||
|
X509KeyStorageFlags.PersistKeySet | |
||||
|
X509KeyStorageFlags.Exportable); |
||||
|
} |
||||
|
|
||||
|
services.AddSingleton( |
||||
|
GetApiResources()); |
||||
|
services.AddSingleton( |
||||
|
GetIdentityResources()); |
||||
|
services.AddSingleton<IUserClaimsPrincipalFactory<IUser>, |
||||
|
UserClaimsPrincipalFactoryWithEmail>(); |
||||
|
services.AddSingleton<IClientStore, |
||||
|
LazyClientStore>(); |
||||
|
services.AddSingleton<IResourceStore, |
||||
|
InMemoryResourcesStore>(); |
||||
|
|
||||
|
services.AddIdentityServer(options => |
||||
|
{ |
||||
|
options.UserInteraction.ErrorUrl = "/error/"; |
||||
|
}) |
||||
|
.AddAspNetIdentity<IUser>() |
||||
|
.AddInMemoryApiResources(GetApiResources()) |
||||
|
.AddInMemoryIdentityResources(GetIdentityResources()) |
||||
|
.AddSigningCredential(certificate); |
||||
|
|
||||
|
return services; |
||||
|
} |
||||
|
|
||||
|
public static IServiceCollection AddMyIdentity(this IServiceCollection services) |
||||
|
{ |
||||
|
services.AddIdentity<IUser, IRole>() |
||||
|
.AddDefaultTokenProviders(); |
||||
|
|
||||
|
return services; |
||||
|
} |
||||
|
|
||||
|
private static IEnumerable<ApiResource> GetApiResources() |
||||
|
{ |
||||
|
yield return new ApiResource(Constants.ApiScope) |
||||
|
{ |
||||
|
UserClaims = new List<string> |
||||
|
{ |
||||
|
JwtClaimTypes.Email, |
||||
|
JwtClaimTypes.Role |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
private static IEnumerable<IdentityResource> GetIdentityResources() |
||||
|
{ |
||||
|
yield return new IdentityResources.OpenId(); |
||||
|
yield return new IdentityResources.Profile(); |
||||
|
yield return new IdentityResources.Email(); |
||||
|
yield return new IdentityResource(Constants.RoleScope, |
||||
|
new[] |
||||
|
{ |
||||
|
JwtClaimTypes.Role |
||||
|
}); |
||||
|
yield return new IdentityResource(Constants.ProfileScope, |
||||
|
new[] |
||||
|
{ |
||||
|
SquidexClaimTypes.SquidexDisplayName, |
||||
|
SquidexClaimTypes.SquidexPictureUrl |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Options.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Squidex.Config |
||||
|
{ |
||||
|
public sealed class Options : Dictionary<string, Action> |
||||
|
{ |
||||
|
public Options() |
||||
|
: base(StringComparer.OrdinalIgnoreCase) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,94 @@ |
|||||
|
// ==========================================================================
|
||||
|
// ServiceExtensions.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Linq; |
||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Squidex.Infrastructure; |
||||
|
|
||||
|
namespace Squidex.Config |
||||
|
{ |
||||
|
public static class ServiceExtensions |
||||
|
{ |
||||
|
public sealed class InterfaceRegistrator<T> |
||||
|
{ |
||||
|
private readonly IServiceCollection services; |
||||
|
|
||||
|
public InterfaceRegistrator(IServiceCollection services) |
||||
|
{ |
||||
|
this.services = services; |
||||
|
} |
||||
|
|
||||
|
public InterfaceRegistrator<T> As<TInterface>() |
||||
|
{ |
||||
|
this.services.AddSingleton(typeof(TInterface), c => c.GetRequiredService<T>()); |
||||
|
|
||||
|
return this; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static InterfaceRegistrator<T> AddSingleton<T>(this IServiceCollection services, Func<IServiceProvider, T> factory) |
||||
|
{ |
||||
|
services.AddSingleton(typeof(T), factory); |
||||
|
|
||||
|
return new InterfaceRegistrator<T>(services); |
||||
|
} |
||||
|
|
||||
|
public static InterfaceRegistrator<T> AddSingleton<T>(this IServiceCollection services, T instance) |
||||
|
{ |
||||
|
services.AddSingleton(instance); |
||||
|
|
||||
|
return new InterfaceRegistrator<T>(services); |
||||
|
} |
||||
|
|
||||
|
public static InterfaceRegistrator<T> AddSingleton<T>(this IServiceCollection services) |
||||
|
{ |
||||
|
services.AddSingleton(typeof(T)); |
||||
|
|
||||
|
return new InterfaceRegistrator<T>(services); |
||||
|
} |
||||
|
|
||||
|
public static T GetOptionalValue<T>(this IConfiguration config, string path, T defaultValue = default(T)) |
||||
|
{ |
||||
|
var value = config.GetValue<T>(path, defaultValue); |
||||
|
|
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
public static string GetRequiredValue(this IConfiguration config, string path) |
||||
|
{ |
||||
|
var value = config.GetValue<string>(path); |
||||
|
|
||||
|
if (string.IsNullOrWhiteSpace(value)) |
||||
|
{ |
||||
|
var name = string.Join(' ', path.Split(':').Select(x => x.ToPascalCase())); |
||||
|
|
||||
|
throw new ConfigurationException($"Configure the {name} with '{path}'."); |
||||
|
} |
||||
|
|
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
public static string ConfigureByOption(this IConfiguration config, string path, Options options) |
||||
|
{ |
||||
|
var value = config.GetRequiredValue(path); |
||||
|
|
||||
|
if (options.TryGetValue(value, out var action)) |
||||
|
{ |
||||
|
action(); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
throw new ConfigurationException($"Unsupported value '{value}' for '{path}', supported: {string.Join(' ', options.Keys)}."); |
||||
|
} |
||||
|
|
||||
|
return value; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,35 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// WebModule.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Autofac; |
|
||||
using Microsoft.Extensions.Configuration; |
|
||||
using Squidex.Pipeline; |
|
||||
|
|
||||
namespace Squidex.Config.Web |
|
||||
{ |
|
||||
public class WebModule : Module |
|
||||
{ |
|
||||
private IConfiguration Configuration { get; } |
|
||||
|
|
||||
public WebModule(IConfiguration configuration) |
|
||||
{ |
|
||||
Configuration = configuration; |
|
||||
} |
|
||||
|
|
||||
protected override void Load(ContainerBuilder builder) |
|
||||
{ |
|
||||
builder.RegisterType<AppApiFilter>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
|
|
||||
builder.RegisterType<FileCallbackResultExecutor>() |
|
||||
.AsSelf() |
|
||||
.SingleInstance(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
Loading…
Reference in new issue