public async Task CheckUsagesAsync() { var today = DateTime.Today; foreach (var(key, target) in state.Value.Targets) { var from = GetFromDate(today, target.NumDays); if (target.Triggered == null || target.Triggered < from) { var costs = await usageTracker.GetMonthCallsAsync(target.AppId.Id.ToString(), today, null); var limit = target.Limits; if (costs > limit) { target.Triggered = today; var @event = new AppUsageExceeded { AppId = target.AppId, CallsCurrent = costs, CallsLimit = limit, RuleId = key }; await state.WriteEventAsync(Envelope.Create <IEvent>(@event)); } } } await state.WriteAsync(); }
public virtual async Task <bool> IsBlockedAsync(IAppEntity app, string?clientId, DateTime today) { Guard.NotNull(app, nameof(app)); var appId = app.Id; var isBlocked = false; if (clientId != null && app.Clients.TryGetValue(clientId, out var client) && client.ApiCallsLimit > 0) { var usage = await apiUsageTracker.GetMonthCallsAsync(appId.ToString(), today, clientId); isBlocked = usage >= client.ApiCallsLimit; } var(plan, _) = appPlansProvider.GetPlanForApp(app); var limit = plan.MaxApiCalls; if (limit > 0 || plan.BlockingApiCalls > 0) { var usage = await apiUsageTracker.GetMonthCallsAsync(appId.ToString(), today, null); if (IsOver10Percent(limit, usage) && IsAboutToBeLocked(today, limit, usage) && !HasNotifiedBefore(app.Id)) { var notification = new UsageNotification { AppId = appId, AppName = app.Name, Usage = usage, UsageLimit = limit, Users = GetUsers(app) }; GetGrain().NotifyAsync(notification).Forget(); TrackNotified(appId); } isBlocked = isBlocked || plan.BlockingApiCalls > 0 && usage > plan.BlockingApiCalls; } return(isBlocked); }
public virtual async Task <bool> IsBlockedAsync(IAppEntity app, string?clientId, DateTime today) { Guard.NotNull(app, nameof(app)); var appId = app.Id; var isBlocked = false; if (clientId != null && app.Clients.TryGetValue(clientId, out var client) && client.ApiCallsLimit > 0) { var usage = await apiUsageTracker.GetMonthCallsAsync(appId.ToString(), today, clientId); isBlocked = usage >= client.ApiCallsLimit; } var(plan, _) = appPlansProvider.GetPlanForApp(app); if (plan.MaxApiCalls > 0 || plan.BlockingApiCalls > 0) { var usage = await apiUsageTracker.GetMonthCallsAsync(appId.ToString(), today, null); if (IsAboutToBeLocked(today, plan.MaxApiCalls, usage) && !HasNotifiedBefore(app.Id)) { var users = app.Contributors.Where(x => x.Value == Role.Owner).Select(x => x.Key).ToArray(); var notification = new UsageNotification { AppId = appId, AppName = app.Name, Usage = usage, UsageLimit = plan.MaxApiCalls, Users = users }; usageLimitNotifier.NotifyAsync(notification).Forget(); TrackNotified(appId); } isBlocked = isBlocked || plan.BlockingApiCalls > 0 && usage > plan.BlockingApiCalls; } return(isBlocked); }
public UsageGateTests() { appEntity = Mocks.App(appId); A.CallTo(() => grainFactory.GetGrain <IUsageNotifierGrain>(SingleGrain.Id, null)) .Returns(usageNotifierGrain); A.CallTo(() => appPlansProvider.GetPlan(null)) .Returns(appPlan); A.CallTo(() => appPlansProvider.GetPlanForApp(appEntity)) .Returns((appPlan, "free")); A.CallTo(() => appPlan.MaxApiCalls) .ReturnsLazily(x => apiCallsMax); A.CallTo(() => appPlan.BlockingApiCalls) .ReturnsLazily(x => apiCallsBlocking); A.CallTo(() => usageTracker.GetMonthCallsAsync(appId.Id.ToString(), today, A <string> ._)) .ReturnsLazily(x => Task.FromResult(apiCallsCurrent)); sut = new UsageGate(appPlansProvider, usageTracker, grainFactory); }