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 }