Commit 65013491 authored by Matija Obreza's avatar Matija Obreza
Browse files

AuditTrailService made useful

- Added listAuditLogs(EntityId)
- Added javadoc to AuditTrailService
- listAuditLogs(EntityId) loads referenced entity data
parent 6efb79cb
......@@ -32,6 +32,7 @@ import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import org.genesys.blocks.auditlog.annotations.NotAudited;
import org.genesys.blocks.model.ClassPK;
......@@ -96,6 +97,14 @@ public class AuditLog implements Serializable {
@Column(length = 10, nullable = false, updatable = false)
private AuditAction action;
/** The previous entity. */
@Transient
private Object previousEntity;
/** The next entity. */
@Transient
private Object newEntity;
/**
* Gets the id.
*
......@@ -275,4 +284,40 @@ public class AuditLog implements Serializable {
public AuditAction getAction() {
return action;
}
/**
* Sets the previous entity.
*
* @param entity the new previous entity
*/
public void setPreviousEntity(Object entity) {
this.previousEntity=entity;
}
/**
* Gets the previous entity.
*
* @return the previous entity
*/
public Object getPreviousEntity() {
return previousEntity;
}
/**
* Sets the new entity.
*
* @param newEntity the new new entity
*/
public void setNewEntity(Object newEntity) {
this.newEntity = newEntity;
}
/**
* Gets the new entity.
*
* @return the new entity
*/
public Object getNewEntity() {
return newEntity;
}
}
......@@ -19,6 +19,7 @@ import java.util.List;
import org.genesys.blocks.auditlog.model.AuditLog;
import org.genesys.blocks.auditlog.model.filters.AuditLogFilter;
import org.genesys.blocks.model.ClassPK;
import org.genesys.blocks.model.EntityId;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
......@@ -61,4 +62,14 @@ public interface AuditLogCustomRepository {
* @return the page
*/
Page<AuditLog> listAuditLogs(AuditLogFilter filters, Pageable page);
/**
* Load entity from database by classname and id
*
* @param referencedClassPk
* @param previousState
* @return
*/
Object get(ClassPK classPk, Long id);
}
......@@ -15,11 +15,17 @@
*/
package org.genesys.blocks.auditlog.persistence;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import org.genesys.blocks.auditlog.model.AuditLog;
import org.genesys.blocks.auditlog.model.filters.AuditLogFilter;
import org.genesys.blocks.model.ClassPK;
import org.genesys.blocks.model.EntityId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
......@@ -32,10 +38,17 @@ import org.springframework.data.domain.Pageable;
*/
public class AuditLogRepositoryCustomImpl implements AuditLogCustomRepository {
/** The Constant LOG. */
private static final Logger LOG = LoggerFactory.getLogger(AuditLogRepositoryCustomImpl.class);
/** The repository. */
@Autowired
private AuditLogRepository repository;
/** The entity manager. */
@Autowired
private EntityManager entityManager;
/*
* (non-Javadoc)
* @see org.genesys.blocks.auditlog.persistence.AuditLogCustomRepository#
......@@ -43,6 +56,9 @@ public class AuditLogRepositoryCustomImpl implements AuditLogCustomRepository {
*/
@Override
public List<AuditLog> listAuditLogs(final EntityId entity) {
if (entity == null) {
return new ArrayList<>();
}
return repository.listAuditLogs(entity.getClass().getName(), entity.getId());
}
......@@ -78,4 +94,24 @@ public class AuditLogRepositoryCustomImpl implements AuditLogCustomRepository {
public Page<AuditLog> listAuditLogs(final AuditLogFilter filters, final Pageable page) {
return repository.findAll(filters.buildQuery(), page);
}
/*
* (non-Javadoc)
* @see
* org.genesys.blocks.auditlog.persistence.AuditLogCustomRepository#get(org.
* genesys.blocks.model.ClassPK, java.lang.Long)
*/
@Override
public Object get(ClassPK classPk, Long id) {
LOG.trace("Looking up {} id={}", classPk.getClassname(), id);
if (id == null || classPk == null || classPk.getClassname() == null) {
return null;
}
try {
return entityManager.find(Class.forName(classPk.getClassname()), id);
} catch (ClassNotFoundException e) {
LOG.error(e.getMessage(), e);
return null;
}
}
}
......@@ -16,12 +16,15 @@
package org.genesys.blocks.auditlog.service;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.genesys.blocks.auditlog.component.AuditTrailInterceptor;
import org.genesys.blocks.auditlog.model.AuditAction;
import org.genesys.blocks.auditlog.model.AuditLog;
import org.genesys.blocks.auditlog.model.TransactionAuditLog;
import org.genesys.blocks.auditlog.model.filters.AuditLogFilter;
import org.genesys.blocks.model.EntityId;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
......@@ -41,8 +44,49 @@ public interface AuditTrailService {
*/
Page<AuditLog> listAuditLogs(AuditLogFilter filters, Pageable page);
/**
* Create a temporary audit log entry. This is used by the
* {@link AuditTrailInterceptor}.
*
* @param action the action
* @param entity the entity
* @param id the id
* @param propertyName the property name
* @param previousState the previous state
* @param currentState the current state
* @param referencedEntity the referenced entity
* @return the transaction audit log
*/
TransactionAuditLog auditLogEntry(AuditAction action, Object entity, long id, String propertyName, String previousState, String currentState, Class<?> referencedEntity);
/**
* Record audit logs in the database.
*
* @param auditLogs the audit logs
* @return the list
*/
List<AuditLog> addAuditLogs(Set<TransactionAuditLog> auditLogs);
/**
* List audit logs for the specified entity. Logs are sorted by log date
* (descending). Where logs reference an entity, these are made available in
* {@link AuditLog#getNewEntity()} and {@link AuditLog#getPreviousEntity()}.
*
* @param entity Entity for which to list logs
* @return List of all log entries for the specified entity
*/
List<AuditLog> listAuditLogs(EntityId entity);
/**
* Map audit logs by property for the specified entity.
*
* Logs are sorted by log date (descending). Where logs reference an entity,
* these are made available in {@link AuditLog#getNewEntity()} and
* {@link AuditLog#getPreviousEntity()}.
*
* @param entity Entity for which to list logs
* @return Map of all log entries for the specified entity by property name
*/
Map<String, List<AuditLog>> auditLogs(EntityId entity);
}
......@@ -15,11 +15,15 @@
*/
package org.genesys.blocks.auditlog.service.impl;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang3.math.NumberUtils;
import org.genesys.blocks.auditlog.model.AuditAction;
import org.genesys.blocks.auditlog.model.AuditLog;
import org.genesys.blocks.auditlog.model.TransactionAuditLog;
......@@ -27,6 +31,8 @@ import org.genesys.blocks.auditlog.model.filters.AuditLogFilter;
import org.genesys.blocks.auditlog.persistence.AuditLogRepository;
import org.genesys.blocks.auditlog.service.AuditTrailService;
import org.genesys.blocks.auditlog.service.ClassPKService;
import org.genesys.blocks.model.ClassPK;
import org.genesys.blocks.model.EntityId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -57,12 +63,24 @@ public class AuditTrailServiceImpl implements AuditTrailService {
@Autowired
private AuditLogRepository auditLogRepository;
/*
* (non-Javadoc)
* @see
* org.genesys.blocks.auditlog.service.AuditTrailService#addAuditLogs(java.util.
* Set)
*/
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED)
public List<AuditLog> addAuditLogs(Set<TransactionAuditLog> auditLogs) {
public List<AuditLog> addAuditLogs(final Set<TransactionAuditLog> auditLogs) {
return auditLogRepository.save(auditLogs.stream().map(tlog -> toAuditLog(tlog)).collect(Collectors.toList()));
}
/*
* (non-Javadoc)
* @see org.genesys.blocks.auditlog.service.AuditTrailService#auditLogEntry(org.
* genesys.blocks.auditlog.model.AuditAction, java.lang.Object, long,
* java.lang.String, java.lang.String, java.lang.String, java.lang.Class)
*/
@Override
public TransactionAuditLog auditLogEntry(final AuditAction action, final Object entity, final long id, final String propertyName, final String previousState,
final String currentState, final Class<?> referencedEntity) {
......@@ -85,8 +103,14 @@ public class AuditTrailServiceImpl implements AuditTrailService {
return log;
}
private AuditLog toAuditLog(TransactionAuditLog tlog) {
AuditLog auditLog = new AuditLog();
/**
* To audit log.
*
* @param tlog the tlog
* @return the audit log
*/
private AuditLog toAuditLog(final TransactionAuditLog tlog) {
final AuditLog auditLog = new AuditLog();
auditLog.setLogDate(new Date());
auditLog.setAction(tlog.getAction());
auditLog.setClassPk(tlog.getClassPk());
......@@ -108,4 +132,47 @@ public class AuditTrailServiceImpl implements AuditTrailService {
public Page<AuditLog> listAuditLogs(final AuditLogFilter filters, final Pageable page) {
return auditLogRepository.listAuditLogs(filters, page);
}
/*
* (non-Javadoc)
* @see org.genesys.blocks.auditlog.service.AuditTrailService#listAuditLogs(org.
* genesys.blocks.model.EntityId)
*/
@Override
public List<AuditLog> listAuditLogs(final EntityId entity) {
List<AuditLog> auditLogs = auditLogRepository.listAuditLogs(entity);
auditLogs.stream()
// for logs with a referenced entity
.filter(auditLog -> auditLog.getReferencedEntity() != null)
// set previous and new objects
.forEach(auditLog -> {
ClassPK referencedClassPk = auditLog.getReferencedEntity();
LOG.trace("Loading referenced entity {}", referencedClassPk);
if (auditLog.getPreviousState() != null) {
auditLog.setPreviousEntity(auditLogRepository.get(referencedClassPk, NumberUtils.toLong(auditLog.getPreviousState())));
}
if (auditLog.getNewState() != null) {
auditLog.setNewEntity(auditLogRepository.get(referencedClassPk, NumberUtils.toLong(auditLog.getNewState())));
}
});
return auditLogs;
}
/* (non-Javadoc)
* @see org.genesys.blocks.auditlog.service.AuditTrailService#auditLogs(org.genesys.blocks.model.EntityId)
*/
@Override
public Map<String, List<AuditLog>> auditLogs(EntityId entity) {
Map<String, List<AuditLog>> logMap = new HashMap<>();
listAuditLogs(entity).stream().forEach(auditLog -> {
List<AuditLog> m = logMap.get(auditLog.getPropertyName());
if (m == null) {
logMap.put(auditLog.getPropertyName(), m = new ArrayList<>());
}
m.add(auditLog);
});
return logMap;
}
}
......@@ -18,6 +18,7 @@ package org.genesys.blocks.auditlog.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.genesys.blocks.auditlog.annotations.Audited;
......@@ -33,6 +34,9 @@ public class ExampleAuditedEntity extends BasicModel {
@Column(length = 10)
private String name;
@ManyToOne(optional = true)
private ExampleAuditedEntity reference;
public String getName() {
return name;
}
......@@ -40,4 +44,12 @@ public class ExampleAuditedEntity extends BasicModel {
public void setName(String name) {
this.name = name;
}
public void setReference(ExampleAuditedEntity refEntity) {
this.reference = refEntity;
}
public ExampleAuditedEntity getReference() {
return reference;
}
}
......@@ -31,6 +31,7 @@ import org.genesys.blocks.auditlog.model.AuditLog;
import org.genesys.blocks.auditlog.model.ExampleAuditedEntity;
import org.genesys.blocks.auditlog.persistence.ExampleAuditedEntityRepository;
import org.genesys.blocks.auditlog.test.ServiceTest;
import org.genesys.blocks.model.ClassPK;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
......@@ -150,4 +151,40 @@ public class AuditTrailServiceTest extends ServiceTest {
}
}
@Test
public void testLoadReferencedEntity() {
ExampleAuditedEntity entity = new ExampleAuditedEntity();
entity.setName("Test 1");
entity = exampleAuditedEntityService.save(entity);
ClassPK classPk = classPkService.getClassPk(ExampleAuditedEntity.class);
assertThat(auditLogRepository.get(classPk, null), is(nullValue()));
assertThat(auditLogRepository.get(classPk, -1l), is(nullValue()));
Object lookup = auditLogRepository.get(classPk, entity.getId());
assertThat(lookup, not(nullValue()));
assertThat(lookup.getClass(), equalTo(ExampleAuditedEntity.class));
assertThat(((ExampleAuditedEntity) lookup).getId(), is(entity.getId()));
}
@Test
public void testReferencedEntityAuditLog() {
ExampleAuditedEntity refEntity = new ExampleAuditedEntity();
refEntity.setName("Test 1");
refEntity = exampleAuditedEntityService.save(refEntity);
ExampleAuditedEntity entity = new ExampleAuditedEntity();
entity.setName("Test 2");
entity = exampleAuditedEntityService.save(entity);
entity.setReference(refEntity);
entity = exampleAuditedEntityService.save(entity);
assertThat(entity.getReference(), not(nullValue()));
assertThat(listAuditLogs(entity), hasSize(1));
assertThat(listAuditLogs(entity).get(0).getPreviousEntity(), is(nullValue()));
assertThat(listAuditLogs(entity).get(0).getNewEntity(), not(nullValue()));
assertThat(listAuditLogs(entity).get(0).getNewEntity().getClass(), equalTo(ExampleAuditedEntity.class));
assertThat(((ExampleAuditedEntity)listAuditLogs(entity).get(0).getNewEntity()).getId(), is(refEntity.getId()));
}
}
......@@ -23,6 +23,7 @@ import java.util.List;
import org.genesys.blocks.auditlog.model.AuditLog;
import org.genesys.blocks.auditlog.persistence.AuditLogRepository;
import org.genesys.blocks.auditlog.service.AuditTrailService;
import org.genesys.blocks.auditlog.service.ClassPKService;
import org.genesys.blocks.model.EntityId;
import org.genesys.blocks.persistence.ClassPKRepository;
......@@ -46,6 +47,9 @@ public abstract class BaseTest {
@Autowired
protected AuditLogRepository auditLogRepository;
@Autowired
protected AuditTrailService auditTrailService;
@Autowired
protected ClassPKRepository classPkRepository;
......@@ -72,7 +76,7 @@ public abstract class BaseTest {
}
protected List<AuditLog> listAuditLogs(final EntityId entity) {
return auditLogRepository.listAuditLogs(entity);
return auditTrailService.listAuditLogs(entity);
}
protected void printAuditLogs(final EntityId entity) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment