* @throws Throwable
*/
public Object intercept(ProceedingJoinPoint joinPoint) throws Throwable {
// extract MethodSignature
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
logger.debug("Intercepted a method call on " + methodSignature.toString());
// find the RateLimited annotation, method gets priority over class
RateLimited annotation = methodSignature.getMethod().getAnnotation(RateLimited.class);
if (annotation == null) {
annotation = (RateLimited) joinPoint.getSourceLocation().getWithinType().getAnnotation(RateLimited.class);
}
// resolve method group name based on the methodGrouping in the annotation
String methodGroupName = null;
switch (annotation.methodGrouping()) {
case GROUPED:
methodGroupName = annotation.groupName();
break;
case UNGROUPED:
methodGroupName = methodSignature.toString();
break;
default:
methodGroupName = methodSignature.toString();
break;
}
// get the limiter strategy chain from the spring context
AbstractLimiterStrategy limiterStrategyChain = (AbstractLimiterStrategy) applicationContext.getBean(annotation.limiterBean());
// generate a uuid to be used later on if rollback is required
UUID methodInvocationUUID = UUIDGenerator.generateUUID();
// run through the limiter strategy chain and get the conclusion
LimiterStrategyConclusion conclusion = limiterStrategyChain.hasLimitBeenExceededChain(methodGroupName, methodInvocationUUID,
joinPoint.getArgs());
// if limit is not exceeded call the method and do a post invocation clean up where needed
if (!conclusion.getHasLimitBeenExceeded()) {
logger.trace("About to run method " + methodSignature.toString());
try {
Object obj = joinPoint.proceed(joinPoint.getArgs());
logger.trace("Finished running " + methodSignature.toString());
return obj;
} catch (Throwable t) {
logger.debug("Method " + methodSignature.toString() + " did not exit gracefully. " + t);
throw t;
} finally {
limiterStrategyChain.postInvocationCleanupChain(methodGroupName, methodInvocationUUID, joinPoint.getArgs());
}
}