Browse Source

1) Do not enqueue events twice

2) Fixed style for rule events.
pull/214/head
Sebastian Stehle 8 years ago
parent
commit
d5acde4186
  1. 2
      src/Squidex.Domain.Apps.Core.Model/Rules/RuleJob.cs
  2. 17
      src/Squidex.Domain.Apps.Core.Operations/HandleRules/Constants.cs
  3. 13
      src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleService.cs
  4. 2
      src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEventEntity.cs
  5. 8
      src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEventRepository.cs
  6. 9
      src/Squidex.Domain.Apps.Entities/Rules/RuleEnqueuer.cs
  7. 2
      src/Squidex.Infrastructure/EventSourcing/JsonEventDataFormatter.cs
  8. 4
      src/Squidex/app/features/rules/pages/events/rule-events-page.component.scss
  9. 37
      tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleServiceTests.cs
  10. 2
      tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleDequeuerTests.cs

2
src/Squidex.Domain.Apps.Core.Model/Rules/RuleJob.cs

@ -13,7 +13,7 @@ namespace Squidex.Domain.Apps.Core.Rules
{
public sealed class RuleJob
{
public Guid RuleId { get; set; }
public Guid JobId { get; set; }
public Guid AppId { get; set; }

17
src/Squidex.Domain.Apps.Core.Operations/HandleRules/Constants.cs

@ -0,0 +1,17 @@
// ==========================================================================
// Constants.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using NodaTime;
namespace Squidex.Domain.Apps.Core.HandleRules
{
public static class Constants
{
public static readonly Duration ExpirationTime = Duration.FromDays(2);
}
}

13
src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleService.cs

@ -23,7 +23,6 @@ namespace Squidex.Domain.Apps.Core.HandleRules
public class RuleService
{
private const string ContentPrefix = "Content";
private static readonly Duration ExpirationTime = Duration.FromDays(2);
private readonly Dictionary<Type, IRuleActionHandler> ruleActionHandlers;
private readonly Dictionary<Type, IRuleTriggerHandler> ruleTriggerHandlers;
private readonly TypeNameRegistry typeNameRegistry;
@ -84,18 +83,26 @@ namespace Squidex.Domain.Apps.Core.HandleRules
var actionName = typeNameRegistry.GetName(actionType);
var actionData = actionHandler.CreateJob(appEventEnvelope, eventName, rule.Action);
var eventTime = @event.Headers.Contains(CommonHeaders.Timestamp) ? @event.Headers.Timestamp() : now;
var eventGuid = @event.Headers.Contains(CommonHeaders.EventId) ? @event.Headers.EventId() : Guid.NewGuid();
var job = new RuleJob
{
RuleId = Guid.NewGuid(),
JobId = eventGuid,
ActionName = actionName,
ActionData = actionData.Data,
AppId = appEvent.AppId.Id,
Created = now,
EventName = eventName,
Expires = now.Plus(ExpirationTime),
Expires = eventTime.Plus(Constants.ExpirationTime),
Description = actionData.Description
};
if (job.Expires < now)
{
return null;
}
return job;
}

2
src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEventEntity.cs

@ -20,7 +20,7 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Rules
{
[BsonRequired]
[BsonElement]
public Guid AssetId { get; set; }
public Guid AppId { get; set; }
[BsonRequired]
[BsonElement]

8
src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEventRepository.cs

@ -36,7 +36,7 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Rules
protected override async Task SetupCollectionAsync(IMongoCollection<MongoRuleEventEntity> collection)
{
await collection.Indexes.CreateOneAsync(Index.Ascending(x => x.NextAttempt));
await collection.Indexes.CreateOneAsync(Index.Ascending(x => x.AssetId).Descending(x => x.Created));
await collection.Indexes.CreateOneAsync(Index.Ascending(x => x.AppId).Descending(x => x.Created));
await collection.Indexes.CreateOneAsync(Index.Ascending(x => x.Expires), new CreateIndexOptions { ExpireAfter = TimeSpan.Zero });
}
@ -48,7 +48,7 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Rules
public async Task<IReadOnlyList<IRuleEventEntity>> QueryByAppAsync(Guid appId, int skip = 0, int take = 20)
{
var ruleEventEntities =
await Collection.Find(x => x.AssetId == appId).Skip(skip).Limit(take).SortByDescending(x => x.Created)
await Collection.Find(x => x.AppId == appId).Skip(skip).Limit(take).SortByDescending(x => x.Created)
.ToListAsync();
return ruleEventEntities;
@ -65,7 +65,7 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Rules
public async Task<int> CountByAppAsync(Guid appId)
{
return (int)await Collection.CountAsync(x => x.AssetId == appId);
return (int)await Collection.CountAsync(x => x.AppId == appId);
}
public Task EnqueueAsync(Guid id, Instant nextAttempt)
@ -75,7 +75,7 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Rules
public Task EnqueueAsync(RuleJob job, Instant nextAttempt)
{
var entity = SimpleMapper.Map(job, new MongoRuleEventEntity { Job = job, Created = nextAttempt, NextAttempt = nextAttempt });
var entity = SimpleMapper.Map(job, new MongoRuleEventEntity { Id = job.JobId, Job = job, Created = nextAttempt, NextAttempt = nextAttempt });
return Collection.InsertOneIfNotExistsAsync(entity);
}

9
src/Squidex.Domain.Apps.Entities/Rules/RuleEnqueuer.cs

@ -7,6 +7,7 @@
// ==========================================================================
using System.Threading.Tasks;
using NodaTime;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Entities.Rules.Repositories;
using Squidex.Domain.Apps.Events;
@ -32,19 +33,17 @@ namespace Squidex.Domain.Apps.Entities.Rules
get { return ".*"; }
}
public RuleEnqueuer(
IRuleEventRepository ruleEventRepository, IAppProvider appProvider,
public RuleEnqueuer(IAppProvider appProvider, IRuleEventRepository ruleEventRepository,
RuleService ruleService)
{
Guard.NotNull(appProvider, nameof(appProvider));
Guard.NotNull(ruleEventRepository, nameof(ruleEventRepository));
Guard.NotNull(ruleService, nameof(ruleService));
Guard.NotNull(appProvider, nameof(appProvider));
this.appProvider = appProvider;
this.ruleEventRepository = ruleEventRepository;
this.ruleService = ruleService;
this.appProvider = appProvider;
}
public Task ClearAsync()

2
src/Squidex.Infrastructure/EventSourcing/JsonEventDataFormatter.cs

@ -39,6 +39,8 @@ namespace Squidex.Infrastructure.EventSourcing
var envelope = new Envelope<IEvent>(eventPayload, headers);
envelope.SetEventId(eventData.EventId);
return envelope;
}

4
src/Squidex/app/features/rules/pages/events/rule-events-page.component.scss

@ -29,13 +29,13 @@ h3 {
position: relative;
background: $color-border;
border: 0;
margin: -1.25rem;
margin: -.7rem -1.25rem;
margin-bottom: 1rem;
}
&::before {
@include caret-top($color-border);
@include absolute(-1.1rem, 2.3rem, auto, auto);
@include absolute(-1.1rem, 2.5rem, auto, auto);
}
h3 {

37
tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleServiceTests.cs

@ -114,7 +114,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
}
[Fact]
public void Should_create_job_if_triggeres()
public void Should_not_create_job_if_too_old()
{
var e = new ContentCreated { SchemaId = new NamedId<Guid>(Guid.NewGuid(), "my-schema"), AppId = new NamedId<Guid>(Guid.NewGuid(), "my-event") };
@ -123,6 +123,39 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
var ruleConfig = new Rule(new ContentChangedTrigger(), new WebhookAction());
var ruleEnvelope = Envelope.Create(e);
ruleEnvelope.SetTimestamp(now.Minus(Duration.FromDays(3)));
var actionData = new RuleJobData();
var actionDescription = "MyDescription";
var eventName = "MySchemaCreatedEvent";
A.CallTo(() => clock.GetCurrentInstant())
.Returns(now);
A.CallTo(() => ruleTriggerHandler.Triggers(A<Envelope<AppEvent>>.Ignored, ruleConfig.Trigger))
.Returns(true);
A.CallTo(() => ruleActionHandler.CreateJob(A<Envelope<AppEvent>>.Ignored, eventName, ruleConfig.Action))
.Returns((actionDescription, actionData));
var job = sut.CreateJob(ruleConfig, ruleEnvelope);
Assert.Null(job);
}
[Fact]
public void Should_create_job_if_triggered()
{
var e = new ContentCreated { SchemaId = new NamedId<Guid>(Guid.NewGuid(), "my-schema"), AppId = new NamedId<Guid>(Guid.NewGuid(), "my-event") };
var now = SystemClock.Instance.GetCurrentInstant();
var ruleConfig = new Rule(new ContentChangedTrigger(), new WebhookAction());
var ruleEnvelope = Envelope.Create(e);
ruleEnvelope.SetTimestamp(now);
var actionName = "WebhookAction";
var actionData = new RuleJobData();
var actionDescription = "MyDescription";
@ -151,7 +184,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
Assert.Equal(e.AppId.Id, job.AppId);
Assert.NotEqual(Guid.Empty, job.RuleId);
Assert.NotEqual(Guid.Empty, job.JobId);
}
[Fact]

2
tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleDequeuerTests.cs

@ -82,7 +82,7 @@ namespace Squidex.Domain.Apps.Entities.Rules
var job = new RuleJob
{
RuleId = Guid.NewGuid(),
JobId = Guid.NewGuid(),
ActionData = actionData,
ActionName = actionName,
Created = now

Loading…
Cancel
Save