Browse Source

Started with event enricher.

pull/306/head
Sebastian 8 years ago
parent
commit
91cd235c02
  1. 2
      src/Squidex.Domain.Apps.Core.Model/Rules/Triggers/ContentChangedTriggerSchema.cs
  2. 2
      src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/AlgoliaActionHandler.cs
  3. 6
      src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/ElasticSearchActionHandler.cs
  4. 3
      src/Squidex.Domain.Apps.Core.Operations/HandleRules/EnrichedEvents/EnrichedContentEventAction.cs
  5. 34
      src/Squidex.Domain.Apps.Core.Operations/HandleRules/Triggers/ContentChangedTriggerHandler.cs
  6. 33
      src/Squidex.Domain.Apps.Entities/Contents/ContentVersionLoader.cs
  7. 123
      src/Squidex.Domain.Apps.Entities/Rules/EventEnricher.cs
  8. 5
      src/Squidex/Areas/Api/Controllers/Rules/Models/Triggers/ContentChangedTriggerSchemaDto.cs

2
src/Squidex.Domain.Apps.Core.Model/Rules/Triggers/ContentChangedTriggerSchema.cs

@ -20,5 +20,7 @@ namespace Squidex.Domain.Apps.Core.Rules.Triggers
public bool SendDelete { get; set; }
public bool SendPublish { get; set; }
public bool SendUnpublish { get; set; }
}
}

2
src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/AlgoliaActionHandler.cs

@ -68,7 +68,7 @@ namespace Squidex.Domain.Apps.Core.HandleRules.Actions
};
if (contentEvent.Action == EnrichedContentEventAction.Deleted ||
contentEvent.Action == EnrichedContentEventAction.Archived)
contentEvent.Action == EnrichedContentEventAction.Unpublished)
{
ruleDescription = $"Delete entry from Algolia index: {action.IndexName}";
}

6
src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/ElasticSearchActionHandler.cs

@ -78,13 +78,13 @@ namespace Squidex.Domain.Apps.Core.HandleRules.Actions
};
if (contentEvent.Action == EnrichedContentEventAction.Deleted ||
contentEvent.Action == EnrichedContentEventAction.Archived)
contentEvent.Action == EnrichedContentEventAction.Unpublished)
{
ruleDescription = $"Delete entry from Algolia index: {action.IndexName}";
ruleDescription = $"Delete entry index: {action.IndexName}";
}
else
{
ruleDescription = $"Upsert to ES index: {action.IndexName}";
ruleDescription = $"Upsert to index: {action.IndexName}";
ruleJob.Content = formatter.ToPayload(contentEvent);
ruleJob.Content["objectID"] = contentId;

3
src/Squidex.Domain.Apps.Core.Operations/HandleRules/EnrichedEvents/EnrichedContentEventAction.cs

@ -9,11 +9,10 @@ namespace Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents
{
public enum EnrichedContentEventAction
{
Archived,
Created,
Deleted,
Published,
Restored,
Unpublished,
Updated
}
}

34
src/Squidex.Domain.Apps.Core.Operations/HandleRules/Triggers/ContentChangedTriggerHandler.cs

@ -44,10 +44,36 @@ namespace Squidex.Domain.Apps.Core.HandleRules.Triggers
private static bool MatchsType(ContentChangedTriggerSchema schema, SchemaEvent @event)
{
return
(schema.SendCreate && @event is ContentCreated) ||
(schema.SendUpdate && @event is ContentUpdated) ||
(schema.SendDelete && @event is ContentDeleted) ||
(schema.SendPublish && @event is ContentStatusChanged statusChanged && statusChanged.Status == Status.Published);
IsCreate(schema, @event) ||
IsUpdate(schema, @event) ||
IsDelete(schema, @event) ||
IsPublished(schema, @event) ||
IsUnpublished(schema, @event);
}
private static bool IsPublished(ContentChangedTriggerSchema schema, SchemaEvent @event)
{
return schema.SendPublish && @event is ContentStatusChanged statusChanged && statusChanged.Status == Status.Published;
}
private static bool IsUnpublished(ContentChangedTriggerSchema schema, SchemaEvent @event)
{
return schema.SendUnpublish && @event is ContentStatusChanged statusChanged && statusChanged.Status != Status.Published;
}
private static bool IsCreate(ContentChangedTriggerSchema schema, SchemaEvent @event)
{
return schema.SendCreate && @event is ContentCreated;
}
private static bool IsUpdate(ContentChangedTriggerSchema schema, SchemaEvent @event)
{
return schema.SendUpdate && @event is ContentUpdated || schema.SendUpdate && @event is ContentChangesPublished;
}
private static bool IsDelete(ContentChangedTriggerSchema schema, SchemaEvent @event)
{
return (schema.SendDelete && @event is ContentDeleted);
}
}
}

33
src/Squidex.Domain.Apps.Entities/Contents/ContentVersionLoader.cs

