Audit is a very popular feature, and every company I worked with implementing auditing in a different way. Other than JPA audit and using PLSQL trigger, I have done an audit event service which reading message from Message Queue and persist into DB, and also implement @Auditable using spring AOP. My current company prefers to use spring event to achieve the same goal, it's similar to the event service I built.
@Getter
@Setter
@ToString
@EqualsAndHashCode
public class AuditEvent extends ApplicationEvent{
private AuditType auditType;
private BaseEntity entity;
private String oldValue;
private String newValue;
private String moduleId;
private String sourceIp;
private String dataName;
}
@Component
@RequiredArgsConstructor
public class AuditPublisher{
final ApplicationEventPublisher publisher;
public void publishAudit(AuditEvent auditEvent) {
publisher.publishEvent(auditEvent);
}
}@Service
public class SomeService{
private final AuditPublisher auditPublisher;
public void createSomething(){
AuditEvent auditEvent = new AuditEvent();
auditPublisher.publishAudit(auditEvent);
}
}@Component
public class AuditListener implements ApplicationListener<AuditEvent> {
final AuditTrailRepository auditTrailRepository;
public void onApplicationEvent(AuditEvent auditEvent) {
AuditTrail auditTrail = AuditTrail.builder().build();
BeanUtils.copyProperties(auditEvent, auditTrail);
auditTrail.setCreatedBy(AuditContext.getCurrentUser);
auditTrailRepository.save(auditTrail);
}
}@Component
public class AuditInterceptor implements WebRequestInterceptor {
public void preHandle(WebRequest request) {
String username = null;
if (request.getHeader("User") != null) {
username = request.getHeader("User");
}
AuditContext.setCurrentUser(username);
}
public void postHandle(WebRequest request, ModelMap modelMap) {
AuditContext.clear();
}
}public final class AuditContext {
private static final InheritableThreadLocal<String> CURRENT_USER = new InheritableThreadLocal<>();
private AuditContext() {
}
public static void setCurrentUser(String username) {
CURRENT_USER.set(username);
}
public static String getCurrentUser(){
return CURRENT_USER.get();
}
public static void clear(){
CURRENT_USER.remove();
}
}
Comments
Post a Comment