1 package org.oxerr.vividseats.client.rescu.impl;
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Method;
5
6 import org.slf4j.Logger;
7 import org.slf4j.LoggerFactory;
8
9 import io.github.poshjosh.ratelimiter.RateLimiter;
10 import io.github.poshjosh.ratelimiter.RateLimiterContext;
11 import io.github.poshjosh.ratelimiter.RateLimiterRegistries;
12 import io.github.poshjosh.ratelimiter.store.BandwidthsStore;
13 import si.mazi.rescu.Interceptor;
14
15 public class RateLimiterInterceptor implements Interceptor {
16
17 private final Logger log = LoggerFactory.getLogger(RateLimiterInterceptor.class);
18
19 private final BandwidthsStore<String> store;
20
21 public RateLimiterInterceptor(BandwidthsStore<String> store) {
22 this.store = store;
23 }
24
25 @Override
26 public Object aroundInvoke(InvocationHandler invocationHandler, Object proxy, Method method, Object[] args)
27 throws Throwable {
28 var limiter = getRateLimiter(method);
29
30 log.trace("Acquiring permit for {}...", method);
31 var timeSpent = limiter.acquire();
32 log.trace("Acquired permit for {} in {} seconds.", method, timeSpent);
33
34 return invocationHandler.invoke(proxy, method, args);
35 }
36
37 public RateLimiter getRateLimiter(Method method) {
38 var context = RateLimiterContext.builder().classes(method.getDeclaringClass()).store(store).build();
39 return RateLimiterRegistries.of(context).getMethodRateLimiter(method);
40 }
41
42 }