mirror of https://github.com/Squidex/squidex.git
15 changed files with 110 additions and 129 deletions
@ -0,0 +1,76 @@ |
|||
// ==========================================================================
|
|||
// ApiCostsFilter.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Diagnostics; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.Filters; |
|||
using Squidex.Domain.Apps.Read.Apps.Services; |
|||
using Squidex.Infrastructure.UsageTracking; |
|||
|
|||
namespace Squidex.Pipeline |
|||
{ |
|||
public sealed class ApiCostsFilter : IAsyncActionFilter, IFilterContainer |
|||
{ |
|||
private readonly IAppPlansProvider appPlanProvider; |
|||
private readonly IUsageTracker usageTracker; |
|||
|
|||
public ApiCostsFilter(IAppPlansProvider appPlanProvider, IUsageTracker usageTracker) |
|||
{ |
|||
this.appPlanProvider = appPlanProvider; |
|||
|
|||
this.usageTracker = usageTracker; |
|||
} |
|||
|
|||
IFilterMetadata IFilterContainer.FilterDefinition { get; set; } |
|||
|
|||
public ApiCostsAttribute FilterDefinition |
|||
{ |
|||
get |
|||
{ |
|||
return (ApiCostsAttribute)((IFilterContainer)this).FilterDefinition; |
|||
} |
|||
} |
|||
|
|||
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) |
|||
{ |
|||
var appFeature = context.HttpContext.Features.Get<IAppFeature>(); |
|||
|
|||
if (appFeature?.App != null && FilterDefinition.Weight > 0) |
|||
{ |
|||
var stopWatch = Stopwatch.StartNew(); |
|||
|
|||
try |
|||
{ |
|||
var plan = appPlanProvider.GetPlanForApp(appFeature.App); |
|||
|
|||
var usage = await usageTracker.GetMonthlyCalls(appFeature.App.Id.ToString(), DateTime.Today); |
|||
|
|||
if (plan.MaxApiCalls >= 0 && (usage * 1.1) > plan.MaxApiCalls) |
|||
{ |
|||
context.Result = new StatusCodeResult(429); |
|||
return; |
|||
} |
|||
|
|||
await next(); |
|||
} |
|||
finally |
|||
{ |
|||
stopWatch.Stop(); |
|||
|
|||
await usageTracker.TrackAsync(appFeature.App.Id.ToString(), FilterDefinition.Weight, stopWatch.ElapsedMilliseconds); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
await next(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,22 +0,0 @@ |
|||
// ==========================================================================
|
|||
// AppFeature.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using Squidex.Domain.Apps.Read.Apps; |
|||
|
|||
namespace Squidex.Pipeline |
|||
{ |
|||
public sealed class AppFeature : IAppFeature |
|||
{ |
|||
public IAppEntity App { get; } |
|||
|
|||
public AppFeature(IAppEntity app) |
|||
{ |
|||
App = app; |
|||
} |
|||
} |
|||
} |
|||
@ -1,45 +0,0 @@ |
|||
// ==========================================================================
|
|||
// AppTrackingMiddleware.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System.Diagnostics; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Squidex.Infrastructure.UsageTracking; |
|||
|
|||
namespace Squidex.Pipeline |
|||
{ |
|||
public sealed class AppTrackingMiddleware |
|||
{ |
|||
private readonly RequestDelegate next; |
|||
private readonly IUsageTracker usageTracker; |
|||
|
|||
public AppTrackingMiddleware(RequestDelegate next, IUsageTracker usageTracker) |
|||
{ |
|||
this.next = next; |
|||
this.usageTracker = usageTracker; |
|||
} |
|||
|
|||
public async Task Invoke(HttpContext context) |
|||
{ |
|||
var stopWatch = Stopwatch.StartNew(); |
|||
|
|||
await next(context); |
|||
|
|||
var appFeature = context.Features.Get<IAppFeature>(); |
|||
|
|||
if (appFeature?.App != null) |
|||
{ |
|||
stopWatch.Stop(); |
|||
|
|||
var weight = context.Features.Get<IAppTrackingWeightFeature>()?.Weight ?? 1; |
|||
|
|||
await usageTracker.TrackAsync(appFeature.App.Id.ToString(), weight, stopWatch.ElapsedMilliseconds); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,15 +0,0 @@ |
|||
// ==========================================================================
|
|||
// IAppTrackingWeightFeature.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
namespace Squidex.Pipeline |
|||
{ |
|||
public interface IAppTrackingWeightFeature |
|||
{ |
|||
double Weight { get; } |
|||
} |
|||
} |
|||
Loading…
Reference in new issue