Beispiel #1
0
        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();
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }