diff --git a/src/Squidex.Infrastructure/CQRS/Commands/AggregateCommand.cs b/src/Squidex.Events/AppEvent.cs similarity index 67% rename from src/Squidex.Infrastructure/CQRS/Commands/AggregateCommand.cs rename to src/Squidex.Events/AppEvent.cs index 253f6c3ea..f55037de4 100644 --- a/src/Squidex.Infrastructure/CQRS/Commands/AggregateCommand.cs +++ b/src/Squidex.Events/AppEvent.cs @@ -1,5 +1,5 @@ // ========================================================================== -// AggregateCommand.cs +// AppEvent.cs // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex Group @@ -7,11 +7,12 @@ // ========================================================================== using System; +using Squidex.Infrastructure; -namespace Squidex.Infrastructure.CQRS.Commands +namespace Squidex.Events { - public class AggregateCommand : IAggregateCommand + public abstract class AppEvent : SquidexEvent { - public Guid AggregateId { get; set; } + public NamedId AppId { get; set; } } } diff --git a/src/Squidex.Events/Apps/AppClientAttached.cs b/src/Squidex.Events/Apps/AppClientAttached.cs index a26510767..5d4e80362 100644 --- a/src/Squidex.Events/Apps/AppClientAttached.cs +++ b/src/Squidex.Events/Apps/AppClientAttached.cs @@ -8,12 +8,11 @@ using System; using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Events.Apps { [TypeName("AppClientAttachedEvent")] - public sealed class AppClientAttached : IEvent + public sealed class AppClientAttached : AppEvent { public string Id { get; set; } diff --git a/src/Squidex.Events/Apps/AppClientRenamed.cs b/src/Squidex.Events/Apps/AppClientRenamed.cs index 87ab285cb..8c89038f8 100644 --- a/src/Squidex.Events/Apps/AppClientRenamed.cs +++ b/src/Squidex.Events/Apps/AppClientRenamed.cs @@ -7,12 +7,11 @@ // ========================================================================== using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Events.Apps { [TypeName("AppClientRenamedEvent")] - public sealed class AppClientRenamed : IEvent + public sealed class AppClientRenamed : AppEvent { public string Id { get; set; } diff --git a/src/Squidex.Events/Apps/AppClientRevoked.cs b/src/Squidex.Events/Apps/AppClientRevoked.cs index 1ce890b80..45d267eb5 100644 --- a/src/Squidex.Events/Apps/AppClientRevoked.cs +++ b/src/Squidex.Events/Apps/AppClientRevoked.cs @@ -7,12 +7,11 @@ // ========================================================================== using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Events.Apps { [TypeName("AppClientRevokedEvent")] - public sealed class AppClientRevoked : IEvent + public sealed class AppClientRevoked : AppEvent { public string Id { get; set; } } diff --git a/src/Squidex.Events/Apps/AppContributorAssigned.cs b/src/Squidex.Events/Apps/AppContributorAssigned.cs index 07be384ad..12a57fac2 100644 --- a/src/Squidex.Events/Apps/AppContributorAssigned.cs +++ b/src/Squidex.Events/Apps/AppContributorAssigned.cs @@ -8,12 +8,11 @@ using Squidex.Core.Apps; using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Events.Apps { [TypeName("AppContributorAssignedEvent")] - public class AppContributorAssigned : IEvent + public class AppContributorAssigned : AppEvent { public string ContributorId { get; set; } diff --git a/src/Squidex.Events/Apps/AppContributorRemoved.cs b/src/Squidex.Events/Apps/AppContributorRemoved.cs index 5f42d9d50..bd46cca5b 100644 --- a/src/Squidex.Events/Apps/AppContributorRemoved.cs +++ b/src/Squidex.Events/Apps/AppContributorRemoved.cs @@ -7,12 +7,11 @@ // ========================================================================== using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Events.Apps { [TypeName("AppContributorRemovedEvent")] - public class AppContributorRemoved : IEvent + public class AppContributorRemoved : AppEvent { public string ContributorId { get; set; } } diff --git a/src/Squidex.Events/Apps/AppCreated.cs b/src/Squidex.Events/Apps/AppCreated.cs index c995f55f5..715f166ca 100644 --- a/src/Squidex.Events/Apps/AppCreated.cs +++ b/src/Squidex.Events/Apps/AppCreated.cs @@ -7,12 +7,11 @@ // ========================================================================== using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Events.Apps { [TypeName("AppCreatedEvent")] - public class AppCreated : IEvent + public class AppCreated : AppEvent { public string Name { get; set; } } diff --git a/src/Squidex.Events/Apps/AppLanguageAdded.cs b/src/Squidex.Events/Apps/AppLanguageAdded.cs index 12807bc64..edf35c90f 100644 --- a/src/Squidex.Events/Apps/AppLanguageAdded.cs +++ b/src/Squidex.Events/Apps/AppLanguageAdded.cs @@ -7,12 +7,11 @@ // ========================================================================== using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Events.Apps { [TypeName("AppLanguageAddedEvent")] - public sealed class AppLanguageAdded : IEvent + public sealed class AppLanguageAdded : AppEvent { public Language Language { get; set; } } diff --git a/src/Squidex.Events/Apps/AppLanguageRemoved.cs b/src/Squidex.Events/Apps/AppLanguageRemoved.cs index a234fd592..b7a87edab 100644 --- a/src/Squidex.Events/Apps/AppLanguageRemoved.cs +++ b/src/Squidex.Events/Apps/AppLanguageRemoved.cs @@ -7,12 +7,11 @@ // ========================================================================== using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Events.Apps { [TypeName("AppLanguageRemovedEvent")] - public sealed class AppLanguageRemoved : IEvent + public sealed class AppLanguageRemoved : AppEvent { public Language Language { get; set; } } diff --git a/src/Squidex.Events/Apps/AppMasterLanguageSet.cs b/src/Squidex.Events/Apps/AppMasterLanguageSet.cs index b87f14384..a0ae5b073 100644 --- a/src/Squidex.Events/Apps/AppMasterLanguageSet.cs +++ b/src/Squidex.Events/Apps/AppMasterLanguageSet.cs @@ -7,12 +7,11 @@ // ========================================================================== using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Events.Apps { [TypeName("AppMasterLanguageSetEvent")] - public sealed class AppMasterLanguageSet : IEvent + public sealed class AppMasterLanguageSet : AppEvent { public Language Language { get; set; } } diff --git a/src/Squidex.Events/Contents/ContentCreated.cs b/src/Squidex.Events/Contents/ContentCreated.cs index 30e566e77..dbd8fcf65 100644 --- a/src/Squidex.Events/Contents/ContentCreated.cs +++ b/src/Squidex.Events/Contents/ContentCreated.cs @@ -6,18 +6,14 @@ // All rights reserved. // ========================================================================== -using System; using Squidex.Core.Contents; using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Events.Contents { [TypeName("ContentCreatedEvent")] - public class ContentCreated : IEvent + public class ContentCreated : ContentEvent { - public Guid SchemaId { get; set; } - public ContentData Data { get; set; } } } diff --git a/src/Squidex.Events/Contents/ContentDeleted.cs b/src/Squidex.Events/Contents/ContentDeleted.cs index e6d79f30d..3716b3f07 100644 --- a/src/Squidex.Events/Contents/ContentDeleted.cs +++ b/src/Squidex.Events/Contents/ContentDeleted.cs @@ -7,12 +7,11 @@ // ========================================================================== using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Events.Contents { [TypeName("ContentDeletedEvent")] - public class ContentDeleted : IEvent + public class ContentDeleted : ContentEvent { } } diff --git a/src/Squidex.Write/ISchemaCommand.cs b/src/Squidex.Events/Contents/ContentEvent.cs similarity index 69% rename from src/Squidex.Write/ISchemaCommand.cs rename to src/Squidex.Events/Contents/ContentEvent.cs index 3fa5c6b18..671504619 100644 --- a/src/Squidex.Write/ISchemaCommand.cs +++ b/src/Squidex.Events/Contents/ContentEvent.cs @@ -1,5 +1,5 @@ // ========================================================================== -// ISchemaCommand.cs +// ContentEvent.cs // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex Group @@ -8,10 +8,10 @@ using System; -namespace Squidex.Write +namespace Squidex.Events.Contents { - public interface ISchemaCommand : IAppCommand + public abstract class ContentEvent : SchemaEvent { - Guid SchemaId { get; set; } + public Guid ContentId { get; set; } } } diff --git a/src/Squidex.Events/Contents/ContentPublished.cs b/src/Squidex.Events/Contents/ContentPublished.cs index c352396c0..ecdeebdcf 100644 --- a/src/Squidex.Events/Contents/ContentPublished.cs +++ b/src/Squidex.Events/Contents/ContentPublished.cs @@ -7,12 +7,11 @@ // ========================================================================== using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Events.Contents { [TypeName("ContentPublishedEvent")] - public class ContentPublished : IEvent + public class ContentPublished : ContentEvent { } } diff --git a/src/Squidex.Events/Contents/ContentUnpublished.cs b/src/Squidex.Events/Contents/ContentUnpublished.cs index f3b8d02b5..f791caa58 100644 --- a/src/Squidex.Events/Contents/ContentUnpublished.cs +++ b/src/Squidex.Events/Contents/ContentUnpublished.cs @@ -7,12 +7,11 @@ // ========================================================================== using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Events.Contents { [TypeName("ContentUnpublishedEvent")] - public class ContentUnpublished : IEvent + public class ContentUnpublished : ContentEvent { } } diff --git a/src/Squidex.Events/Contents/ContentUpdated.cs b/src/Squidex.Events/Contents/ContentUpdated.cs index 3ff53c121..ae1a15f12 100644 --- a/src/Squidex.Events/Contents/ContentUpdated.cs +++ b/src/Squidex.Events/Contents/ContentUpdated.cs @@ -8,12 +8,11 @@ using Squidex.Core.Contents; using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Events.Contents { [TypeName("ContentUpdatedEvent")] - public class ContentUpdated : IEvent + public class ContentUpdated : ContentEvent { public ContentData Data { get; set; } } diff --git a/src/Squidex.Events/EventExtensions.cs b/src/Squidex.Events/EventExtensions.cs deleted file mode 100644 index 07cfae2c6..000000000 --- a/src/Squidex.Events/EventExtensions.cs +++ /dev/null @@ -1,41 +0,0 @@ -// ========================================================================== -// EventExtensions.cs -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex Group -// All rights reserved. -// ========================================================================== - -using System; -using System.Globalization; -using Squidex.Infrastructure.CQRS; - -namespace Squidex.Events -{ - public static class EventExtensions - { - public static Guid AppId(this EnvelopeHeaders headers) - { - return headers["AppId"].ToGuid(CultureInfo.InvariantCulture); - } - - public static Envelope SetAppId(this Envelope envelope, Guid value) where T : class - { - envelope.Headers.Set("AppId", value); - - return envelope; - } - - public static Guid SchemaId(this EnvelopeHeaders headers) - { - return headers["SchemaId"].ToGuid(CultureInfo.InvariantCulture); - } - - public static Envelope SetSchemaId(this Envelope envelope, Guid value) where T : class - { - envelope.Headers.Set("SchemaId", value); - - return envelope; - } - } -} diff --git a/src/Squidex.Write/IAppCommand.cs b/src/Squidex.Events/SchemaEvent.cs similarity index 66% rename from src/Squidex.Write/IAppCommand.cs rename to src/Squidex.Events/SchemaEvent.cs index 0715d604b..104c92269 100644 --- a/src/Squidex.Write/IAppCommand.cs +++ b/src/Squidex.Events/SchemaEvent.cs @@ -1,5 +1,5 @@ // ========================================================================== -// IAppCommand.cs +// SchemaEvent.cs // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex Group @@ -7,12 +7,12 @@ // ========================================================================== using System; -using Squidex.Infrastructure.CQRS.Commands; +using Squidex.Infrastructure; -namespace Squidex.Write +namespace Squidex.Events { - public interface IAppCommand : ICommand + public abstract class SchemaEvent : AppEvent { - Guid AppId { get; set; } + public NamedId SchemaId { get; set; } } -} \ No newline at end of file +} diff --git a/src/Squidex.Events/Schemas/FieldEvent.cs b/src/Squidex.Events/Schemas/FieldEvent.cs index acd33b4d4..3bcad7ffc 100644 --- a/src/Squidex.Events/Schemas/FieldEvent.cs +++ b/src/Squidex.Events/Schemas/FieldEvent.cs @@ -6,12 +6,12 @@ // All rights reserved. // ========================================================================== -using Squidex.Infrastructure.CQRS.Events; +using Squidex.Infrastructure; namespace Squidex.Events.Schemas { - public abstract class FieldEvent : IEvent + public abstract class FieldEvent : SchemaEvent { - public long FieldId { get; set; } + public NamedId FieldId { get; set; } } } diff --git a/src/Squidex.Events/Schemas/SchemaCreated.cs b/src/Squidex.Events/Schemas/SchemaCreated.cs index fa3b5ce72..c648517ce 100644 --- a/src/Squidex.Events/Schemas/SchemaCreated.cs +++ b/src/Squidex.Events/Schemas/SchemaCreated.cs @@ -8,12 +8,11 @@ using Squidex.Core.Schemas; using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Events.Schemas { [TypeName("SchemaCreatedEvent")] - public class SchemaCreated : IEvent + public class SchemaCreated : SchemaEvent { public string Name { get; set; } diff --git a/src/Squidex.Events/Schemas/SchemaDeleted.cs b/src/Squidex.Events/Schemas/SchemaDeleted.cs index 8cc5a6ade..3f1cb2b20 100644 --- a/src/Squidex.Events/Schemas/SchemaDeleted.cs +++ b/src/Squidex.Events/Schemas/SchemaDeleted.cs @@ -7,12 +7,11 @@ // ========================================================================== using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Events.Schemas { [TypeName("SchemaDeletedEvent")] - public class SchemaDeleted : IEvent + public class SchemaDeleted : SchemaEvent { } } diff --git a/src/Squidex.Events/Schemas/SchemaPublished.cs b/src/Squidex.Events/Schemas/SchemaPublished.cs index ce141fc07..77b49a043 100644 --- a/src/Squidex.Events/Schemas/SchemaPublished.cs +++ b/src/Squidex.Events/Schemas/SchemaPublished.cs @@ -7,12 +7,11 @@ // ========================================================================== using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Events.Schemas { [TypeName("SchemaPublished")] - public class SchemaPublished : IEvent + public class SchemaPublished : SchemaEvent { } } diff --git a/src/Squidex.Events/Schemas/SchemaUnpublished.cs b/src/Squidex.Events/Schemas/SchemaUnpublished.cs index 6c621999b..d3dc1ac3d 100644 --- a/src/Squidex.Events/Schemas/SchemaUnpublished.cs +++ b/src/Squidex.Events/Schemas/SchemaUnpublished.cs @@ -7,12 +7,11 @@ // ========================================================================== using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Events.Schemas { [TypeName("SchemaUnpublished")] - public class SchemaUnpublished : IEvent + public class SchemaUnpublished : SchemaEvent { } } diff --git a/src/Squidex.Events/Schemas/SchemaUpdated.cs b/src/Squidex.Events/Schemas/SchemaUpdated.cs index 58a107248..5534b17bf 100644 --- a/src/Squidex.Events/Schemas/SchemaUpdated.cs +++ b/src/Squidex.Events/Schemas/SchemaUpdated.cs @@ -8,12 +8,11 @@ using Squidex.Core.Schemas; using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Events.Schemas { [TypeName("SchemaUpdatedEvent")] - public class SchemaUpdated : IEvent + public class SchemaUpdated : SchemaEvent { public SchemaProperties Properties { get; set; } } diff --git a/src/Squidex.Events/Schemas/Utils/SchemaEventDispatcher.cs b/src/Squidex.Events/Schemas/Utils/SchemaEventDispatcher.cs index 92c1e8aaf..515072067 100644 --- a/src/Squidex.Events/Schemas/Utils/SchemaEventDispatcher.cs +++ b/src/Squidex.Events/Schemas/Utils/SchemaEventDispatcher.cs @@ -1,5 +1,5 @@ // ========================================================================== -// SchemaUpdater.cs +// SchemaEventDispatcher.cs // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex Group @@ -19,32 +19,32 @@ namespace Squidex.Events.Schemas.Utils public static Schema Dispatch(FieldAdded @event, Schema schema, FieldRegistry registry) { - return schema.AddOrUpdateField(registry.CreateField(@event.FieldId, @event.Name, @event.Properties)); + return schema.AddOrUpdateField(registry.CreateField(@event.FieldId.Id, @event.Name, @event.Properties)); } public static Schema Dispatch(FieldUpdated @event, Schema schema) { - return schema.UpdateField(@event.FieldId, @event.Properties); + return schema.UpdateField(@event.FieldId.Id, @event.Properties); } public static Schema Dispatch(FieldHidden @event, Schema schema) { - return schema.HideField(@event.FieldId); + return schema.HideField(@event.FieldId.Id); } public static Schema Dispatch(FieldShown @event, Schema schema) { - return schema.ShowField(@event.FieldId); + return schema.ShowField(@event.FieldId.Id); } public static Schema Dispatch(FieldDisabled @event, Schema schema) { - return schema.DisableField(@event.FieldId); + return schema.DisableField(@event.FieldId.Id); } public static Schema Dispatch(FieldEnabled @event, Schema schema) { - return schema.EnableField(@event.FieldId); + return schema.EnableField(@event.FieldId.Id); } public static Schema Dispatch(SchemaUpdated @event, Schema schema) @@ -54,7 +54,7 @@ namespace Squidex.Events.Schemas.Utils public static Schema Dispatch(FieldDeleted @event, Schema schema) { - return schema.DeleteField(@event.FieldId); + return schema.DeleteField(@event.FieldId.Id); } public static Schema Dispatch(SchemaPublished @event, Schema schema) diff --git a/src/Squidex.Events/SquidexEvent.cs b/src/Squidex.Events/SquidexEvent.cs new file mode 100644 index 000000000..e84658bef --- /dev/null +++ b/src/Squidex.Events/SquidexEvent.cs @@ -0,0 +1,18 @@ +// ========================================================================== +// SquidexEvent.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using Squidex.Infrastructure; +using Squidex.Infrastructure.CQRS.Events; + +namespace Squidex.Events +{ + public abstract class SquidexEvent : IEvent + { + public RefToken Actor { get; set; } + } +} diff --git a/src/Squidex.Infrastructure.MongoDb/EventStore/MongoEventStore.cs b/src/Squidex.Infrastructure.MongoDb/EventStore/MongoEventStore.cs index 46ffffa71..6e6d3ce18 100644 --- a/src/Squidex.Infrastructure.MongoDb/EventStore/MongoEventStore.cs +++ b/src/Squidex.Infrastructure.MongoDb/EventStore/MongoEventStore.cs @@ -82,19 +82,21 @@ namespace Squidex.Infrastructure.MongoDb.EventStore { return Observable.Create(async (observer, ct) => { - var position = await GetPreviousOffset(lastReceivedPosition); + var commitOffset = await GetPreviousOffset(lastReceivedPosition); - await Collection.Find(new BsonDocument()).ForEachAsync(commit => + await Collection.Find(x => x.EventsOffset >= commitOffset).SortBy(x => x.EventsOffset).ForEachAsync(commit => { + var eventNumber = commit.EventsOffset; + foreach (var @event in commit.Events) { - position++; + eventNumber++; - if (position > lastReceivedPosition) + if (eventNumber > lastReceivedPosition) { var eventData = SimpleMapper.Map(@event, new EventData()); - observer.OnNext(new StoredEvent(position, eventData)); + observer.OnNext(new StoredEvent(eventNumber, eventData)); } } }, ct); diff --git a/src/Squidex.Infrastructure/CQRS/Commands/IAggregateCommand.cs b/src/Squidex.Infrastructure/CQRS/Commands/IAggregateCommand.cs index 763fab240..ea306cdca 100644 --- a/src/Squidex.Infrastructure/CQRS/Commands/IAggregateCommand.cs +++ b/src/Squidex.Infrastructure/CQRS/Commands/IAggregateCommand.cs @@ -12,6 +12,6 @@ namespace Squidex.Infrastructure.CQRS.Commands { public interface IAggregateCommand : ICommand { - Guid AggregateId { get; set; } + Guid AggregateId { get; } } } \ No newline at end of file diff --git a/src/Squidex.Infrastructure/CQRS/DomainObject.cs b/src/Squidex.Infrastructure/CQRS/DomainObject.cs index b9130fedf..985f60f7c 100644 --- a/src/Squidex.Infrastructure/CQRS/DomainObject.cs +++ b/src/Squidex.Infrastructure/CQRS/DomainObject.cs @@ -45,12 +45,12 @@ namespace Squidex.Infrastructure.CQRS DispatchEvent(@event); version++; } - protected void RaiseEvent(IEvent @event) + protected virtual void RaiseEvent(IEvent @event) { RaiseEvent(Envelope.Create(@event)); } - protected void RaiseEvent(Envelope @event) where TEvent : class, IEvent + protected virtual void RaiseEvent(Envelope @event) where TEvent : class, IEvent { Guard.NotNull(@event, nameof(@event)); diff --git a/src/Squidex.Infrastructure/CQRS/EnvelopeExtensions.cs b/src/Squidex.Infrastructure/CQRS/EnvelopeExtensions.cs index 3022bc98c..27a757517 100644 --- a/src/Squidex.Infrastructure/CQRS/EnvelopeExtensions.cs +++ b/src/Squidex.Infrastructure/CQRS/EnvelopeExtensions.cs @@ -62,18 +62,6 @@ namespace Squidex.Infrastructure.CQRS return envelope; } - public static RefToken Actor(this EnvelopeHeaders headers) - { - return RefToken.Parse(headers[CommonHeaders.Actor].ToString()); - } - - public static Envelope SetActor(this Envelope envelope, RefToken value) where T : class - { - envelope.Headers.Set(CommonHeaders.Actor, value.ToString()); - - return envelope; - } - public static Instant Timestamp(this EnvelopeHeaders headers) { return headers[CommonHeaders.Timestamp].ToInstant(CultureInfo.InvariantCulture); diff --git a/src/Squidex.Infrastructure/CQRS/Events/EnrichWithActorProcessor.cs b/src/Squidex.Infrastructure/CQRS/Events/EnrichWithActorProcessor.cs deleted file mode 100644 index b3e8c8539..000000000 --- a/src/Squidex.Infrastructure/CQRS/Events/EnrichWithActorProcessor.cs +++ /dev/null @@ -1,29 +0,0 @@ -// ========================================================================== -// EnrichWithActorProcessor.cs -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex Group -// All rights reserved. -// ========================================================================== - -using System.Threading.Tasks; -using Squidex.Infrastructure.CQRS.Commands; -using Squidex.Infrastructure.Tasks; - -namespace Squidex.Infrastructure.CQRS.Events -{ - public sealed class EnrichWithActorProcessor : IEventProcessor - { - public Task ProcessEventAsync(Envelope @event, IAggregate aggregate, ICommand command) - { - var actorCommand = command as IActorCommand; - - if (actorCommand != null) - { - @event.SetActor(actorCommand.Actor); - } - - return TaskHelper.Done; - } - } -} diff --git a/src/Squidex.Infrastructure/Json/NamedGuidIdConverted.cs b/src/Squidex.Infrastructure/Json/NamedGuidIdConverter.cs similarity index 96% rename from src/Squidex.Infrastructure/Json/NamedGuidIdConverted.cs rename to src/Squidex.Infrastructure/Json/NamedGuidIdConverter.cs index 0b8cfb425..781a030fc 100644 --- a/src/Squidex.Infrastructure/Json/NamedGuidIdConverted.cs +++ b/src/Squidex.Infrastructure/Json/NamedGuidIdConverter.cs @@ -12,7 +12,7 @@ using Newtonsoft.Json; namespace Squidex.Infrastructure.Json { - public sealed class NamedGuidIdConverted : JsonConverter + public sealed class NamedGuidIdConverter : JsonConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { diff --git a/src/Squidex.Infrastructure/Json/NamedLongIdConverter.cs b/src/Squidex.Infrastructure/Json/NamedLongIdConverter.cs new file mode 100644 index 000000000..0d86c732b --- /dev/null +++ b/src/Squidex.Infrastructure/Json/NamedLongIdConverter.cs @@ -0,0 +1,53 @@ +// ========================================================================== +// NamedLongIdConverter.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System; +using System.Linq; +using Newtonsoft.Json; + +namespace Squidex.Infrastructure.Json +{ + public sealed class NamedLongIdConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var namedId = (NamedId)value; + + writer.WriteValue($"{namedId.Id},{namedId.Name}"); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) + { + return null; + } + + var parts = ((string)reader.Value).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + + if (parts.Length < 2) + { + throw new JsonException("Named id must have more than 2 parts divided by commata"); + } + + long id; + + if (!long.TryParse(parts[0], out id)) + { + throw new JsonException("Named id must be a valid long"); + } + + return new NamedId(id, string.Join(",", parts.Skip(1))); + } + + public override bool CanConvert(Type objectType) + { + return objectType == typeof(NamedId); + } + } +} diff --git a/src/Squidex.Infrastructure/Json/NamedStringIdConverted.cs b/src/Squidex.Infrastructure/Json/NamedStringIdConverter.cs similarity index 95% rename from src/Squidex.Infrastructure/Json/NamedStringIdConverted.cs rename to src/Squidex.Infrastructure/Json/NamedStringIdConverter.cs index da7f3599e..ac4a7bf1c 100644 --- a/src/Squidex.Infrastructure/Json/NamedStringIdConverted.cs +++ b/src/Squidex.Infrastructure/Json/NamedStringIdConverter.cs @@ -12,7 +12,7 @@ using Newtonsoft.Json; namespace Squidex.Infrastructure.Json { - public sealed class NamedStringIdConverted : JsonConverter + public sealed class NamedStringIdConverter : JsonConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { diff --git a/src/Squidex.Infrastructure/NamedId.cs b/src/Squidex.Infrastructure/NamedId.cs index 8849f8a99..8d7cba263 100644 --- a/src/Squidex.Infrastructure/NamedId.cs +++ b/src/Squidex.Infrastructure/NamedId.cs @@ -38,7 +38,7 @@ namespace Squidex.Infrastructure public bool Equals(NamedId other) { - return other != null && (ReferenceEquals(this, other) || Id.Equals(other.Id))); + return other != null && (ReferenceEquals(this, other) || Id.Equals(other.Id)); } public override int GetHashCode() diff --git a/src/Squidex.Read.MongoDb/Apps/MongoAppRepository_EventHandling.cs b/src/Squidex.Read.MongoDb/Apps/MongoAppRepository_EventHandling.cs index 6e88f5d0d..68b68ae5a 100644 --- a/src/Squidex.Read.MongoDb/Apps/MongoAppRepository_EventHandling.cs +++ b/src/Squidex.Read.MongoDb/Apps/MongoAppRepository_EventHandling.cs @@ -8,6 +8,7 @@ using System; using System.Threading.Tasks; +using Squidex.Events; using Squidex.Events.Apps; using Squidex.Infrastructure; using Squidex.Infrastructure.CQRS; @@ -29,7 +30,7 @@ namespace Squidex.Read.MongoDb.Apps protected async Task On(AppCreated @event, EnvelopeHeaders headers) { - await Collection.CreateAsync(headers, a => + await Collection.CreateAsync(@event, headers, a => { SimpleMapper.Map(@event, a); }); @@ -39,7 +40,7 @@ namespace Squidex.Read.MongoDb.Apps protected Task On(AppContributorAssigned @event, EnvelopeHeaders headers) { - return UpdateAsync(headers, a => + return UpdateAsync(@event, headers, a => { var contributor = a.Contributors.GetOrAddNew(@event.ContributorId); @@ -49,7 +50,7 @@ namespace Squidex.Read.MongoDb.Apps protected Task On(AppContributorRemoved @event, EnvelopeHeaders headers) { - return UpdateAsync(headers, a => + return UpdateAsync(@event, headers, a => { a.Contributors.Remove(@event.ContributorId); }); @@ -57,7 +58,7 @@ namespace Squidex.Read.MongoDb.Apps protected Task On(AppClientAttached @event, EnvelopeHeaders headers) { - return UpdateAsync(headers, a => + return UpdateAsync(@event, headers, a => { a.Clients[@event.Id] = SimpleMapper.Map(@event, new MongoAppClientEntity()); }); @@ -65,7 +66,7 @@ namespace Squidex.Read.MongoDb.Apps protected Task On(AppClientRevoked @event, EnvelopeHeaders headers) { - return UpdateAsync(headers, a => + return UpdateAsync(@event, headers, a => { a.Clients.Remove(@event.Id); }); @@ -73,7 +74,7 @@ namespace Squidex.Read.MongoDb.Apps protected Task On(AppClientRenamed @event, EnvelopeHeaders headers) { - return UpdateAsync(headers, a => + return UpdateAsync(@event, headers, a => { a.Clients[@event.Id].Name = @event.Name; }); @@ -81,7 +82,7 @@ namespace Squidex.Read.MongoDb.Apps protected Task On(AppLanguageAdded @event, EnvelopeHeaders headers) { - return UpdateAsync(headers, a => + return UpdateAsync(@event, headers, a => { a.Languages.Add(@event.Language.Iso2Code); }); @@ -89,7 +90,7 @@ namespace Squidex.Read.MongoDb.Apps protected Task On(AppLanguageRemoved @event, EnvelopeHeaders headers) { - return UpdateAsync(headers, a => + return UpdateAsync(@event, headers, a => { a.Languages.Remove(@event.Language.Iso2Code); }); @@ -97,15 +98,15 @@ namespace Squidex.Read.MongoDb.Apps protected Task On(AppMasterLanguageSet @event, EnvelopeHeaders headers) { - return UpdateAsync(headers, a => + return UpdateAsync(@event, headers, a => { a.MasterLanguage = @event.Language.Iso2Code; }); } - public async Task UpdateAsync(EnvelopeHeaders headers, Action updater) + public async Task UpdateAsync(SquidexEvent @event, EnvelopeHeaders headers, Action updater) { - await Collection.UpdateAsync(headers, updater); + await Collection.UpdateAsync(@event, headers, updater); AppSaved?.Invoke(headers.AggregateId()); } diff --git a/src/Squidex.Read.MongoDb/Contents/MongoContentRepository_EventHandling.cs b/src/Squidex.Read.MongoDb/Contents/MongoContentRepository_EventHandling.cs index 48b37e64b..f8ef896d6 100644 --- a/src/Squidex.Read.MongoDb/Contents/MongoContentRepository_EventHandling.cs +++ b/src/Squidex.Read.MongoDb/Contents/MongoContentRepository_EventHandling.cs @@ -10,7 +10,6 @@ using System; using System.Threading.Tasks; using MongoDB.Bson; using MongoDB.Driver; -using Squidex.Events; using Squidex.Events.Contents; using Squidex.Events.Schemas; using Squidex.Infrastructure.CQRS; @@ -59,7 +58,7 @@ namespace Squidex.Read.MongoDb.Contents protected Task On(SchemaCreated @event, EnvelopeHeaders headers) { - return ForSchemaIdAsync(headers.AggregateId(), async collection => + return ForSchemaIdAsync(@event.SchemaId.Id, async collection => { await collection.Indexes.CreateOneAsync(IndexKeys.Ascending(x => x.IsPublished)); await collection.Indexes.CreateOneAsync(IndexKeys.Text(x => x.Text)); @@ -68,9 +67,9 @@ namespace Squidex.Read.MongoDb.Contents protected Task On(ContentCreated @event, EnvelopeHeaders headers) { - return ForSchemaAsync(headers.SchemaId(), (collection, schema) => + return ForSchemaAsync(@event.SchemaId.Id, (collection, schema) => { - return collection.CreateAsync(headers, x => + return collection.CreateAsync(@event, headers, x => { SimpleMapper.Map(@event, x); @@ -81,9 +80,9 @@ namespace Squidex.Read.MongoDb.Contents protected Task On(ContentUpdated @event, EnvelopeHeaders headers) { - return ForSchemaAsync(headers.SchemaId(), (collection, schema) => + return ForSchemaAsync(@event.SchemaId.Id, (collection, schema) => { - return collection.UpdateAsync(headers, x => + return collection.UpdateAsync(@event, headers, x => { x.SetData(schema, @event.Data); }); @@ -92,9 +91,9 @@ namespace Squidex.Read.MongoDb.Contents protected Task On(ContentPublished @event, EnvelopeHeaders headers) { - return ForSchemaIdAsync(headers.SchemaId(), collection => + return ForSchemaIdAsync(@event.SchemaId.Id, collection => { - return collection.UpdateAsync(headers, x => + return collection.UpdateAsync(@event, headers, x => { x.IsPublished = true; }); @@ -103,9 +102,9 @@ namespace Squidex.Read.MongoDb.Contents protected Task On(ContentUnpublished @event, EnvelopeHeaders headers) { - return ForSchemaIdAsync(headers.SchemaId(), collection => + return ForSchemaIdAsync(@event.SchemaId.Id, collection => { - return collection.UpdateAsync(headers, x => + return collection.UpdateAsync(@event, headers, x => { x.IsPublished = false; }); @@ -114,9 +113,9 @@ namespace Squidex.Read.MongoDb.Contents protected Task On(ContentDeleted @event, EnvelopeHeaders headers) { - return ForSchemaIdAsync(headers.SchemaId(), collection => + return ForSchemaIdAsync(@event.SchemaId.Id, collection => { - return collection.UpdateAsync(headers, x => + return collection.UpdateAsync(@event, headers, x => { x.IsDeleted = true; }); @@ -125,7 +124,7 @@ namespace Squidex.Read.MongoDb.Contents protected Task On(FieldDeleted @event, EnvelopeHeaders headers) { - return ForSchemaIdAsync(headers.SchemaId(), collection => + return ForSchemaIdAsync(@event.SchemaId.Id, collection => { return collection.UpdateManyAsync(new BsonDocument(), Update.Unset(new StringFieldDefinition($"Data.{@event.FieldId}"))); }); diff --git a/src/Squidex.Read.MongoDb/History/MongoHistoryEventRepository.cs b/src/Squidex.Read.MongoDb/History/MongoHistoryEventRepository.cs index eaf2ea0a5..7246c295a 100644 --- a/src/Squidex.Read.MongoDb/History/MongoHistoryEventRepository.cs +++ b/src/Squidex.Read.MongoDb/History/MongoHistoryEventRepository.cs @@ -12,6 +12,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using MongoDB.Driver; +using Squidex.Events; using Squidex.Infrastructure.CQRS; using Squidex.Infrastructure.CQRS.Events; using Squidex.Infrastructure.MongoDb; @@ -80,15 +81,17 @@ namespace Squidex.Read.MongoDb.History if (message != null) { - await Collection.CreateAsync(@event.Headers, x => + await Collection.CreateAsync((SquidexEvent)@event.Payload, @event.Headers, entity => { - x.SessionEventIndex = Interlocked.Increment(ref sessionEventCount); + entity.Id = Guid.NewGuid(); - x.Channel = message.Channel; - x.Message = message.Message; + entity.SessionEventIndex = Interlocked.Increment(ref sessionEventCount); - x.Parameters = message.Parameters.ToDictionary(p => p.Key, p => p.Value); - }, false); + entity.Channel = message.Channel; + entity.Message = message.Message; + + entity.Parameters = message.Parameters.ToDictionary(p => p.Key, p => p.Value); + }); } } } diff --git a/src/Squidex.Read.MongoDb/Schemas/MongoSchemaRepository_EventHandling.cs b/src/Squidex.Read.MongoDb/Schemas/MongoSchemaRepository_EventHandling.cs index 50974b44d..a29b4b68a 100644 --- a/src/Squidex.Read.MongoDb/Schemas/MongoSchemaRepository_EventHandling.cs +++ b/src/Squidex.Read.MongoDb/Schemas/MongoSchemaRepository_EventHandling.cs @@ -9,6 +9,7 @@ using System; using System.Threading.Tasks; using Squidex.Core.Schemas; +using Squidex.Events; using Squidex.Events.Schemas; using Squidex.Events.Schemas.Utils; using Squidex.Infrastructure.CQRS; @@ -32,71 +33,71 @@ namespace Squidex.Read.MongoDb.Schemas { var schema = SchemaEventDispatcher.Dispatch(@event); - await Collection.CreateAsync(headers, s => { UpdateSchema(s, schema); SimpleMapper.Map(@event, s); }); + await Collection.CreateAsync(@event, headers, s => { UpdateSchema(s, schema); SimpleMapper.Map(@event, s); }); SchemaSaved?.Invoke(headers.AggregateId()); } protected Task On(FieldDeleted @event, EnvelopeHeaders headers) { - return UpdateSchema(headers, s => SchemaEventDispatcher.Dispatch(@event, s)); + return UpdateSchema(@event, headers, s => SchemaEventDispatcher.Dispatch(@event, s)); } protected Task On(FieldDisabled @event, EnvelopeHeaders headers) { - return UpdateSchema(headers, s => SchemaEventDispatcher.Dispatch(@event, s)); + return UpdateSchema(@event, headers, s => SchemaEventDispatcher.Dispatch(@event, s)); } protected Task On(FieldEnabled @event, EnvelopeHeaders headers) { - return UpdateSchema(headers, s => SchemaEventDispatcher.Dispatch(@event, s)); + return UpdateSchema(@event, headers, s => SchemaEventDispatcher.Dispatch(@event, s)); } protected Task On(FieldHidden @event, EnvelopeHeaders headers) { - return UpdateSchema(headers, s => SchemaEventDispatcher.Dispatch(@event, s)); + return UpdateSchema(@event, headers, s => SchemaEventDispatcher.Dispatch(@event, s)); } protected Task On(FieldShown @event, EnvelopeHeaders headers) { - return UpdateSchema(headers, s => SchemaEventDispatcher.Dispatch(@event, s)); + return UpdateSchema(@event, headers, s => SchemaEventDispatcher.Dispatch(@event, s)); } protected Task On(FieldUpdated @event, EnvelopeHeaders headers) { - return UpdateSchema(headers, s => SchemaEventDispatcher.Dispatch(@event, s)); + return UpdateSchema(@event, headers, s => SchemaEventDispatcher.Dispatch(@event, s)); } protected Task On(SchemaUpdated @event, EnvelopeHeaders headers) { - return UpdateSchema(headers, s => SchemaEventDispatcher.Dispatch(@event, s)); + return UpdateSchema(@event, headers, s => SchemaEventDispatcher.Dispatch(@event, s)); } protected Task On(SchemaPublished @event, EnvelopeHeaders headers) { - return UpdateSchema(headers, s => SchemaEventDispatcher.Dispatch(@event, s)); + return UpdateSchema(@event, headers, s => SchemaEventDispatcher.Dispatch(@event, s)); } protected Task On(SchemaUnpublished @event, EnvelopeHeaders headers) { - return UpdateSchema(headers, s => SchemaEventDispatcher.Dispatch(@event, s)); + return UpdateSchema(@event, headers, s => SchemaEventDispatcher.Dispatch(@event, s)); } protected Task On(FieldAdded @event, EnvelopeHeaders headers) { - return UpdateSchema(headers, s => SchemaEventDispatcher.Dispatch(@event, s, registry)); + return UpdateSchema(@event, headers, s => SchemaEventDispatcher.Dispatch(@event, s, registry)); } protected async Task On(SchemaDeleted @event, EnvelopeHeaders headers) { - await Collection.UpdateAsync(headers, s => s.IsDeleted = true); + await Collection.UpdateAsync(@event, headers, s => s.IsDeleted = true); SchemaSaved?.Invoke(headers.AggregateId()); } - private async Task UpdateSchema(EnvelopeHeaders headers, Func updater) + private async Task UpdateSchema(SquidexEvent @event, EnvelopeHeaders headers, Func updater) { - await Collection.UpdateAsync(headers, e => UpdateSchema(e, updater)); + await Collection.UpdateAsync(@event, headers, e => UpdateSchema(e, updater)); SchemaSaved?.Invoke(headers.AggregateId()); } diff --git a/src/Squidex.Read.MongoDb/Utils/CollectionExtensions.cs b/src/Squidex.Read.MongoDb/Utils/CollectionExtensions.cs new file mode 100644 index 000000000..a3ce7e418 --- /dev/null +++ b/src/Squidex.Read.MongoDb/Utils/CollectionExtensions.cs @@ -0,0 +1,55 @@ +// ========================================================================== +// CollectionExtensions.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System; +using System.Threading.Tasks; +using MongoDB.Driver; +using Squidex.Events; +using Squidex.Infrastructure; +using Squidex.Infrastructure.CQRS; +using Squidex.Infrastructure.MongoDb; + +namespace Squidex.Read.MongoDb.Utils +{ + public static class CollectionExtensions + { + public static Task CreateAsync(this IMongoCollection collection, SquidexEvent @event, EnvelopeHeaders headers, Action updater) where T : MongoEntity, new() + { + var entity = EntityMapper.Create(@event, headers); + + updater(entity); + + return collection.InsertOneIfNotExistsAsync(entity); + } + + public static async Task CreateAsync(this IMongoCollection collection, SquidexEvent @event, EnvelopeHeaders headers, Func updater) where T : MongoEntity, new() + { + var entity = EntityMapper.Create(@event, headers); + + await updater(entity); + + await collection.InsertOneIfNotExistsAsync(entity); + } + + public static async Task UpdateAsync(this IMongoCollection collection, SquidexEvent @event, EnvelopeHeaders headers, Action updater) where T : MongoEntity, new() + { + var entity = await collection.Find(t => t.Id == headers.AggregateId()).FirstOrDefaultAsync(); + + if (entity == null) + { + throw new DomainObjectNotFoundException(headers.AggregateId().ToString(), typeof(T)); + } + + EntityMapper.Update(@event, headers, entity); + + updater(entity); + + await collection.ReplaceOneAsync(t => t.Id == entity.Id, entity); + } + } +} diff --git a/src/Squidex.Read.MongoDb/Utils/EntityMapper.cs b/src/Squidex.Read.MongoDb/Utils/EntityMapper.cs index cfd6ef802..ff3044909 100644 --- a/src/Squidex.Read.MongoDb/Utils/EntityMapper.cs +++ b/src/Squidex.Read.MongoDb/Utils/EntityMapper.cs @@ -6,9 +6,6 @@ // All rights reserved. // ========================================================================== -using System; -using System.Threading.Tasks; -using MongoDB.Driver; using Squidex.Events; using Squidex.Infrastructure.CQRS; using Squidex.Infrastructure.MongoDb; @@ -20,109 +17,72 @@ namespace Squidex.Read.MongoDb.Utils { public static class EntityMapper { - public static T Create(EnvelopeHeaders headers, bool useAggregateId = true) where T : MongoEntity, new() + public static T Create(SquidexEvent @event, EnvelopeHeaders headers) where T : MongoEntity, new() { var entity = new T(); - UpdateWithId(headers, entity, useAggregateId); - UpdateWithAppId(headers, entity); - UpdateWithCreated(headers, entity); - UpdateWithCreatedBy(headers, entity); + SetId(headers, entity); - return Update(entity, headers); + SetCreated(headers, entity); + SetCreatedBy(@event, entity); + + SetAppId(@event, entity); + + return Update(@event, headers, entity); } - public static T Update(T entity, EnvelopeHeaders headers) where T : MongoEntity + public static T Update(SquidexEvent @event, EnvelopeHeaders headers, T entity) where T : MongoEntity, new() { - UpdateWithLastModified(headers, entity); - UpdateWithLastModifiedBy(headers, entity); + SetLastModified(headers, entity); + SetLastModifiedBy(@event, entity); return entity; } - private static void UpdateWithCreated(EnvelopeHeaders headers, MongoEntity entity) + private static void SetId(EnvelopeHeaders headers, MongoEntity entity) + { + entity.Id = headers.AggregateId(); + } + + private static void SetCreated(EnvelopeHeaders headers, MongoEntity entity) { entity.Created = headers.Timestamp().ToDateTimeUtc(); } - private static void UpdateWithLastModified(EnvelopeHeaders headers, MongoEntity entity) + private static void SetLastModified(EnvelopeHeaders headers, MongoEntity entity) { entity.LastModified = headers.Timestamp().ToDateTimeUtc(); } - private static void UpdateWithCreatedBy(EnvelopeHeaders headers, MongoEntity entity) + private static void SetCreatedBy(SquidexEvent @event, MongoEntity entity) { var createdBy = entity as ITrackCreatedByEntity; if (createdBy != null) { - createdBy.CreatedBy = headers.Actor(); + createdBy.CreatedBy = @event.Actor; } } - private static void UpdateWithLastModifiedBy(EnvelopeHeaders headers, MongoEntity entity) + private static void SetLastModifiedBy(SquidexEvent @event, MongoEntity entity) { var modifiedBy = entity as ITrackLastModifiedByEntity; if (modifiedBy != null) { - modifiedBy.LastModifiedBy = headers.Actor(); + modifiedBy.LastModifiedBy = @event.Actor; } } - private static void UpdateWithAppId(EnvelopeHeaders headers, MongoEntity entity) + private static void SetAppId(SquidexEvent @event, MongoEntity entity) { var appEntity = entity as IAppRefEntity; + var appEvent = @event as AppEvent; - if (appEntity != null) - { - appEntity.AppId = headers.AppId(); - } - } - - private static void UpdateWithId(EnvelopeHeaders headers, MongoEntity entity, bool useAggregateId) - { - if (useAggregateId) - { - entity.Id = headers.AggregateId(); - } - else - { - entity.Id = Guid.NewGuid(); - } - } - - public static Task CreateAsync(this IMongoCollection collection, EnvelopeHeaders headers, Action updater, bool useAggregateId = true) where T : MongoEntity, new() - { - var entity = Create(headers, useAggregateId); - - updater(entity); - - return collection.InsertOneIfNotExistsAsync(entity); - } - - public static async Task CreateAsync(this IMongoCollection collection, EnvelopeHeaders headers, Func updater, bool useAggregateId = true) where T : MongoEntity, new() - { - var entity = Create(headers, useAggregateId); - - await updater(entity); - - await collection.InsertOneIfNotExistsAsync(entity); - } - - public static async Task UpdateAsync(this IMongoCollection collection, EnvelopeHeaders headers, Action updater) where T : MongoEntity - { - var entity = await collection.Find(t => t.Id == headers.AggregateId()).FirstOrDefaultAsync(); - - if (entity == null) + if (appEntity != null && appEvent != null) { - return; + appEntity.AppId = appEvent.AppId.Id; } - - Update(entity, headers); - updater(entity); - - await collection.ReplaceOneAsync(t => t.Id == entity.Id, entity); } } } diff --git a/src/Squidex.Read/Schemas/SchemaHistoryEventsCreator.cs b/src/Squidex.Read/Schemas/SchemaHistoryEventsCreator.cs index a6d713f76..dcbb779b7 100644 --- a/src/Squidex.Read/Schemas/SchemaHistoryEventsCreator.cs +++ b/src/Squidex.Read/Schemas/SchemaHistoryEventsCreator.cs @@ -7,12 +7,12 @@ // ========================================================================== using System.Threading.Tasks; +using Squidex.Events; using Squidex.Events.Schemas; using Squidex.Infrastructure; using Squidex.Infrastructure.CQRS; using Squidex.Infrastructure.CQRS.Events; using Squidex.Read.History; -using Squidex.Read.Schemas.Services; // ReSharper disable InvertIf @@ -20,15 +20,9 @@ namespace Squidex.Read.Schemas { public sealed class SchemaHistoryEventsCreator : HistoryEventsCreatorBase { - private readonly ISchemaProvider schemaProvider; - - public SchemaHistoryEventsCreator(TypeNameRegistry typeNameRegistry, ISchemaProvider schemaProvider) + public SchemaHistoryEventsCreator(TypeNameRegistry typeNameRegistry) : base(typeNameRegistry) { - Guard.NotNull(schemaProvider, nameof(schemaProvider)); - - this.schemaProvider = schemaProvider; - AddEventMessage( "created schema {[Name]}"); @@ -69,45 +63,27 @@ namespace Squidex.Read.Schemas "deleted field {[Field]} of schema {[Name]}"); } - protected override async Task CreateEventCoreAsync(Envelope @event) + protected override Task CreateEventCoreAsync(Envelope @event) { - var schemaCreated = @event.Payload as SchemaCreated; + var schemaEvent = @event.Payload as SchemaEvent; - if (schemaCreated != null) + if (schemaEvent == null) { - string channel = $"schemas.{schemaCreated.Name}"; - - return ForEvent(@event.Payload, channel).AddParameter("Name", schemaCreated.Name); + return Task.FromResult(null); } - else - { - var schemaEntity = await schemaProvider.FindSchemaByIdAsync(@event.Headers.AggregateId()); - var schemaName = schemaEntity.Label ?? schemaEntity.Name; - string channel = $"schemas.{schemaName}"; + string channel = $"schemas.{schemaEvent.SchemaId.Name}"; - var result = ForEvent(@event.Payload, channel).AddParameter("Name", schemaName); + var result = ForEvent(@event.Payload, channel).AddParameter("Name", schemaEvent.SchemaId.Name); - var fieldAdded = @event.Payload as FieldAdded; + var fieldEvent = schemaEvent as FieldEvent; - if (fieldAdded != null) - { - result.AddParameter("Field", fieldAdded.Name); - } - else - { - var fieldEvent = @event.Payload as FieldEvent; - - if (fieldEvent != null) - { - var fieldName = schemaEntity.Schema.Fields.GetOrDefault(fieldEvent.FieldId)?.Name; - - result.AddParameter("Field", fieldName); - } - } - - return result; + if (fieldEvent != null) + { + result.AddParameter("Field", fieldEvent.FieldId.Name); } + + return Task.FromResult(result); } } } \ No newline at end of file diff --git a/src/Squidex.Write/AppAggregateCommand.cs b/src/Squidex.Write/AppAggregateCommand.cs index af50e83e8..0e672a0bd 100644 --- a/src/Squidex.Write/AppAggregateCommand.cs +++ b/src/Squidex.Write/AppAggregateCommand.cs @@ -7,21 +7,15 @@ // ========================================================================== using System; +using Squidex.Infrastructure.CQRS.Commands; namespace Squidex.Write { - public class AppAggregateCommand : SquidexCommand, IAppCommand + public class AppAggregateCommand : AppCommand, IAggregateCommand { - Guid IAppCommand.AppId + Guid IAggregateCommand.AggregateId { - get - { - return AggregateId; - } - set - { - AggregateId = value; - } + get { return AppId.Id; } } } } diff --git a/src/Squidex.Write/AppCommand.cs b/src/Squidex.Write/AppCommand.cs index dba4115df..fb3654689 100644 --- a/src/Squidex.Write/AppCommand.cs +++ b/src/Squidex.Write/AppCommand.cs @@ -7,11 +7,12 @@ // ========================================================================== using System; +using Squidex.Infrastructure; namespace Squidex.Write { - public abstract class AppCommand : SquidexCommand, IAppCommand + public abstract class AppCommand : SquidexCommand { - public Guid AppId { get; set; } + public NamedId AppId { get; set; } } } diff --git a/src/Squidex.Write/Apps/AppDomainObject.cs b/src/Squidex.Write/Apps/AppDomainObject.cs index 750ad84e6..7e94400d4 100644 --- a/src/Squidex.Write/Apps/AppDomainObject.cs +++ b/src/Squidex.Write/Apps/AppDomainObject.cs @@ -101,11 +101,13 @@ namespace Squidex.Write.Apps ThrowIfCreated(); - RaiseEvent(SimpleMapper.Map(command, new AppCreated())); + var appId = new NamedId(command.AggregateId, command.Name); - RaiseEvent(CreateInitialOwner(command)); - RaiseEvent(CreateInitialLanguage()); - RaiseEvent(CreateInitialMasterLanguage()); + RaiseEvent(SimpleMapper.Map(command, new AppCreated { AppId = appId })); + + RaiseEvent(SimpleMapper.Map(command, CreateInitialOwner(appId, command))); + RaiseEvent(SimpleMapper.Map(command, CreateInitialLanguage(appId))); + RaiseEvent(SimpleMapper.Map(command, CreateInitialMasterLanguage(appId))); return this; } @@ -198,19 +200,19 @@ namespace Squidex.Write.Apps return this; } - private static AppLanguageAdded CreateInitialLanguage() + private static AppLanguageAdded CreateInitialLanguage(NamedId id) { - return new AppLanguageAdded { Language = DefaultLanguage }; + return new AppLanguageAdded { AppId = id, Language = DefaultLanguage }; } - private static AppMasterLanguageSet CreateInitialMasterLanguage() + private static AppMasterLanguageSet CreateInitialMasterLanguage(NamedId id) { - return new AppMasterLanguageSet { Language = DefaultLanguage }; + return new AppMasterLanguageSet { AppId = id, Language = DefaultLanguage }; } - private static AppContributorAssigned CreateInitialOwner(IActorCommand command) + private static AppContributorAssigned CreateInitialOwner(NamedId id, SquidexCommand command) { - return new AppContributorAssigned { ContributorId = command.Actor.Identifier, Permission = PermissionLevel.Owner }; + return new AppContributorAssigned { AppId = id, ContributorId = command.Actor.Identifier, Permission = PermissionLevel.Owner }; } private void ThrowIfNotCreated() diff --git a/src/Squidex.Write/Apps/Commands/CreateApp.cs b/src/Squidex.Write/Apps/Commands/CreateApp.cs index 7f8d2964e..ae3bb8a5d 100644 --- a/src/Squidex.Write/Apps/Commands/CreateApp.cs +++ b/src/Squidex.Write/Apps/Commands/CreateApp.cs @@ -13,11 +13,11 @@ using Squidex.Infrastructure.CQRS.Commands; namespace Squidex.Write.Apps.Commands { - public sealed class CreateApp : AggregateCommand, IActorCommand, IValidatable + public sealed class CreateApp : SquidexCommand, IValidatable, IAggregateCommand { public string Name { get; set; } - public RefToken Actor { get; set; } + public Guid AggregateId { get; set; } public CreateApp() { diff --git a/src/Squidex.Write/Contents/Commands/ContentCommand.cs b/src/Squidex.Write/Contents/Commands/ContentCommand.cs new file mode 100644 index 000000000..e2a9312fb --- /dev/null +++ b/src/Squidex.Write/Contents/Commands/ContentCommand.cs @@ -0,0 +1,23 @@ +// ========================================================================== +// ContentCommand.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System; +using Squidex.Infrastructure.CQRS.Commands; + +namespace Squidex.Write.Contents.Commands +{ + public abstract class ContentCommand : SchemaCommand, IAggregateCommand + { + public Guid ContentId { get; set; } + + Guid IAggregateCommand.AggregateId + { + get { return ContentId; } + } + } +} diff --git a/src/Squidex.Write/Contents/ContentDataCommand.cs b/src/Squidex.Write/Contents/Commands/ContentDataCommand.cs similarity index 86% rename from src/Squidex.Write/Contents/ContentDataCommand.cs rename to src/Squidex.Write/Contents/Commands/ContentDataCommand.cs index c6b79f22b..bef731061 100644 --- a/src/Squidex.Write/Contents/ContentDataCommand.cs +++ b/src/Squidex.Write/Contents/Commands/ContentDataCommand.cs @@ -10,9 +10,9 @@ using System.Collections.Generic; using Squidex.Core.Contents; using Squidex.Infrastructure; -namespace Squidex.Write.Contents +namespace Squidex.Write.Contents.Commands { - public class ContentDataCommand : SchemaCommand, IValidatable + public abstract class ContentDataCommand : ContentCommand, IValidatable { public ContentData Data { get; set; } diff --git a/src/Squidex.Write/Contents/Commands/CreateContent.cs b/src/Squidex.Write/Contents/Commands/CreateContent.cs index e265b9fdc..9b891b04c 100644 --- a/src/Squidex.Write/Contents/Commands/CreateContent.cs +++ b/src/Squidex.Write/Contents/Commands/CreateContent.cs @@ -6,9 +6,15 @@ // All rights reserved. // ========================================================================== +using System; + namespace Squidex.Write.Contents.Commands { public class CreateContent : ContentDataCommand { + public CreateContent() + { + ContentId = Guid.NewGuid(); + } } } diff --git a/src/Squidex.Write/Contents/Commands/DeleteContent.cs b/src/Squidex.Write/Contents/Commands/DeleteContent.cs index a6380e674..cb98ae54a 100644 --- a/src/Squidex.Write/Contents/Commands/DeleteContent.cs +++ b/src/Squidex.Write/Contents/Commands/DeleteContent.cs @@ -8,7 +8,7 @@ namespace Squidex.Write.Contents.Commands { - public class DeleteContent : SchemaCommand + public class DeleteContent : ContentCommand { } } diff --git a/src/Squidex.Write/Contents/Commands/PublishContent.cs b/src/Squidex.Write/Contents/Commands/PublishContent.cs index 49f46825c..4f888c687 100644 --- a/src/Squidex.Write/Contents/Commands/PublishContent.cs +++ b/src/Squidex.Write/Contents/Commands/PublishContent.cs @@ -8,7 +8,7 @@ namespace Squidex.Write.Contents.Commands { - public class PublishContent : SchemaCommand + public class PublishContent : ContentCommand { } } diff --git a/src/Squidex.Write/Contents/Commands/UnpublishContent.cs b/src/Squidex.Write/Contents/Commands/UnpublishContent.cs index ca44644a4..7e60e1464 100644 --- a/src/Squidex.Write/Contents/Commands/UnpublishContent.cs +++ b/src/Squidex.Write/Contents/Commands/UnpublishContent.cs @@ -8,7 +8,7 @@ namespace Squidex.Write.Contents.Commands { - public class UnpublishContent : SchemaCommand + public class UnpublishContent : ContentCommand { } } diff --git a/src/Squidex.Write/Contents/ContentCommandHandler.cs b/src/Squidex.Write/Contents/ContentCommandHandler.cs index 6c61d4c2d..f6423740b 100644 --- a/src/Squidex.Write/Contents/ContentCommandHandler.cs +++ b/src/Squidex.Write/Contents/ContentCommandHandler.cs @@ -46,7 +46,7 @@ namespace Squidex.Write.Contents { s.Create(command); - context.Succeed(command.AggregateId); + context.Succeed(command.ContentId); }); } @@ -88,8 +88,11 @@ namespace Squidex.Write.Contents { Guard.Valid(command, nameof(command), message); - var taskForApp = appProvider.FindAppByIdAsync(command.AppId); - var taskForSchema = schemaProvider.FindSchemaByIdAsync(command.SchemaId); + var taskForApp = + appProvider.FindAppByIdAsync(command.AppId.Id); + + var taskForSchema = + schemaProvider.FindSchemaByIdAsync(command.SchemaId.Id); await Task.WhenAll(taskForApp, taskForSchema); diff --git a/src/Squidex.Write/EnrichWithAppIdProcessor.cs b/src/Squidex.Write/EnrichWithAppIdProcessor.cs deleted file mode 100644 index 2bb3b9a53..000000000 --- a/src/Squidex.Write/EnrichWithAppIdProcessor.cs +++ /dev/null @@ -1,42 +0,0 @@ -// ========================================================================== -// EnrichWithAppIdProcessor.cs -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex Group -// All rights reserved. -// ========================================================================== - -using System.Threading.Tasks; -using Squidex.Events; -using Squidex.Infrastructure.CQRS; -using Squidex.Infrastructure.CQRS.Commands; -using Squidex.Infrastructure.CQRS.Events; -using Squidex.Infrastructure.Tasks; -using Squidex.Write.Apps; - -namespace Squidex.Write -{ - public sealed class EnrichWithAppIdProcessor : IEventProcessor - { - public Task ProcessEventAsync(Envelope @event, IAggregate aggregate, ICommand command) - { - var appDomainObject = aggregate as AppDomainObject; - - if (appDomainObject != null) - { - @event.SetAppId(aggregate.Id); - } - else - { - var appCommand = command as IAppCommand; - - if (appCommand != null) - { - @event.SetAppId(appCommand.AppId); - } - } - - return TaskHelper.Done; - } - } -} diff --git a/src/Squidex.Write/EnrichWithSchemaIdProcessor.cs b/src/Squidex.Write/EnrichWithSchemaIdProcessor.cs deleted file mode 100644 index 434073e58..000000000 --- a/src/Squidex.Write/EnrichWithSchemaIdProcessor.cs +++ /dev/null @@ -1,42 +0,0 @@ -// ========================================================================== -// EnrichWithSchemaIdProcessor.cs -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex Group -// All rights reserved. -// ========================================================================== - -using System.Threading.Tasks; -using Squidex.Events; -using Squidex.Infrastructure.CQRS; -using Squidex.Infrastructure.CQRS.Commands; -using Squidex.Infrastructure.CQRS.Events; -using Squidex.Infrastructure.Tasks; -using Squidex.Write.Schemas; - -namespace Squidex.Write -{ - public sealed class EnrichWithSchemaIdProcessor : IEventProcessor - { - public Task ProcessEventAsync(Envelope @event, IAggregate aggregate, ICommand command) - { - var schemaDomainObject = aggregate as SchemaDomainObject; - - if (schemaDomainObject != null) - { - @event.SetSchemaId(aggregate.Id); - } - else - { - var schemaCommand = command as ISchemaCommand; - - if (schemaCommand != null) - { - @event.SetSchemaId(schemaCommand.SchemaId); - } - } - - return TaskHelper.Done; - } - } -} diff --git a/src/Squidex.Write/SchemaAggregateCommand.cs b/src/Squidex.Write/SchemaAggregateCommand.cs index 02c0ce2d2..0168fa358 100644 --- a/src/Squidex.Write/SchemaAggregateCommand.cs +++ b/src/Squidex.Write/SchemaAggregateCommand.cs @@ -7,21 +7,15 @@ // ========================================================================== using System; +using Squidex.Infrastructure.CQRS.Commands; namespace Squidex.Write { - public abstract class SchemaAggregateCommand : AppCommand, ISchemaCommand + public abstract class SchemaAggregateCommand : SchemaCommand, IAggregateCommand { - Guid ISchemaCommand.SchemaId + Guid IAggregateCommand.AggregateId { - get - { - return AggregateId; - } - set - { - AggregateId = value; - } + get { return AppId.Id; } } } } diff --git a/src/Squidex.Write/SchemaCommand.cs b/src/Squidex.Write/SchemaCommand.cs index f0e0e895c..96109e695 100644 --- a/src/Squidex.Write/SchemaCommand.cs +++ b/src/Squidex.Write/SchemaCommand.cs @@ -7,11 +7,12 @@ // ========================================================================== using System; +using Squidex.Infrastructure; namespace Squidex.Write { - public abstract class SchemaCommand : AppCommand, ISchemaCommand + public abstract class SchemaCommand : AppCommand { - public Guid SchemaId { get; set; } + public NamedId SchemaId { get; set; } } } diff --git a/src/Squidex.Write/Schemas/Commands/AddField.cs b/src/Squidex.Write/Schemas/Commands/AddField.cs index d021fae3f..eb727c29d 100644 --- a/src/Squidex.Write/Schemas/Commands/AddField.cs +++ b/src/Squidex.Write/Schemas/Commands/AddField.cs @@ -12,7 +12,7 @@ using Squidex.Infrastructure; namespace Squidex.Write.Schemas.Commands { - public class AddField : SchemaAggregateCommand, IValidatable + public class AddField : FieldCommand, IValidatable { public string Name { get; set; } diff --git a/src/Squidex.Write/Schemas/Commands/CreateSchema.cs b/src/Squidex.Write/Schemas/Commands/CreateSchema.cs index efb0139af..a39858b42 100644 --- a/src/Squidex.Write/Schemas/Commands/CreateSchema.cs +++ b/src/Squidex.Write/Schemas/Commands/CreateSchema.cs @@ -10,10 +10,11 @@ using System; using System.Collections.Generic; using Squidex.Core.Schemas; using Squidex.Infrastructure; +using Squidex.Infrastructure.CQRS.Commands; namespace Squidex.Write.Schemas.Commands { - public class CreateSchema : AppCommand, IValidatable + public class CreateSchema : AppCommand, IValidatable, IAggregateCommand { private SchemaProperties properties; @@ -31,9 +32,16 @@ namespace Squidex.Write.Schemas.Commands public string Name { get; set; } + public Guid SchemaId { get; set; } + + Guid IAggregateCommand.AggregateId + { + get { return SchemaId; } + } + public CreateSchema() { - AggregateId = Guid.NewGuid(); + SchemaId = Guid.NewGuid(); } public void Validate(IList errors) diff --git a/src/Squidex.Write/Schemas/Commands/DeleteField.cs b/src/Squidex.Write/Schemas/Commands/DeleteField.cs index 117aad9d6..46bf6c8f8 100644 --- a/src/Squidex.Write/Schemas/Commands/DeleteField.cs +++ b/src/Squidex.Write/Schemas/Commands/DeleteField.cs @@ -8,8 +8,7 @@ namespace Squidex.Write.Schemas.Commands { - public class DeleteField : SchemaAggregateCommand + public class DeleteField : FieldCommand { - public long FieldId { get; set; } } } \ No newline at end of file diff --git a/src/Squidex.Write/Schemas/Commands/DisableField.cs b/src/Squidex.Write/Schemas/Commands/DisableField.cs index 22dc5a8c7..f305c6cc5 100644 --- a/src/Squidex.Write/Schemas/Commands/DisableField.cs +++ b/src/Squidex.Write/Schemas/Commands/DisableField.cs @@ -8,8 +8,7 @@ namespace Squidex.Write.Schemas.Commands { - public class DisableField : SchemaAggregateCommand + public class DisableField : FieldCommand { - public long FieldId { get; set; } } } diff --git a/src/Squidex.Write/Schemas/Commands/EnableField.cs b/src/Squidex.Write/Schemas/Commands/EnableField.cs index b15eddee5..5a954a011 100644 --- a/src/Squidex.Write/Schemas/Commands/EnableField.cs +++ b/src/Squidex.Write/Schemas/Commands/EnableField.cs @@ -8,8 +8,7 @@ namespace Squidex.Write.Schemas.Commands { - public class EnableField : SchemaAggregateCommand + public class EnableField : FieldCommand { - public long FieldId { get; set; } } } diff --git a/src/Squidex.Infrastructure/CQRS/Commands/IActorCommand.cs b/src/Squidex.Write/Schemas/Commands/FieldCommand.cs similarity index 68% rename from src/Squidex.Infrastructure/CQRS/Commands/IActorCommand.cs rename to src/Squidex.Write/Schemas/Commands/FieldCommand.cs index 1e6852c3a..c5be47fe0 100644 --- a/src/Squidex.Infrastructure/CQRS/Commands/IActorCommand.cs +++ b/src/Squidex.Write/Schemas/Commands/FieldCommand.cs @@ -1,15 +1,15 @@ // ========================================================================== -// IActorCommand.cs +// FieldCommand.cs // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex Group // All rights reserved. // ========================================================================== -namespace Squidex.Infrastructure.CQRS.Commands +namespace Squidex.Write.Schemas.Commands { - public interface IActorCommand : ICommand + public class FieldCommand : SchemaAggregateCommand { - RefToken Actor { get; set; } + public long FieldId { get; set; } } } diff --git a/src/Squidex.Write/Schemas/Commands/HideField.cs b/src/Squidex.Write/Schemas/Commands/HideField.cs index d0623b780..c9253d7a3 100644 --- a/src/Squidex.Write/Schemas/Commands/HideField.cs +++ b/src/Squidex.Write/Schemas/Commands/HideField.cs @@ -8,8 +8,7 @@ namespace Squidex.Write.Schemas.Commands { - public class HideField : SchemaAggregateCommand + public class HideField : FieldCommand { - public long FieldId { get; set; } } } diff --git a/src/Squidex.Write/Schemas/Commands/ShowField.cs b/src/Squidex.Write/Schemas/Commands/ShowField.cs index 9fd43cc8a..352d95be1 100644 --- a/src/Squidex.Write/Schemas/Commands/ShowField.cs +++ b/src/Squidex.Write/Schemas/Commands/ShowField.cs @@ -8,8 +8,7 @@ namespace Squidex.Write.Schemas.Commands { - public class ShowField : SchemaAggregateCommand + public class ShowField : FieldCommand { - public long FieldId { get; set; } } } diff --git a/src/Squidex.Write/Schemas/Commands/UpdateField.cs b/src/Squidex.Write/Schemas/Commands/UpdateField.cs index abc7ddcf9..bdacace0d 100644 --- a/src/Squidex.Write/Schemas/Commands/UpdateField.cs +++ b/src/Squidex.Write/Schemas/Commands/UpdateField.cs @@ -12,10 +12,8 @@ using Squidex.Infrastructure; namespace Squidex.Write.Schemas.Commands { - public class UpdateField : SchemaAggregateCommand, IValidatable + public class UpdateField : FieldCommand, IValidatable { - public long FieldId { get; set; } - public FieldProperties Properties { get; set; } public void Validate(IList errors) diff --git a/src/Squidex.Write/Schemas/SchemaCommandHandler.cs b/src/Squidex.Write/Schemas/SchemaCommandHandler.cs index 5ff35a786..3ec0c7531 100644 --- a/src/Squidex.Write/Schemas/SchemaCommandHandler.cs +++ b/src/Squidex.Write/Schemas/SchemaCommandHandler.cs @@ -32,7 +32,7 @@ namespace Squidex.Write.Schemas protected async Task On(CreateSchema command, CommandContext context) { - if (await schemas.FindSchemaByNameAsync(command.AppId, command.Name) != null) + if (await schemas.FindSchemaByNameAsync(command.AppId.Id, command.Name) != null) { var error = new ValidationError($"A schema with name '{command.Name}' already exists", "DisplayName", diff --git a/src/Squidex.Write/Schemas/SchemaDomainObject.cs b/src/Squidex.Write/Schemas/SchemaDomainObject.cs index 8f365785b..5e84f3185 100644 --- a/src/Squidex.Write/Schemas/SchemaDomainObject.cs +++ b/src/Squidex.Write/Schemas/SchemaDomainObject.cs @@ -112,7 +112,7 @@ namespace Squidex.Write.Schemas VerifyCreatedAndNotDeleted(); - RaiseEvent(SimpleMapper.Map(command, new FieldAdded { FieldId = ++totalFields })); + RaiseEvent(SimpleMapper.Map(command, new FieldAdded { FieldId = new NamedId(++totalFields, command.Name) })); return this; } @@ -123,7 +123,7 @@ namespace Squidex.Write.Schemas VerifyCreatedAndNotDeleted(); - RaiseEvent(SimpleMapper.Map(command, new FieldUpdated())); + RaiseEvent(command, SimpleMapper.Map(command, new FieldUpdated())); return this; } @@ -156,7 +156,7 @@ namespace Squidex.Write.Schemas VerifyCreatedAndNotDeleted(); - RaiseEvent(new FieldHidden { FieldId = command.FieldId }); + RaiseEvent(command, new FieldHidden()); return this; } @@ -167,7 +167,7 @@ namespace Squidex.Write.Schemas VerifyCreatedAndNotDeleted(); - RaiseEvent(new FieldShown { FieldId = command.FieldId }); + RaiseEvent(command, new FieldShown()); return this; } @@ -178,7 +178,7 @@ namespace Squidex.Write.Schemas VerifyCreatedAndNotDeleted(); - RaiseEvent(new FieldDisabled { FieldId = command.FieldId }); + RaiseEvent(command, new FieldDisabled()); return this; } @@ -189,7 +189,7 @@ namespace Squidex.Write.Schemas VerifyCreatedAndNotDeleted(); - RaiseEvent(new FieldEnabled { FieldId = command.FieldId }); + RaiseEvent(command, new FieldEnabled()); return this; } @@ -200,7 +200,7 @@ namespace Squidex.Write.Schemas VerifyCreatedAndNotDeleted(); - RaiseEvent(new FieldDeleted { FieldId = command.FieldId }); + RaiseEvent(command, new FieldDeleted()); return this; } @@ -236,6 +236,22 @@ namespace Squidex.Write.Schemas return this; } + protected void RaiseEvent(FieldCommand fieldCommand, FieldEvent @event) + { + Field field; + + if (schema.Fields.TryGetValue(fieldCommand.FieldId, out field)) + { + @event.FieldId = new NamedId(field.Id, field.Name); + } + else + { + throw new DomainObjectNotFoundException(fieldCommand.FieldId.ToString(), "Fields", typeof(Field)); + } + + RaiseEvent(@event); + } + private void VerifyNotCreated() { if (schema != null) diff --git a/src/Squidex.Write/SquidexCommand.cs b/src/Squidex.Write/SquidexCommand.cs index ec08da4f7..abb221411 100644 --- a/src/Squidex.Write/SquidexCommand.cs +++ b/src/Squidex.Write/SquidexCommand.cs @@ -7,11 +7,10 @@ // ========================================================================== using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Commands; namespace Squidex.Write { - public abstract class SquidexCommand : AggregateCommand, IActorCommand + public abstract class SquidexCommand { public RefToken Actor { get; set; } } diff --git a/src/Squidex/Config/Domain/ClusterModule.cs b/src/Squidex/Config/Domain/ClusterModule.cs index 7bab3818f..f67561229 100644 --- a/src/Squidex/Config/Domain/ClusterModule.cs +++ b/src/Squidex/Config/Domain/ClusterModule.cs @@ -46,7 +46,7 @@ namespace Squidex.Config.Domain throw new ConfigurationException("You must specify the clusterer type in the 'squidex:clusterer:type' configuration section."); } - if (string.Equals(clustererType, "Slack", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(clustererType, "Redis", StringComparison.OrdinalIgnoreCase)) { var connectionString = Configuration.GetValue("squidex:clusterer:redis:connectionString"); @@ -78,9 +78,9 @@ namespace Squidex.Config.Domain .As() .SingleInstance(); } - else + else if (!string.Equals(clustererType, "None", StringComparison.OrdinalIgnoreCase)) { - throw new ConfigurationException($"Unsupported clusterer type '{clustererType}' for key 'squidex:clusterer:type', supported: Redis."); + throw new ConfigurationException($"Unsupported clusterer type '{clustererType}' for key 'squidex:clusterer:type', supported: Redis, None."); } } } diff --git a/src/Squidex/Config/Domain/InfrastructureModule.cs b/src/Squidex/Config/Domain/InfrastructureModule.cs index abfa0b5d2..f493ca230 100644 --- a/src/Squidex/Config/Domain/InfrastructureModule.cs +++ b/src/Squidex/Config/Domain/InfrastructureModule.cs @@ -64,10 +64,6 @@ namespace Squidex.Config.Domain .AsSelf() .SingleInstance(); - builder.RegisterType() - .AsSelf() - .SingleInstance(); - builder.RegisterType() .AsSelf() .SingleInstance(); diff --git a/src/Squidex/Config/Domain/Serializers.cs b/src/Squidex/Config/Domain/Serializers.cs index d826239a0..08fcbc99b 100644 --- a/src/Squidex/Config/Domain/Serializers.cs +++ b/src/Squidex/Config/Domain/Serializers.cs @@ -23,13 +23,21 @@ namespace Squidex.Config.Domain private static JsonSerializerSettings ConfigureJson(JsonSerializerSettings settings, TypeNameHandling typeNameHandling) { settings.SerializationBinder = new TypeNameSerializationBinder(typeNameRegistry); + settings.ContractResolver = new CamelCasePropertyNamesContractResolver(); + + settings.Converters.Add(new NamedGuidIdConverter()); + settings.Converters.Add(new NamedLongIdConverter()); + settings.Converters.Add(new NamedStringIdConverter()); settings.Converters.Add(new LanguageConverter()); settings.Converters.Add(new PropertiesBagConverter()); settings.Converters.Add(new RefTokenConverter()); + settings.NullValueHandling = NullValueHandling.Ignore; + settings.DateFormatHandling = DateFormatHandling.IsoDateFormat; settings.DateParseHandling = DateParseHandling.DateTime; + settings.TypeNameHandling = typeNameHandling; return settings; @@ -37,7 +45,7 @@ namespace Squidex.Config.Domain static Serializers() { - typeNameRegistry.Map(typeof(EventExtensions).GetTypeInfo().Assembly); + typeNameRegistry.Map(typeof(SquidexEvent).GetTypeInfo().Assembly); } private static JsonSerializerSettings CreateSettings() diff --git a/src/Squidex/Config/Domain/StoreMongoDbModule.cs b/src/Squidex/Config/Domain/StoreMongoDbModule.cs index d846794cd..d23761c32 100644 --- a/src/Squidex/Config/Domain/StoreMongoDbModule.cs +++ b/src/Squidex/Config/Domain/StoreMongoDbModule.cs @@ -96,7 +96,6 @@ namespace Squidex.Config.Domain builder.RegisterType() .WithParameter(ResolvedParameter.ForNamed(MongoDatabaseName)) .As() - .As() .AsSelf() .SingleInstance(); @@ -120,7 +119,14 @@ namespace Squidex.Config.Domain .As() .AsSelf() .SingleInstance(); - + + builder.Register(c => + new MongoDbConsumerWrapper( + c.ResolveNamed(MongoDatabaseName), + c.Resolve())) + .As() + .SingleInstance(); + /* builder.Register(c => new MongoDbConsumerWrapper( c.ResolveNamed(MongoDatabaseName), @@ -138,9 +144,9 @@ namespace Squidex.Config.Domain builder.Register(c => new MongoDbConsumerWrapper( c.ResolveNamed(MongoDatabaseName), - c.Resolve())) + c.Resolve())) .As() - .SingleInstance(); + .SingleInstance();*/ } } } diff --git a/src/Squidex/Config/Domain/WriteModule.cs b/src/Squidex/Config/Domain/WriteModule.cs index ccf87fc6d..0369345e2 100644 --- a/src/Squidex/Config/Domain/WriteModule.cs +++ b/src/Squidex/Config/Domain/WriteModule.cs @@ -12,7 +12,6 @@ using Squidex.Core.Schemas; using Squidex.Infrastructure.CQRS.Commands; using Squidex.Infrastructure.CQRS.Events; using Squidex.Pipeline.CommandHandlers; -using Squidex.Write; using Squidex.Write.Apps; using Squidex.Write.Contents; using Squidex.Write.Schemas; @@ -47,22 +46,10 @@ namespace Squidex.Config.Domain .SingleInstance(); - builder.RegisterType() - .As() - .SingleInstance(); - - builder.RegisterType() - .As() - .SingleInstance(); - builder.RegisterType() .As() .SingleInstance(); - builder.RegisterType() - .As() - .SingleInstance(); - builder.RegisterType() .AsSelf() diff --git a/src/Squidex/Controllers/Api/Schemas/SchemasController.cs b/src/Squidex/Controllers/Api/Schemas/SchemasController.cs index 856e4f937..404353d29 100644 --- a/src/Squidex/Controllers/Api/Schemas/SchemasController.cs +++ b/src/Squidex/Controllers/Api/Schemas/SchemasController.cs @@ -6,7 +6,6 @@ // All rights reserved. // ========================================================================== -using System; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; @@ -100,7 +99,7 @@ namespace Squidex.Controllers.Api.Schemas [ProducesResponseType(typeof(ErrorDto), 409)] public async Task PostSchema(string app, [FromBody] CreateSchemaDto request) { - var command = SimpleMapper.Map(request, new CreateSchema { AggregateId = Guid.NewGuid() }); + var command = SimpleMapper.Map(request, new CreateSchema()); await CommandBus.PublishAsync(command); diff --git a/src/Squidex/Controllers/ContentApi/ContentsController.cs b/src/Squidex/Controllers/ContentApi/ContentsController.cs index b6d1a0a36..015937fd7 100644 --- a/src/Squidex/Controllers/ContentApi/ContentsController.cs +++ b/src/Squidex/Controllers/ContentApi/ContentsController.cs @@ -111,7 +111,7 @@ namespace Squidex.Controllers.ContentApi [Route("content/{app}/{name}/")] public async Task PostContent([FromBody] ContentData request) { - var command = new CreateContent { Data = request, AggregateId = Guid.NewGuid() }; + var command = new CreateContent { Data = request, ContentId = Guid.NewGuid() }; var context = await CommandBus.PublishAsync(command); var result = context.Result(); @@ -123,7 +123,7 @@ namespace Squidex.Controllers.ContentApi [Route("content/{app}/{name}/{id}")] public async Task PutContent(Guid id, [FromBody] ContentData request) { - var command = new UpdateContent { AggregateId = id, Data = request }; + var command = new UpdateContent { ContentId = id, Data = request }; await CommandBus.PublishAsync(command); @@ -134,7 +134,7 @@ namespace Squidex.Controllers.ContentApi [Route("content/{app}/{name}/{id}")] public async Task PatchContent(Guid id, [FromBody] ContentData request) { - var command = new PatchContent { AggregateId = id, Data = request }; + var command = new PatchContent { ContentId = id, Data = request }; await CommandBus.PublishAsync(command); @@ -145,7 +145,7 @@ namespace Squidex.Controllers.ContentApi [Route("content/{app}/{name}/{id}/publish")] public async Task PublishContent(Guid id) { - var command = new PublishContent { AggregateId = id }; + var command = new PublishContent { ContentId = id }; await CommandBus.PublishAsync(command); @@ -156,7 +156,7 @@ namespace Squidex.Controllers.ContentApi [Route("content/{app}/{name}/{id}/unpublish")] public async Task UnpublishContent(Guid id) { - var command = new UnpublishContent { AggregateId = id }; + var command = new UnpublishContent { ContentId = id }; await CommandBus.PublishAsync(command); @@ -167,7 +167,7 @@ namespace Squidex.Controllers.ContentApi [Route("content/{app}/{name}/{id}")] public async Task PutContent(Guid id) { - var command = new DeleteContent { AggregateId = id }; + var command = new DeleteContent { ContentId = id }; await CommandBus.PublishAsync(command); diff --git a/src/Squidex/Pipeline/CommandHandlers/EnrichWithActorHandler.cs b/src/Squidex/Pipeline/CommandHandlers/EnrichWithActorHandler.cs index f4c3d6590..9ceb6d18e 100644 --- a/src/Squidex/Pipeline/CommandHandlers/EnrichWithActorHandler.cs +++ b/src/Squidex/Pipeline/CommandHandlers/EnrichWithActorHandler.cs @@ -12,6 +12,7 @@ using Microsoft.AspNetCore.Http; using Squidex.Infrastructure; using Squidex.Infrastructure.CQRS.Commands; using Squidex.Infrastructure.Security; +using Squidex.Write; // ReSharper disable InvertIf @@ -28,9 +29,9 @@ namespace Squidex.Pipeline.CommandHandlers public Task HandleAsync(CommandContext context) { - var subjectCommand = context.Command as IActorCommand; + var squidexCommand = context.Command as SquidexCommand; - if (subjectCommand != null) + if (squidexCommand != null) { var actorToken = FindActorFromSubject() ?? @@ -41,7 +42,7 @@ namespace Squidex.Pipeline.CommandHandlers throw new SecurityException("No actor with subject or client id available"); } - subjectCommand.Actor = actorToken; + squidexCommand.Actor = actorToken; } return Task.FromResult(false); diff --git a/src/Squidex/Pipeline/CommandHandlers/EnrichWithAppIdHandler.cs b/src/Squidex/Pipeline/CommandHandlers/EnrichWithAppIdHandler.cs index 87c5279c3..30482bd9f 100644 --- a/src/Squidex/Pipeline/CommandHandlers/EnrichWithAppIdHandler.cs +++ b/src/Squidex/Pipeline/CommandHandlers/EnrichWithAppIdHandler.cs @@ -9,6 +9,7 @@ using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; +using Squidex.Infrastructure; using Squidex.Infrastructure.CQRS.Commands; using Squidex.Write; @@ -27,7 +28,7 @@ namespace Squidex.Pipeline.CommandHandlers public Task HandleAsync(CommandContext context) { - var appCommand = context.Command as IAppCommand; + var appCommand = context.Command as AppCommand; if (appCommand != null) { @@ -38,7 +39,7 @@ namespace Squidex.Pipeline.CommandHandlers throw new InvalidOperationException("Cannot resolve app"); } - appCommand.AppId = appFeature.App.Id; + appCommand.AppId = new NamedId(appFeature.App.Id, appFeature.App.Name); } return Task.FromResult(false); diff --git a/src/Squidex/Pipeline/CommandHandlers/EnrichWithSchemaIdHandler.cs b/src/Squidex/Pipeline/CommandHandlers/EnrichWithSchemaIdHandler.cs index 66b93bbe1..a600573f7 100644 --- a/src/Squidex/Pipeline/CommandHandlers/EnrichWithSchemaIdHandler.cs +++ b/src/Squidex/Pipeline/CommandHandlers/EnrichWithSchemaIdHandler.cs @@ -6,6 +6,7 @@ // All rights reserved. // ========================================================================== +using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Infrastructure; using Squidex.Infrastructure; @@ -32,7 +33,7 @@ namespace Squidex.Pipeline.CommandHandlers public async Task HandleAsync(CommandContext context) { - var schemaCommand = context.Command as ISchemaCommand; + var schemaCommand = context.Command as SchemaCommand; if (schemaCommand != null) { @@ -42,14 +43,14 @@ namespace Squidex.Pipeline.CommandHandlers { var schemaName = routeValues["name"].ToString(); - var schema = await schemaProvider.FindSchemaByNameAsync(schemaCommand.AppId, schemaName); + var schema = await schemaProvider.FindSchemaByNameAsync(schemaCommand.AppId.Id, schemaName); if (schema == null) { throw new DomainObjectNotFoundException(schemaName, typeof(SchemaDomainObject)); } - schemaCommand.SchemaId = schema.Id; + schemaCommand.SchemaId = new NamedId(schema.Id, schema.Name); } } diff --git a/src/Squidex/appsettings.json b/src/Squidex/appsettings.json index 2d7c1d6bb..6625280db 100644 --- a/src/Squidex/appsettings.json +++ b/src/Squidex/appsettings.json @@ -4,7 +4,7 @@ "baseUrl": "http://localhost:5000" }, "clusterer": { - "type": "redis", + "type": "none", "redis": { "connectionString": "redis://localhost:6379" }