package rewards.internal.aspects;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import rewards.internal.account.AccountRepository;
import rewards.internal.monitor.Monitor;
import rewards.internal.monitor.MonitorFactory;
import rewards.internal.restaurant.RestaurantRepository;
import rewards.internal.reward.RewardRepository;
/**
* An aspect that will monitor the performance of all three repositories used in the application.
* @see AccountRepository
* @see RestaurantRepository
* @see RewardRepository
*/
// TODO 1: Declare this class to be an aspect
public class RepositoryPerformanceMonitor {
private static final Logger logger = Logger.getLogger(RepositoryPerformanceMonitor.class);
private MonitorFactory monitorFactory;
public RepositoryPerformanceMonitor
(MonitorFactory monitorFactory) {
this.monitorFactory = monitorFactory;
}
/**
* Times repository method invocations and outputs performance results to
* a Log4J logger.
* @param repositoryMethod The join point representing the intercepted repository method
* @return The object returned by the target method
* @throws Throwable if thrown by the target method
*/
// TODO 2: Declare this method as an Around advice
public Object monitor(ProceedingJoinPoint repositoryMethod)
throws Throwable {
String name = createJoinPointTraceName(repositoryMethod);
Monitor monitor = monitorFactory.start(name);
try {
// TODO 3: Proceed with the target method invocation
return null;
} finally {
monitor.stop();
logger.info(monitor);
}
}
// TODO 4: Create a pointcut that matches any method on the AccountRepository, RestaurantRepository, or
// RewardRepository interfaces
private String createJoinPointTraceName(JoinPoint joinPoint) {
Signature signature = joinPoint.getSignature();
StringBuilder sb = new StringBuilder();
sb.append(signature.getDeclaringType().getSimpleName());
sb.append('.').append(signature.getName());
return sb.toString();
}
}