@ -7,52 +7,37 @@
using System;
using System.Threading.Tasks;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Contents.State;
using Orleans;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.States;
namespace Squidex.Domain.Apps.Entities.Contents
{
public sealed class ContentVersionLoader : IContentVersionLoader
{
private readonly IStore<Guid> store;
private readonly FieldRegistry registry;
private readonly IGrainFactory grainFactory;
public ContentVersionLoader(IStore<Guid> store, FieldRegistry registry)
public ContentVersionLoader(IGrainFactory grainFactory)
{
Guard.NotNull(store, nameof(store));
Guard.NotNull(registry, nameof(registry));
Guard.NotNull(grainFactory, nameof(grainFactory));
this.store = store;
this.registry = registry;
this.grainFactory = grainFactory;
}
public async Task<IContentEntity> LoadAsync(Guid id, long version)
{
using (Profiler.TraceMethod<ContentVersionLoader>())
{
var content = new ContentState();
var persistence = store.WithEventSourcing<ContentGrain, Guid>(id, e =>
{
if (content.Version < version)
{
content = content.Apply(e);
content.Version++;
}
});
var grain = grainFactory.GetGrain<IContentGrain>(id);
await persistence.ReadAsync();
var content = await grain.GetStateAsync(version);
if (content.Version != version)
if (content.Value == null || content.Value.Version != version)
{
throw new DomainObjectNotFoundException(id.ToString(), typeof(IContentEntity));
}
return content;
return content.Value;
}
}
}

123
src/Squidex.Domain.Apps.Entities/Rules/EventEnricher.cs

@ -0,0 +1,123 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Threading.Tasks;
using NodaTime;
using Orleans;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents;
using Squidex.Domain.Apps.Entities.Contents;
using Squidex.Domain.Apps.Events;
using Squidex.Domain.Apps.Events.Assets;
using Squidex.Domain.Apps.Events.Contents;
using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Reflection;
namespace Squidex.Domain.Apps.Entities.Rules
{
public sealed class EventEnricher : IEventEnricher
{
private readonly IGrainFactory grainFactory;
private readonly IClock clock;
public EventEnricher(IGrainFactory grainFactory, IClock clock)
{
Guard.NotNull(grainFactory, nameof(grainFactory));
Guard.NotNull(clock, nameof(clock));
this.grainFactory = grainFactory;
this.clock = clock;
}
public Task<EnrichedEvent> EnrichAsync(Envelope<AppEvent> @event)
{
Guard.NotNull(@event, nameof(@event));
if (@event.Payload is ContentEvent contentEvent)
{
return CreateContentEventAsync(contentEvent, @event);
}
if (@event.Payload is AssetEvent assetEvent)
{
}
return Task.FromResult<EnrichedEvent>(null);
}
private async Task<EnrichedEvent> CreateContentEventAsync(ContentEvent contentEvent, Envelope<AppEvent> @event)
{
var result = new EnrichedContentEvent();
var content =
(await grainFactory
.GetGrain<IContentGrain>(contentEvent.ContentId)
.GetStateAsync(@event.Headers.EventStreamNumber())).Value;
SimpleMapper.Map(content, result);
result.Data = content.Data ?? content.DataDraft;
switch (contentEvent)
{
case ContentCreated e:
result.Action = EnrichedContentEventAction.Created;
break;
case ContentDeleted e:
result.Action = EnrichedContentEventAction.Deleted;
break;
case ContentUpdated e:
result.Action = EnrichedContentEventAction.Updated;
break;
case ContentStatusChanged e:
if (e.Status == Status.Published)
{
result.Action = EnrichedContentEventAction.Published;
}
else
{
result.Action = EnrichedContentEventAction.Unpublished;
}
break;
}
result.Name = $"{content.SchemaId.Name.ToPascalCase()}{result.Action}";
SetDefault(result, @event);
return result;
}
private void SetDefault(EnrichedEvent result, Envelope<AppEvent> @event)
{
result.Timestamp =
@event.Headers.Contains(CommonHeaders.Timestamp) ?
@event.Headers.Timestamp() :
clock.GetCurrentInstant();
result.AggregateId =
@event.Headers.Contains(CommonHeaders.AggregateId) ?
@event.Headers.AggregateId() :
Guid.NewGuid();
if (@event.Payload is SquidexEvent squidexEvent)
{
result.Actor = squidexEvent.Actor;
}
if (@event.Payload is AppEvent appEvent)
{
result.AppId = appEvent.AppId;
}
}
}
}

5
src/Squidex/Areas/Api/Controllers/Rules/Models/Triggers/ContentChangedTriggerSchemaDto.cs

@ -35,5 +35,10 @@ namespace Squidex.Areas.Api.Controllers.Rules.Models.Triggers
/// Determines whether to handle the event when a content is published.
/// </summary>
public bool SendPublish { get; set; }
/// <summary>
/// Determines whether to handle the event when a content is unpublished.
/// </summary>
public bool SendUnpublish { get; set; }
}
}

Loading…
Cancel
Save