ICacheConfiguration should be implemented to use caching aspect.
Example:
To use built in configs mentioned above add followings to application.properties file.
# Caching configs
caching.enabled=true
cache.ttl=600
# Define cache config for redis add service address and port
cache.profile=redis
#cache.profile=caffeine
redis.host=localhost
redis.port=6379
Using Cachable annotation with cache name,key or keyExpression(SpEl) and cache action.
@Cacheable(cacheName = "first",key="ALL_CITIES",action = CacheAction.READ)
public List<City> getAll() {
return this.cityDal.getAll();
}
@Cacheable(cacheName = "second",keyExpression="#id",action = CacheAction.READ)
public City getById(int id) {
return this.cityDal.getById(id);
}ILoggerConfiguration interface and ILogging abstract class should be implemented to use logging aspect. For different log logic new ILogging implementation should be done.
Log actions defined as :
public enum LogAction {
ERROR, INFO, WARNING, DEBUG
}ILogging have following methods.
public abstract String debug();
public abstract String info();
public abstract String warn();
public abstract String error(Throwable throwable);Since there is no distinct methods for before and after execution, following fields can be used to achieve this.
If a method need to executed only one of {beforeExecution,afterExecution}, for other part it should return null.
ProceedingJoinPoint joinPoint = null;
Object result = null;
boolean isExecuted = false;joinPoint can be used to get method signature.
result can be used to get result after execution of method.
isExecuted can be used to define log logic before and after execution.
Below example of Logging implementation.
@Component
public class CityLoggingConfig extends ILogging {
public CityLoggingConfig() {
super();
}
@Override
public String debug() {
return super.getIsExecuted() ? "This is before method execution":"This is after method execution";
}
@Override
public String info() {
ProceedingJoinPoint joinPoint = getJoinPoint();// We can access methods parameters with this object.
var method = joinPoint.getArgs();
String methodName = joinPoint.getSignature().getName();
return super.getIsExecuted() ?
"Starting execution of method: "+methodName+" with parameters: "+ Arrays.stream(method).map(o->o.toString()+" ").toString()
: "Finishing execution of method: "+ methodName + (getResult()==null ? "":" with result: "+ getResult());
}
@Override
public String warn() {
return getIsExecuted() ? "Warning before execution":"Warning after execution";
}
@Override
public String error(Throwable throwable) {
return "ERROR in "+getJoinPoint().getSignature().toString()+" Exception details: "+throwable.toString();
}
}Example implementation for ILoggerConfiguration:
To use built in configs mentioned above add followings to application.properties file.
# Logging config
logging.enabled=true
# Logger profile
logger.profile=log4j
#logger.profile=util
Additionally Log4j need log4j2.xml file under resources folder.
Log annotation used with LogAction and logging config:
@Log(log= CityLoggingConfig.class, action = {LogAction.ERROR, LogAction.INFO,LogAction.DEBUG,LogAction.WARNING})
public void add(City city) {
this.cityDal.add(city);
}IValidator should be implemented for entity.
@Component
public class CityValidator implements IValidator<City> {
@Override
public void validate(City target) throws ValidationException {
// Validation code
if (city.getName() == null || city.getName().length() < 3) {
throw new ValidationException("User name cannot be null or empty!");
}
}
}Validate annotation used with validator implementation.
@Validate(CityValidator.class)
public void add(City city) {
this.cityDal.add(city);
}To be able to use Authentication & Authorization your User entity need to inherit from IUser abstract class.
Authentication details in SecurityConfiguration with default settings public request accepted only under "api/auth" path, other request need authentication. Authentication details defined in config package.
Package contains role based Authorization implementation. Roles are currently defined in enum and can be edited directly in enum.
RequiredRoles annotation used for Authorization.
Example:
@RequiredRoles({Role.ADD})
public void add(City city) {
this.cityDal.add(city);
eventBus.publish(new CityCreatedIntegrationEvent(city));
}