From 451a5f24f8c4f2b75a27e56878f44dd976701e84 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Sun, 11 Nov 2018 15:17:51 +0100 Subject: [PATCH] Started with cancelling events. --- .../Rules/MongoRuleEventRepository.cs | 13 ++++---- .../Repositories/IRuleEventRepository.cs | 4 +-- .../Rules/RuleJobResult.cs | 3 +- .../Api/Controllers/Rules/RulesController.cs | 30 +++++++++++++++++-- .../IdentityServer/Config/LazyClientStore.cs | 9 +++--- src/Squidex/Pipeline/Extensions.cs | 15 ++++++---- .../Pipeline/Robots/RobotsTxtMiddleware.cs | 2 +- .../events/rule-events-page.component.html | 14 +++++---- .../events/rule-events-page.component.ts | 4 +++ .../pages/rules/rule-wizard.component.html | 2 +- .../pages/schema/field-wizard.component.html | 2 +- .../pages/schemas/schema-form.component.html | 4 +-- .../pages/more/more-page.component.html | 2 +- .../app/shared/services/rules.service.spec.ts | 13 ++++++++ .../app/shared/services/rules.service.ts | 14 +++++++++ .../shared/state/rule-events.state.spec.ts | 11 +++++++ .../app/shared/state/rule-events.state.ts | 17 ++++++++++- 17 files changed, 127 insertions(+), 32 deletions(-) diff --git a/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEventRepository.cs b/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEventRepository.cs index 352dfc479..f694fc026 100644 --- a/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEventRepository.cs +++ b/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEventRepository.cs @@ -66,11 +66,6 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Rules return ruleEvent; } - public Task RemoveAsync(Guid appId) - { - return Collection.DeleteManyAsync(x => x.AppId == appId); - } - public async Task CountByAppAsync(Guid appId) { return (int)await Collection.CountDocumentsAsync(x => x.AppId == appId); @@ -88,6 +83,14 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Rules return Collection.InsertOneIfNotExistsAsync(entity); } + public Task CancelAsync(Guid id) + { + return Collection.UpdateOneAsync(x => x.Id == id, + Update + .Set(x => x.NextAttempt, null) + .Set(x => x.JobResult, RuleJobResult.Cancelled)); + } + public Task MarkSentAsync(Guid jobId, string dump, RuleResult result, RuleJobResult jobResult, TimeSpan elapsed, Instant? nextAttempt) { return Collection.UpdateOneAsync(x => x.Id == jobId, diff --git a/src/Squidex.Domain.Apps.Entities/Rules/Repositories/IRuleEventRepository.cs b/src/Squidex.Domain.Apps.Entities/Rules/Repositories/IRuleEventRepository.cs index 37b001f72..c630b560b 100644 --- a/src/Squidex.Domain.Apps.Entities/Rules/Repositories/IRuleEventRepository.cs +++ b/src/Squidex.Domain.Apps.Entities/Rules/Repositories/IRuleEventRepository.cs @@ -21,12 +21,12 @@ namespace Squidex.Domain.Apps.Entities.Rules.Repositories Task EnqueueAsync(Guid id, Instant nextAttempt); + Task CancelAsync(Guid id); + Task MarkSentAsync(Guid jobId, string dump, RuleResult result, RuleJobResult jobResult, TimeSpan elapsed, Instant? nextCall); Task QueryPendingAsync(Instant now, Func callback, CancellationToken ct = default(CancellationToken)); - Task RemoveAsync(Guid appId); - Task CountByAppAsync(Guid appId); Task> QueryByAppAsync(Guid appId, int skip = 0, int take = 20); diff --git a/src/Squidex.Domain.Apps.Entities/Rules/RuleJobResult.cs b/src/Squidex.Domain.Apps.Entities/Rules/RuleJobResult.cs index 1587bff95..5d1330cf4 100644 --- a/src/Squidex.Domain.Apps.Entities/Rules/RuleJobResult.cs +++ b/src/Squidex.Domain.Apps.Entities/Rules/RuleJobResult.cs @@ -12,6 +12,7 @@ namespace Squidex.Domain.Apps.Entities.Rules Pending, Success, Retry, - Failed + Failed, + Cancelled } } diff --git a/src/Squidex/Areas/Api/Controllers/Rules/RulesController.cs b/src/Squidex/Areas/Api/Controllers/Rules/RulesController.cs index df642faf5..0ce37daaf 100644 --- a/src/Squidex/Areas/Api/Controllers/Rules/RulesController.cs +++ b/src/Squidex/Areas/Api/Controllers/Rules/RulesController.cs @@ -250,7 +250,7 @@ namespace Squidex.Areas.Api.Controllers.Rules } /// - /// Enqueue the event to be send. + /// Enqueue the event to retry it immediate /// /// The name of the app. /// The event to enqueue. @@ -274,5 +274,31 @@ namespace Squidex.Areas.Api.Controllers.Rules return NoContent(); } + + /// + /// Cancels the event to not retry it again. + /// + /// The name of the app. + /// The event to enqueue. + /// + /// 200 => Rule deqeued. + /// 404 => App or rule event not found. + /// + [HttpDelete] + [Route("apps/{app}/rules/events/{id}/")] + [ApiCosts(0)] + public async Task DeleteEvent(string app, Guid id) + { + var entity = await ruleEventsRepository.FindAsync(id); + + if (entity == null) + { + return NotFound(); + } + + await ruleEventsRepository.CancelAsync(id); + + return NoContent(); + } } -} +} \ No newline at end of file diff --git a/src/Squidex/Areas/IdentityServer/Config/LazyClientStore.cs b/src/Squidex/Areas/IdentityServer/Config/LazyClientStore.cs index 6d48ed63a..adc1451ad 100644 --- a/src/Squidex/Areas/IdentityServer/Config/LazyClientStore.cs +++ b/src/Squidex/Areas/IdentityServer/Config/LazyClientStore.cs @@ -16,6 +16,7 @@ using Squidex.Config; using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Entities; using Squidex.Infrastructure; +using Squidex.Pipeline; namespace Squidex.Areas.IdentityServer.Config { @@ -43,16 +44,16 @@ namespace Squidex.Areas.IdentityServer.Config return client; } - var token = clientId.Split(':', '~'); + var (appName, appClientId) = clientId.GetClientParts(); - if (token.Length != 2) + if (appName == null) { return null; } - var app = await appProvider.GetAppAsync(token[0]); + var app = await appProvider.GetAppAsync(appName); - var appClient = app?.Clients.GetOrDefault(token[1]); + var appClient = app?.Clients.GetOrDefault(appClientId); if (appClient == null) { diff --git a/src/Squidex/Pipeline/Extensions.cs b/src/Squidex/Pipeline/Extensions.cs index 8691365e2..35db046e0 100644 --- a/src/Squidex/Pipeline/Extensions.cs +++ b/src/Squidex/Pipeline/Extensions.cs @@ -22,16 +22,19 @@ namespace Squidex.Pipeline { var clientId = principal.FindFirst(OpenIdClaims.ClientId)?.Value; - var clientIdParts = clientId?.Split(':'); + return clientId?.GetClientParts().ClientId; + } + + public static (string App, string ClientId) GetClientParts(this string clientId) + { + var parts = clientId.Split(':', '~'); - if (clientIdParts?.Length != 2) + if (parts.Length != 2) { - return null; + return (null, null); } - clientId = clientIdParts[1]; - - return clientId; + return (parts[0], parts[1]); } } } diff --git a/src/Squidex/Pipeline/Robots/RobotsTxtMiddleware.cs b/src/Squidex/Pipeline/Robots/RobotsTxtMiddleware.cs index b00aea0bf..2734543e7 100644 --- a/src/Squidex/Pipeline/Robots/RobotsTxtMiddleware.cs +++ b/src/Squidex/Pipeline/Robots/RobotsTxtMiddleware.cs @@ -12,7 +12,7 @@ using Squidex.Infrastructure; namespace Squidex.Pipeline.Robots { - public class RobotsTxtMiddleware : IMiddleware + public sealed class RobotsTxtMiddleware : IMiddleware { private readonly RobotsTxtOptions robotsTxtOptions; diff --git a/src/Squidex/app/features/rules/pages/events/rule-events-page.component.html b/src/Squidex/app/features/rules/pages/events/rule-events-page.component.html index b46ca77a9..4f9ad73e5 100644 --- a/src/Squidex/app/features/rules/pages/events/rule-events-page.component.html +++ b/src/Squidex/app/features/rules/pages/events/rule-events-page.component.html @@ -60,23 +60,27 @@
-
+
{{event.result}}
-
+
Attempts: {{event.numCalls}}
-
+
Next: {{event.nextAttempt | sqxFromNow}}
-
+
+ +
-
+
diff --git a/src/Squidex/app/features/rules/pages/events/rule-events-page.component.ts b/src/Squidex/app/features/rules/pages/events/rule-events-page.component.ts index e56dafa48..694d58a00 100644 --- a/src/Squidex/app/features/rules/pages/events/rule-events-page.component.ts +++ b/src/Squidex/app/features/rules/pages/events/rule-events-page.component.ts @@ -48,6 +48,10 @@ export class RuleEventsPageComponent implements OnInit { this.ruleEventsState.enqueue(event).pipe(onErrorResumeNext()).subscribe(); } + public cancel(event: RuleEventDto) { + this.ruleEventsState.cancel(event).pipe(onErrorResumeNext()).subscribe(); + } + public selectEvent(id: string) { this.selectedEventId = this.selectedEventId !== id ? id : null; } diff --git a/src/Squidex/app/features/rules/pages/rules/rule-wizard.component.html b/src/Squidex/app/features/rules/pages/rules/rule-wizard.component.html index fa6797778..9a7a82dad 100644 --- a/src/Squidex/app/features/rules/pages/rules/rule-wizard.component.html +++ b/src/Squidex/app/features/rules/pages/rules/rule-wizard.component.html @@ -22,7 +22,7 @@
-
+
diff --git a/src/Squidex/app/features/schemas/pages/schema/field-wizard.component.html b/src/Squidex/app/features/schemas/pages/schema/field-wizard.component.html index 4eea34bee..6f0513f40 100644 --- a/src/Squidex/app/features/schemas/pages/schema/field-wizard.component.html +++ b/src/Squidex/app/features/schemas/pages/schema/field-wizard.component.html @@ -16,7 +16,7 @@
-
+