Browse Source

First structures for rabbitmq event consumer

pull/65/head
Sebastian Stehle 9 years ago
parent
commit
c2ccec4d52
  1. 17
      Squidex.sln
  2. 95
      src/Squidex.Infrastructure.RabbitMq/RabbitMqEventConsumer.cs
  3. 10
      src/Squidex.Infrastructure.RabbitMq/RabbitMqOptions.cs
  4. 15
      src/Squidex.Infrastructure.RabbitMq/Squidex.Infrastructure.RabbitMq.csproj
  5. 4
      src/Squidex.Infrastructure/CQRS/Events/EventReceiver.cs
  6. 47
      src/Squidex/Config/Domain/RabbitMqModule.cs
  7. 3
      src/Squidex/Squidex.csproj
  8. 1
      src/Squidex/Startup.cs
  9. 8
      src/Squidex/appsettings.json

17
Squidex.sln

@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
VisualStudioVersion = 15.0.26228.12
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Squidex", "src\Squidex\Squidex.csproj", "{61F6BBCE-A080-4400-B194-70E2F5D2096E}"
EndProject
@ -36,6 +36,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{1667F3B4
EndProject
Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "GenerateLanguages", "tools\GenerateLanguages\GenerateLanguages.csproj", "{927E1F1C-95F0-4991-B33F-603977204B02}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Squidex.Infrastructure.RabbitMq", "src\Squidex.Infrastructure.RabbitMq\Squidex.Infrastructure.RabbitMq.csproj", "{C1E5BBB6-6B6A-4DE5-B19D-0538304DE343}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -162,6 +164,18 @@ Global
{927E1F1C-95F0-4991-B33F-603977204B02}.Release|x64.Build.0 = Release|Any CPU
{927E1F1C-95F0-4991-B33F-603977204B02}.Release|x86.ActiveCfg = Release|Any CPU
{927E1F1C-95F0-4991-B33F-603977204B02}.Release|x86.Build.0 = Release|Any CPU
{C1E5BBB6-6B6A-4DE5-B19D-0538304DE343}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C1E5BBB6-6B6A-4DE5-B19D-0538304DE343}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C1E5BBB6-6B6A-4DE5-B19D-0538304DE343}.Debug|x64.ActiveCfg = Debug|Any CPU
{C1E5BBB6-6B6A-4DE5-B19D-0538304DE343}.Debug|x64.Build.0 = Debug|Any CPU
{C1E5BBB6-6B6A-4DE5-B19D-0538304DE343}.Debug|x86.ActiveCfg = Debug|Any CPU
{C1E5BBB6-6B6A-4DE5-B19D-0538304DE343}.Debug|x86.Build.0 = Debug|Any CPU
{C1E5BBB6-6B6A-4DE5-B19D-0538304DE343}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C1E5BBB6-6B6A-4DE5-B19D-0538304DE343}.Release|Any CPU.Build.0 = Release|Any CPU
{C1E5BBB6-6B6A-4DE5-B19D-0538304DE343}.Release|x64.ActiveCfg = Release|Any CPU
{C1E5BBB6-6B6A-4DE5-B19D-0538304DE343}.Release|x64.Build.0 = Release|Any CPU
{C1E5BBB6-6B6A-4DE5-B19D-0538304DE343}.Release|x86.ActiveCfg = Release|Any CPU
{C1E5BBB6-6B6A-4DE5-B19D-0538304DE343}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -180,5 +194,6 @@ Global
{8B074219-F69A-4E41-83C6-12EE1E647779} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{D7166C56-178A-4457-B56A-C615C7450DEE} = {8CF53B92-5EB1-461D-98F8-70DA9B603FBF}
{927E1F1C-95F0-4991-B33F-603977204B02} = {1667F3B4-31E6-45B2-90FB-97B1ECFE9874}
{C1E5BBB6-6B6A-4DE5-B19D-0538304DE343} = {8CF53B92-5EB1-461D-98F8-70DA9B603FBF}
EndGlobalSection
EndGlobal

95
src/Squidex.Infrastructure.RabbitMq/RabbitMqEventConsumer.cs

