diff --git a/.dockerignore b/.dockerignore
index 19ec84e3b..9b8b49c2a 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -19,4 +19,6 @@
**/node_modules/
# Scripts (should be copied from node_modules on build)
-**/wwwroot/scripts/**/*.*
\ No newline at end of file
+**/wwwroot/scripts/**/*.*
+
+**/src/Squidex/appsettings.Development.json
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 549a8b85d..4c398ec98 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,4 +17,6 @@ _test-output/
node_modules/
# Scripts (should be copied from node_modules on build)
-**/wwwroot/scripts/**/*.*
\ No newline at end of file
+**/wwwroot/scripts/**/*.*
+
+/src/Squidex/appsettings.Development.json
diff --git a/Dockerfile.build b/Dockerfile.build
index d9057ded8..ffe02d925 100644
--- a/Dockerfile.build
+++ b/Dockerfile.build
@@ -37,7 +37,7 @@ WORKDIR /
# Build Frontend
RUN cp -a /tmp/node_modules /src/Squidex/ \
&& cd /src/Squidex \
- %% npm run test:coverage \
+ && npm run test:coverage \
&& npm run build:copy \
&& npm run build
diff --git a/README.md b/README.md
index 450143783..657ab3391 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
# What is Squidex?
-Squidex is an open source headless CMS and content management hub. In contrast to antraditional CMS Squidex provides a rich API with OData filter and Swagger definitions. It is up to you to build your UI on top of it. It can be website, a native app or just another server.
+Squidex is an open source headless CMS and content management hub. In contrast to a traditional CMS Squidex provides a rich API with OData filter and Swagger definitions. It is up to you to build your UI on top of it. It can be website, a native app or just another server.
We built it on top of ASP.NET Core and CQRS and is tested for Windows and Linux on modern Browsers.
[](https://gitter.im/squidex-cms/Lobby)
diff --git a/Squidex.sln b/Squidex.sln
index 7c456fe9f..606cec592 100644
--- a/Squidex.sln
+++ b/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
@@ -32,9 +32,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Squidex.Read.Tests", "tests
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Squidex.Infrastructure.Redis", "src\Squidex.Infrastructure.Redis\Squidex.Infrastructure.Redis.csproj", "{D7166C56-178A-4457-B56A-C615C7450DEE}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{1667F3B4-31E6-45B2-90FB-97B1ECFE9874}"
-EndProject
-Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "GenerateLanguages", "tools\GenerateLanguages\GenerateLanguages.csproj", "{927E1F1C-95F0-4991-B33F-603977204B02}"
+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
@@ -150,18 +148,18 @@ Global
{D7166C56-178A-4457-B56A-C615C7450DEE}.Release|Any CPU.Build.0 = Release|Any CPU
{D7166C56-178A-4457-B56A-C615C7450DEE}.Release|x64.ActiveCfg = Release|Any CPU
{D7166C56-178A-4457-B56A-C615C7450DEE}.Release|x86.ActiveCfg = Release|Any CPU
- {927E1F1C-95F0-4991-B33F-603977204B02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {927E1F1C-95F0-4991-B33F-603977204B02}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {927E1F1C-95F0-4991-B33F-603977204B02}.Debug|x64.ActiveCfg = Debug|Any CPU
- {927E1F1C-95F0-4991-B33F-603977204B02}.Debug|x64.Build.0 = Debug|Any CPU
- {927E1F1C-95F0-4991-B33F-603977204B02}.Debug|x86.ActiveCfg = Debug|Any CPU
- {927E1F1C-95F0-4991-B33F-603977204B02}.Debug|x86.Build.0 = Debug|Any CPU
- {927E1F1C-95F0-4991-B33F-603977204B02}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {927E1F1C-95F0-4991-B33F-603977204B02}.Release|Any CPU.Build.0 = Release|Any CPU
- {927E1F1C-95F0-4991-B33F-603977204B02}.Release|x64.ActiveCfg = Release|Any CPU
- {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
@@ -179,6 +177,6 @@ Global
{6A811927-3C37-430A-90F4-503E37123956} = {8CF53B92-5EB1-461D-98F8-70DA9B603FBF}
{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
diff --git a/src/Squidex.Core/Squidex.Core.csproj b/src/Squidex.Core/Squidex.Core.csproj
index 05847ae26..d5cb482ce 100644
--- a/src/Squidex.Core/Squidex.Core.csproj
+++ b/src/Squidex.Core/Squidex.Core.csproj
@@ -13,8 +13,8 @@
-
-
+
+
diff --git a/src/Squidex.Events/Squidex.Events.csproj b/src/Squidex.Events/Squidex.Events.csproj
index c5dd52a47..fad168319 100644
--- a/src/Squidex.Events/Squidex.Events.csproj
+++ b/src/Squidex.Events/Squidex.Events.csproj
@@ -12,6 +12,6 @@
-
+
diff --git a/src/Squidex.Infrastructure.MongoDb/EventStore/MongoEventStore.cs b/src/Squidex.Infrastructure.MongoDb/EventStore/MongoEventStore.cs
index b7d3ff079..7e6dac229 100644
--- a/src/Squidex.Infrastructure.MongoDb/EventStore/MongoEventStore.cs
+++ b/src/Squidex.Infrastructure.MongoDb/EventStore/MongoEventStore.cs
@@ -10,6 +10,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
+using System.Threading;
using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Driver;
@@ -17,6 +18,7 @@ using NodaTime;
using Squidex.Infrastructure.CQRS.Events;
using Squidex.Infrastructure.Reflection;
+// ReSharper disable ConvertIfStatementToConditionalTernaryExpression
// ReSharper disable ClassNeverInstantiated.Local
// ReSharper disable UnusedMember.Local
// ReSharper disable InvertIf
@@ -55,61 +57,82 @@ namespace Squidex.Infrastructure.MongoDb.EventStore
{
var indexNames =
await Task.WhenAll(
+ collection.Indexes.CreateOneAsync(IndexKeys.Ascending(x => x.EventsOffset), new CreateIndexOptions { Unique = true }),
+ collection.Indexes.CreateOneAsync(IndexKeys.Ascending(x => x.EventStreamOffset).Ascending(x => x.EventStream), new CreateIndexOptions { Unique = true }),
collection.Indexes.CreateOneAsync(IndexKeys.Descending(x => x.EventsOffset), new CreateIndexOptions { Unique = true }),
collection.Indexes.CreateOneAsync(IndexKeys.Descending(x => x.EventStreamOffset).Ascending(x => x.EventStream), new CreateIndexOptions { Unique = true }));
eventsOffsetIndex = indexNames[0];
}
- public IObservable GetEventsAsync(string streamName)
+ public IObservable GetEventsAsync(string streamFilter, long lastReceivedEventNumber = -1)
{
- Guard.NotNullOrEmpty(streamName, nameof(streamName));
-
- return Observable.Create(async (observer, ct) =>
+ return Observable.Create((observer, ct) =>
{
- await Collection.Find(x => x.EventStream == streamName).ForEachAsync(commit =>
+ return GetEventsAsync(storedEvent =>
{
- var eventNumber = commit.EventsOffset;
- var eventStreamNumber = commit.EventStreamOffset;
-
- foreach (var @event in commit.Events)
- {
- eventNumber++;
- eventStreamNumber++;
+ observer.OnNext(storedEvent);
- var eventData = SimpleMapper.Map(@event, new EventData());
-
- observer.OnNext(new StoredEvent(eventNumber, eventStreamNumber, eventData));
- }
- }, ct);
+ return Tasks.TaskHelper.Done;
+ }, ct, streamFilter, lastReceivedEventNumber);
});
}
- public IObservable GetEventsAsync(long lastReceivedEventNumber = -1)
+ public async Task GetEventsAsync(Func callback, CancellationToken cancellationToken, string streamFilter = null, long lastReceivedEventNumber = -1)
{
- return Observable.Create(async (observer, ct) =>
+ Guard.NotNull(callback, nameof(callback));
+
+ var filters = new List>();
+
+ if (lastReceivedEventNumber >= 0)
{
- var commitOffset = await GetPreviousOffset(lastReceivedEventNumber);
+ var commitOffset = await GetPreviousOffsetAsync(lastReceivedEventNumber);
+
+ filters.Add(Filter.Gte(x => x.EventsOffset, commitOffset));
+ }
- await Collection.Find(x => x.EventsOffset >= commitOffset).SortBy(x => x.EventsOffset).ForEachAsync(commit =>
+ if (!string.IsNullOrWhiteSpace(streamFilter) && !string.Equals(streamFilter, "*", StringComparison.OrdinalIgnoreCase))
+ {
+ if (streamFilter.StartsWith("^"))
+ {
+ filters.Add(Filter.Regex(x => x.EventStream, streamFilter));
+ }
+ else
{
- var eventNumber = commit.EventsOffset;
- var eventStreamNumber = commit.EventStreamOffset;
+ filters.Add(Filter.Eq(x => x.EventStream, streamFilter));
+ }
+ }
- foreach (var @event in commit.Events)
- {
- eventNumber++;
- eventStreamNumber++;
+ FilterDefinition filter = new BsonDocument();
- if (eventNumber > lastReceivedEventNumber)
- {
- var eventData = SimpleMapper.Map(@event, new EventData());
+ if (filters.Count > 1)
+ {
+ filter = Filter.And(filters);
+ }
+ else if (filters.Count == 1)
+ {
+ filter = filters[0];
+ }
- observer.OnNext(new StoredEvent(eventNumber, eventStreamNumber, eventData));
- }
+ await Collection.Find(filter).SortBy(x => x.EventsOffset).ForEachAsync(async commit =>
+ {
+ var eventNumber = commit.EventsOffset;
+ var eventStreamNumber = commit.EventStreamOffset;
+
+ foreach (var mongoEvent in commit.Events)
+ {
+ eventNumber++;
+ eventStreamNumber++;
+
+ if (eventNumber > lastReceivedEventNumber)
+ {
+ var eventData = SimpleMapper.Map(mongoEvent, new EventData());
+
+ await callback(new StoredEvent(eventNumber, eventStreamNumber, eventData));
}
- }, ct);
- });
+
+ }
+ }, cancellationToken);
}
public async Task AppendEventsAsync(Guid commitId, string streamName, int expectedVersion, IEnumerable events)
@@ -130,7 +153,7 @@ namespace Squidex.Infrastructure.MongoDb.EventStore
if (commitEvents.Any())
{
- var offset = await GetEventOffset();
+ var offset = await GetEventOffsetAsync();
var commit = new MongoEventCommit
{
@@ -157,7 +180,7 @@ namespace Squidex.Infrastructure.MongoDb.EventStore
{
if (ex.Message.IndexOf(eventsOffsetIndex, StringComparison.OrdinalIgnoreCase) >= 0)
{
- commit.EventsOffset = await GetEventOffset();
+ commit.EventsOffset = await GetEventOffsetAsync();
}
else if (ex.WriteError?.Category == ServerErrorCategory.DuplicateKey)
{
@@ -174,25 +197,24 @@ namespace Squidex.Infrastructure.MongoDb.EventStore
}
}
- private async Task GetPreviousOffset(long startEventNumber)
+ private async Task GetPreviousOffsetAsync(long startEventNumber)
{
var document =
await Collection.Find(x => x.EventsOffset <= startEventNumber)
.Project(Projection
- .Include(x => x.EventStreamOffset)
- .Include(x => x.EventsCount))
+ .Include(x => x.EventsOffset))
.SortByDescending(x => x.EventsOffset).Limit(1)
.FirstOrDefaultAsync();
if (document != null)
{
- return document["EventStreamOffset"].ToInt64();
+ return document["EventsOffset"].ToInt64();
}
return -1;
}
- private async Task GetEventOffset()
+ private async Task GetEventOffsetAsync()
{
var document =
await Collection.Find(new BsonDocument())
diff --git a/src/Squidex.Infrastructure.RabbitMq/RabbitMqEventConsumer.cs b/src/Squidex.Infrastructure.RabbitMq/RabbitMqEventConsumer.cs
new file mode 100644
index 000000000..b1b0c047b
--- /dev/null
+++ b/src/Squidex.Infrastructure.RabbitMq/RabbitMqEventConsumer.cs
@@ -0,0 +1,100 @@
+// ==========================================================================
+// 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 JsonSerializerSettings serializerSettings;
+ private readonly string eventPublisherName;
+ private readonly string exchange;
+ private readonly string eventsFilter;
+ private readonly ConnectionFactory connectionFactory;
+ private readonly Lazy connection;
+ private readonly Lazy channel;
+
+ public string Name
+ {
+ get { return eventPublisherName; }
+ }
+
+ public string EventsFilter
+ {
+ get { return eventsFilter; }
+ }
+
+ public RabbitMqEventConsumer(JsonSerializerSettings serializerSettings, string eventPublisherName, string uri, string exchange, string eventsFilter)
+ {
+ Guard.NotNullOrEmpty(uri, nameof(uri));
+ Guard.NotNullOrEmpty(eventPublisherName, nameof(eventPublisherName));
+ Guard.NotNullOrEmpty(exchange, nameof(exchange));
+ Guard.NotNull(serializerSettings, nameof(serializerSettings));
+
+ connectionFactory = new ConnectionFactory { Uri = uri };
+
+ connection = new Lazy(connectionFactory.CreateConnection);
+ channel = new Lazy(() => connection.Value.CreateModel());
+
+ this.exchange = exchange;
+ this.eventsFilter = eventsFilter;
+ this.eventPublisherName = eventPublisherName;
+ this.serializerSettings = serializerSettings;
+ }
+
+ 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 @event)
+ {
+ var jsonString = JsonConvert.SerializeObject(@event, serializerSettings);
+ var jsonBytes = Encoding.UTF8.GetBytes(jsonString);
+
+ channel.Value.BasicPublish(exchange, string.Empty, null, jsonBytes);
+
+ return TaskHelper.Done;
+ }
+ }
+}
diff --git a/src/Squidex.Infrastructure.RabbitMq/Squidex.Infrastructure.RabbitMq.csproj b/src/Squidex.Infrastructure.RabbitMq/Squidex.Infrastructure.RabbitMq.csproj
new file mode 100644
index 000000000..ab2f8af4c
--- /dev/null
+++ b/src/Squidex.Infrastructure.RabbitMq/Squidex.Infrastructure.RabbitMq.csproj
@@ -0,0 +1,15 @@
+
+
+ netstandard1.6
+
+
+ full
+ True
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Squidex.Infrastructure.Redis/RedisInfrastructureErrors.cs b/src/Squidex.Infrastructure.Redis/RedisInfrastructureErrors.cs
deleted file mode 100644
index 1fca8ec32..000000000
--- a/src/Squidex.Infrastructure.Redis/RedisInfrastructureErrors.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-// ==========================================================================
-// RedisInfrastructureErrors.cs
-// Squidex Headless CMS
-// ==========================================================================
-// Copyright (c) Squidex Group
-// All rights reserved.
-// ==========================================================================
-
-using Microsoft.Extensions.Logging;
-
-namespace Squidex.Infrastructure.Redis
-{
- public static class RedisInfrastructureErrors
- {
- public static readonly EventId InvalidatingReceivedFailed = new EventId(50001, "InvalidingReceivedFailed");
-
- public static readonly EventId InvalidatingPublishedFailed = new EventId(50002, "InvalidatingPublishedFailed");
- }
-}
diff --git a/src/Squidex.Infrastructure.Redis/RedisPubSub.cs b/src/Squidex.Infrastructure.Redis/RedisPubSub.cs
index dcf893bb8..de71cb843 100644
--- a/src/Squidex.Infrastructure.Redis/RedisPubSub.cs
+++ b/src/Squidex.Infrastructure.Redis/RedisPubSub.cs
@@ -8,7 +8,7 @@
using System;
using System.Collections.Concurrent;
-using Microsoft.Extensions.Logging;
+using Squidex.Infrastructure.Log;
using StackExchange.Redis;
namespace Squidex.Infrastructure.Redis
@@ -16,31 +16,30 @@ namespace Squidex.Infrastructure.Redis
public class RedisPubSub : IPubSub, IExternalSystem
{
private readonly ConcurrentDictionary subscriptions = new ConcurrentDictionary();
- private readonly IConnectionMultiplexer redis;
- private readonly ILogger logger;
- private readonly ISubscriber subscriber;
+ private readonly IConnectionMultiplexer redisClient;
+ private readonly ISemanticLog log;
+ private readonly ISubscriber redisSubscriber;
- public RedisPubSub(IConnectionMultiplexer redis, ILogger logger)
+ public RedisPubSub(IConnectionMultiplexer redis, ISemanticLog log)
{
Guard.NotNull(redis, nameof(redis));
- Guard.NotNull(logger, nameof(logger));
+ Guard.NotNull(log, nameof(log));
- this.redis = redis;
+ this.log = log;
- this.logger = logger;
-
- subscriber = redis.GetSubscriber();
+ redisClient = redis;
+ redisSubscriber = redis.GetSubscriber();
}
public void Connect()
{
try
{
- redis.GetStatus();
+ redisClient.GetStatus();
}
catch (Exception ex)
{
- throw new ConfigurationException($"Redis connection failed to connect to database {redis.Configuration}", ex);
+ throw new ConfigurationException($"Redis connection failed to connect to database {redisClient.Configuration}", ex);
}
}
@@ -48,14 +47,14 @@ namespace Squidex.Infrastructure.Redis
{
Guard.NotNullOrEmpty(channelName, nameof(channelName));
- subscriptions.GetOrAdd(channelName, c => new RedisSubscription(subscriber, c, logger)).Publish(token, notifySelf);
+ subscriptions.GetOrAdd(channelName, c => new RedisSubscription(redisSubscriber, c, log)).Publish(token, notifySelf);
}
public IDisposable Subscribe(string channelName, Action handler)
{
Guard.NotNullOrEmpty(channelName, nameof(channelName));
- return subscriptions.GetOrAdd(channelName, c => new RedisSubscription(subscriber, c, logger)).Subscribe(handler);
+ return subscriptions.GetOrAdd(channelName, c => new RedisSubscription(redisSubscriber, c, log)).Subscribe(handler);
}
}
}
diff --git a/src/Squidex.Infrastructure.Redis/RedisSubscription.cs b/src/Squidex.Infrastructure.Redis/RedisSubscription.cs
index 045858ce4..a7b628dd8 100644
--- a/src/Squidex.Infrastructure.Redis/RedisSubscription.cs
+++ b/src/Squidex.Infrastructure.Redis/RedisSubscription.cs
@@ -9,7 +9,7 @@
using System;
using System.Linq;
using System.Reactive.Subjects;
-using Microsoft.Extensions.Logging;
+using Squidex.Infrastructure.Log;
using StackExchange.Redis;
// ReSharper disable InvertIf
@@ -22,11 +22,11 @@ namespace Squidex.Infrastructure.Redis
private readonly Subject subject = new Subject();
private readonly ISubscriber subscriber;
private readonly string channelName;
- private readonly ILogger logger;
+ private readonly ISemanticLog log;
- public RedisSubscription(ISubscriber subscriber, string channelName, ILogger logger)
+ public RedisSubscription(ISubscriber subscriber, string channelName, ISemanticLog log)
{
- this.logger = logger;
+ this.log = log;
this.subscriber = subscriber;
this.subscriber.Subscribe(channelName, (channel, value) => HandleInvalidation(value));
@@ -38,13 +38,16 @@ namespace Squidex.Infrastructure.Redis
{
try
{
- var message = string.Join("#", (notifySelf ? Guid.Empty : InstanceId).ToString());
+ var message = string.Join("#", (notifySelf ? Guid.Empty : InstanceId).ToString(), token);
subscriber.Publish(channelName, message);
}
catch (Exception ex)
{
- logger.LogError(RedisInfrastructureErrors.InvalidatingReceivedFailed, ex, "Failed to send invalidation message {0}", token);
+ log.LogError(ex, w => w
+ .WriteProperty("action", "PublishRedisMessage")
+ .WriteProperty("state", "Failed")
+ .WriteProperty("token", token));
}
}
@@ -78,7 +81,9 @@ namespace Squidex.Infrastructure.Redis
}
catch (Exception ex)
{
- logger.LogError(RedisInfrastructureErrors.InvalidatingReceivedFailed, ex, "Failed to receive invalidation message.");
+ log.LogError(ex, w => w
+ .WriteProperty("action", "ReceiveRedisMessage")
+ .WriteProperty("state", "Failed"));
}
}
diff --git a/src/Squidex.Infrastructure.Redis/Squidex.Infrastructure.Redis.csproj b/src/Squidex.Infrastructure.Redis/Squidex.Infrastructure.Redis.csproj
index 98a461896..5e5b44588 100644
--- a/src/Squidex.Infrastructure.Redis/Squidex.Infrastructure.Redis.csproj
+++ b/src/Squidex.Infrastructure.Redis/Squidex.Infrastructure.Redis.csproj
@@ -10,7 +10,6 @@
-
diff --git a/src/Squidex.Infrastructure/CQRS/Commands/CommandContext.cs b/src/Squidex.Infrastructure/CQRS/Commands/CommandContext.cs
index 31f76e399..113f85317 100644
--- a/src/Squidex.Infrastructure/CQRS/Commands/CommandContext.cs
+++ b/src/Squidex.Infrastructure/CQRS/Commands/CommandContext.cs
@@ -13,6 +13,7 @@ namespace Squidex.Infrastructure.CQRS.Commands
public sealed class CommandContext
{
private readonly ICommand command;
+ private readonly Guid contextId = Guid.NewGuid();
private Exception exception;
private Tuple