예제 #1
0
        public async Task Should_notify_found_users()
        {
            var user1 = SetupUser("1", "*****@*****.**");
            var user2 = SetupUser("2", "*****@*****.**");
            var user3 = SetupUser("3", null);

            var notification = new UsageNotification
            {
                AppName    = "my-app",
                Usage      = 1000,
                UsageLimit = 3000,
                Users      = new[] { "1", "2", "3" }
            };

            await sut.NotifyAsync(notification);

            A.CallTo(() => notificationSender.SendUsageAsync(user1 !, "my-app", 1000, 3000))
            .MustHaveHappened();

            A.CallTo(() => notificationSender.SendUsageAsync(user2 !, "my-app", 1000, 3000))
            .MustHaveHappened();

            A.CallTo(() => notificationSender.SendUsageAsync(user3 !, "my-app", 1000, 3000))
            .MustNotHaveHappened();
        }
예제 #2
0
        public async Task NotifyAsync(UsageNotification notification)
        {
            var now = DateTime.UtcNow;

            if (!HasBeenSentBefore(notification.AppId, now))
            {
                if (notificationSender.IsActive)
                {
                    foreach (var userId in notification.Users)
                    {
                        var user = await userResolver.FindByIdOrEmailAsync(userId);

                        if (user != null)
                        {
                            notificationSender.SendUsageAsync(user,
                                                              notification.AppName,
                                                              notification.Usage,
                                                              notification.UsageLimit).Forget();
                        }
                    }
                }

                await TrackNotifiedAsync(notification.AppId, now);
            }
        }
예제 #3
0
        public async Task Should_not_send_notification_if_not_active()
        {
            SetupUser("1", null);
            SetupUser("2", null);

            var notification = new UsageNotification
            {
                AppName    = "my-app",
                Usage      = 1000,
                UsageLimit = 3000,
                Users      = new[] { "1", "2" }
            };

            await sut.NotifyAsync(notification);

            A.CallTo(() => notificationSender.SendUsageAsync(A <IUser> ._, "my-app", 1000, 3000))
            .MustNotHaveHappened();
        }
예제 #4
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);
        }
예제 #5
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);
        }
예제 #6
0
        public async Task Should_not_notify_again()
        {
            var user = SetupUser("1", "*****@*****.**");

            var notification = new UsageNotification
            {
                AppName    = "my-app",
                Usage      = 1000,
                UsageLimit = 3000,
                Users      = new[] { "1" }
            };

            await sut.NotifyAsync(notification);

            await sut.NotifyAsync(notification);

            A.CallTo(() => notificationSender.SendUsageAsync(user !, "my-app", 1000, 3000))
            .MustHaveHappenedOnceExactly();
        }
예제 #7
0
        public async Task Should_send_again_after_3_days()
        {
            var user = SetupUser("1", "*****@*****.**");

            var notification = new UsageNotification
            {
                AppName    = "my-app",
                Usage      = 1000,
                UsageLimit = 3000,
                Users      = new[] { "1" }
            };

            await sut.NotifyAsync(notification);

            time = time.Plus(Duration.FromDays(3));

            await sut.NotifyAsync(notification);

            A.CallTo(() => notificationSender.SendUsageAsync(user !, "my-app", 1000, 3000))
            .MustHaveHappenedTwiceExactly();
        }