@ -0,0 +1,95 @@
// ==========================================================================
// RabbitMqEventConsumer.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using RabbitMQ.Client;
using Squidex.Infrastructure.CQRS.Events;
using Squidex.Infrastructure.Tasks;
// ReSharper disable InvertIf
namespace Squidex.Infrastructure.RabbitMq
{
public sealed class RabbitMqEventConsumer : DisposableObjectBase, IExternalSystem, IEventConsumer
{
private readonly string exchange;
private readonly string streamFilter;
private readonly ConnectionFactory connectionFactory;
private readonly Lazy<IConnection> connection;
private readonly Lazy<IModel> channel;
public string Name
{
get { return GetType().Name; }
}
public string StreamFilter
{
get { return streamFilter; }
}
public RabbitMqEventConsumer(string uri, string exchange, string streamFilter)
{
Guard.NotNullOrEmpty(uri, nameof(uri));
Guard.NotNullOrEmpty(exchange, nameof(exchange));
connectionFactory = new ConnectionFactory { Uri = uri };
connection = new Lazy<IConnection>(connectionFactory.CreateConnection);
channel = new Lazy<IModel>(() => connection.Value.CreateModel());
this.exchange = exchange;
this.streamFilter = streamFilter;
}
protected override void DisposeObject(bool disposing)
{
if (connection.IsValueCreated)
{
connection.Value.Close();
connection.Value.Dispose();
}
}
public void Connect()
{
try
{
var currentConnection = connection.Value;
if (!currentConnection.IsOpen)
{
throw new ConfigurationException($"RabbitMq event bus failed to connect to {connectionFactory.Endpoint}");
}
}
catch (Exception e)
{
throw new ConfigurationException($"RabbitMq event bus failed to connect to {connectionFactory.Endpoint}", e);
}
}
public Task ClearAsync()
{
return TaskHelper.Done;
}
public Task On(Envelope<IEvent> @event)
{
var jsonString = JsonConvert.SerializeObject(@event);
var jsonBytes = Encoding.UTF8.GetBytes(jsonString);
channel.Value.BasicPublish(exchange, string.Empty, null, jsonBytes);
return TaskHelper.Done;
}
}
}

10
src/Squidex.Infrastructure.RabbitMq/RabbitMqOptions.cs

@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Squidex.Infrastructure.RabbitMq
{
class RabbitMqOptions
{
}
}

15
src/Squidex.Infrastructure.RabbitMq/Squidex.Infrastructure.RabbitMq.csproj

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>full</DebugType>
<DebugSymbols>True</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="RabbitMQ.Client" Version="4.1.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\src\Squidex.Infrastructure\Squidex.Infrastructure.csproj" />
</ItemGroup>
</Project>

4
src/Squidex.Infrastructure/CQRS/Events/EventReceiver.cs

@ -66,6 +66,8 @@ namespace Squidex.Infrastructure.CQRS.Events
public void Next()
{
ThrowIfDisposed();
timer?.Trigger();
}
@ -73,6 +75,8 @@ namespace Squidex.Infrastructure.CQRS.Events
{
Guard.NotNull(eventConsumer, nameof(eventConsumer));
ThrowIfDisposed();
if (timer != null)
{
return;

47
src/Squidex/Config/Domain/RabbitMqModule.cs

@ -0,0 +1,47 @@
// ==========================================================================
// RabbitMqModule.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using Autofac;
using Microsoft.Extensions.Configuration;
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(connectionString, exchange, streamFilter))
.As<IEventConsumer>()
.As<IExternalSystem>()
.SingleInstance();
}
}
}
}

3
src/Squidex/Squidex.csproj

@ -15,7 +15,7 @@
<ItemGroup>
<EmbeddedResource Include="Config\Identity\Cert\*.*;Docs\*.md" />
<None Update="dockerfile">
<None Update="dockerfile">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</None>
</ItemGroup>
@ -25,6 +25,7 @@
<ProjectReference Include="..\Squidex.Events\Squidex.Events.csproj" />
<ProjectReference Include="..\Squidex.Infrastructure\Squidex.Infrastructure.csproj" />
<ProjectReference Include="..\Squidex.Infrastructure.MongoDb\Squidex.Infrastructure.MongoDb.csproj" />
<ProjectReference Include="..\Squidex.Infrastructure.RabbitMq\Squidex.Infrastructure.RabbitMq.csproj" />
<ProjectReference Include="..\Squidex.Infrastructure.Redis\Squidex.Infrastructure.Redis.csproj" />
<ProjectReference Include="..\Squidex.Read\Squidex.Read.csproj" />
<ProjectReference Include="..\Squidex.Read.MongoDb\Squidex.Read.MongoDb.csproj" />

1
src/Squidex/Startup.cs

@ -80,6 +80,7 @@ namespace Squidex
builder.RegisterModule(new ClusterModule(Configuration));
builder.RegisterModule(new EventStoreModule(Configuration));
builder.RegisterModule(new InfrastructureModule(Configuration));
builder.RegisterModule(new RabbitMqModule(Configuration));
builder.RegisterModule(new ReadModule(Configuration));
builder.RegisterModule(new StoreModule(Configuration));
builder.RegisterModule(new WebModule(Configuration));

8
src/Squidex/appsettings.json

@ -19,6 +19,14 @@
"databaseName": "Squidex"
}
},
"eventPublishers": {
"rabbitMq": {
"connectionString": "amqp://guest:guest@localhost/",
"exchange": "Squidex",
"enabled": false,
"streamFilter": "*"
}
},
"stores": {
"type": "mongoDb",
"mongoDb": {

Loading…
Cancel
Save