package core.framework.impl.web.rate;
import core.framework.api.web.Interceptor;
import core.framework.api.web.Invocation;
import core.framework.api.web.Response;
import core.framework.api.web.exception.TooManyRequestsException;
import core.framework.api.web.rate.LimitRate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.TimeUnit;
/**
* @author neo
*/
public class LimitRateInterceptor implements Interceptor {
private final Logger logger = LoggerFactory.getLogger(LimitRateInterceptor.class);
private final RateLimiter rateLimiter = new RateLimiter(1000); // save at max 1000 group/ip combination
@Override
public Response intercept(Invocation invocation) throws Exception {
LimitRate limitRate = invocation.annotation(LimitRate.class);
if (limitRate != null) {
String group = limitRate.value();
String clientIP = invocation.context().request().clientIP();
logger.debug("acquire, group={}, clientIP={}", group, clientIP);
boolean result = rateLimiter.acquire(group, clientIP);
if (!result) {
throw new TooManyRequestsException("rate exceeded");
}
}
return invocation.proceed();
}
public void config(String group, int maxPermits, int fillRate, TimeUnit unit) {
rateLimiter.config(group, maxPermits, fillRate, unit);
}
}