1
I have the following method:
@RequestMapping(path = "/{tenant}/import", method = RequestMethod.POST, consumes = "application/json", produces = "text/plain; charset=UTF-8")
@Transactional
public ResponseEntity<String> requisicaoImportacao(@PathVariable("tenant") String tenant,
@RequestHeader(name = "authentication") String token,
HttpServletRequest req, HttpServletResponse resp) {
...
// faz lógica de negócio
...
}
I need to make sure that for each tenant
, i get a unique access. Only this also needs to be done in other methods. To avoid changing the business code, I decided to put in an aspect this processing.
I created the annotation TenantMutex
to deal with it. The business code has been changed only by adding the notation:
@RequestMapping(path = "/{tenant}/import", method = RequestMethod.POST, consumes = "application/json", produces = "text/plain; charset=UTF-8")
@Transactional
@TenantMutex(0)
public ResponseEntity<String> requisicaoImportacao(@PathVariable("tenant") String tenant,
@RequestHeader(name = "authentication") String token,
HttpServletRequest req, HttpServletResponse resp) {
...
// faz lógica de negócio
...
}
And the processing of this aspect was implemented as follows:
@Aspect
@Component
public class ConcurrencyAspect {
private final HashMap<String, ReentrantLock> tenantLocks;
public ConcurrencyAspect(@Autowired @Qualifier("tenantLocks") HashMap<String, ReentrantLock> tenantLocks) {
this.tenantLocks = tenantLocks;
}
@Around(value = "@annotation(tenantMutex)")
public Object tenantMutex(ProceedingJoinPoint jp, TenantMutex tenantMutex) throws Throwable {
String tenant = (String) jp.getArgs()[tenantMutex.value()];
if (tenant == null) {
throw new HttpClientErrorException(HttpStatus.BAD_REQUEST);
}
tenant = tenant.toLowerCase();
ReentrantLock l = tenantLocks.get(tenant);
if (!l.tryLock(10, TimeUnit.SECONDS)) {
throw new HttpServerErrorException(HttpStatus.SERVICE_UNAVAILABLE);
}
try {
return jp.proceed();
} finally {
l.unlock();
}
}
}
I managed to get the value of tenant
making the "gambiarra" to put, in the note TenantMutex
, the position of the argument of tenant
(in the case of this method, it was at position 0). However, this did not seem so correct.
Is there any more natural alternative to get the value of this parameter within the processing "around" the jointpoint? Preferably that it is somehow passed as an argument to the method that deals with the jointpoint?
I found something related to this: https://www.javainuse.com/spring/spring-boot-aop and also https://stackoverflow.com/q/5568617/4438007 ; maybe you can use and transform in a reply
– Jefferson Quesado
Another interesting point: https://docs.spring.io/spring/docs/2.0.x/reference/aop.html#aop-pointcuts-designators
– Jefferson Quesado
I was able to make an implementation based on this: https://stackoverflow.com/a/3567170/4438007
– Jefferson Quesado