DATACOUCH-91 - Support auditing (via java config)
This commit adds support for auditing via the use of the four annotations (CreatedBy, LastModifiedBy, CreationDate, LastModificationDate), enabled via the EnableCouchbaseAuditing annotation. As couchbase entities MUST have an id, the only case where the creation event can be detected is when the entity has a Version annotated field.
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
package org.springframework.data.couchbase.repository.auditing;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.couchbase.IntegrationTestApplicationConfig;
|
||||
import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories;
|
||||
|
||||
@Configuration
|
||||
@EnableCouchbaseRepositories
|
||||
@EnableCouchbaseAuditing(modifyOnCreate = false)
|
||||
public class AuditedApplicationConfig extends IntegrationTestApplicationConfig {
|
||||
|
||||
@Bean
|
||||
public AuditedAuditorAware couchbaseAuditorAware() {
|
||||
return new AuditedAuditorAware();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.springframework.data.couchbase.repository.auditing;
|
||||
|
||||
import org.springframework.data.domain.AuditorAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
public class AuditedAuditorAware implements AuditorAware<String> {
|
||||
|
||||
private String auditor = "auditor";
|
||||
|
||||
@Override
|
||||
public String getCurrentAuditor() {
|
||||
return auditor;
|
||||
}
|
||||
|
||||
public void setAuditor(String auditor) {
|
||||
this.auditor = auditor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
package org.springframework.data.couchbase.repository.auditing;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.springframework.data.annotation.CreatedBy;
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.LastModifiedBy;
|
||||
import org.springframework.data.annotation.LastModifiedDate;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.couchbase.core.mapping.Document;
|
||||
|
||||
@Document
|
||||
public class AuditedItem {
|
||||
|
||||
@Id
|
||||
private final String id;
|
||||
|
||||
private String value;
|
||||
|
||||
@CreatedBy
|
||||
private String creator;
|
||||
|
||||
@LastModifiedBy
|
||||
private String lastModifiedBy;
|
||||
|
||||
@LastModifiedDate
|
||||
private Date lastModification;
|
||||
|
||||
@CreatedDate
|
||||
private Date creationDate;
|
||||
|
||||
@Version
|
||||
private long version;
|
||||
|
||||
public AuditedItem(String id, String value) {
|
||||
this.id = id;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getCreator() {
|
||||
return creator;
|
||||
}
|
||||
|
||||
public void setCreator(String creator) {
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
public String getLastModifiedBy() {
|
||||
return lastModifiedBy;
|
||||
}
|
||||
|
||||
public void setLastModifiedBy(String lastModifiedBy) {
|
||||
this.lastModifiedBy = lastModifiedBy;
|
||||
}
|
||||
|
||||
public Date getLastModification() {
|
||||
return lastModification;
|
||||
}
|
||||
|
||||
public void setLastModification(Date lastModification) {
|
||||
this.lastModification = lastModification;
|
||||
}
|
||||
|
||||
public Date getCreationDate() {
|
||||
return creationDate;
|
||||
}
|
||||
|
||||
public void setCreationDate(Date creationDate) {
|
||||
this.creationDate = creationDate;
|
||||
}
|
||||
|
||||
public long getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(long version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AuditedItem{" +
|
||||
"id='" + id + '\'' +
|
||||
", value='" + value + '\'' +
|
||||
", creator='" + creator + '\'' +
|
||||
", lastModifiedBy='" + lastModifiedBy + '\'' +
|
||||
", lastModification=" + lastModification +
|
||||
", creationDate=" + creationDate +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
AuditedItem that = (AuditedItem) o;
|
||||
|
||||
if (!id.equals(that.id)) return false;
|
||||
if (!value.equals(that.value)) return false;
|
||||
if (creator != null ? !creator.equals(that.creator) : that.creator != null) return false;
|
||||
if (lastModifiedBy != null ? !lastModifiedBy.equals(that.lastModifiedBy) : that.lastModifiedBy != null)
|
||||
return false;
|
||||
if (lastModification != null ? !lastModification.equals(that.lastModification) : that.lastModification != null)
|
||||
return false;
|
||||
return creationDate != null ? creationDate.equals(that.creationDate) : that.creationDate == null;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = id.hashCode();
|
||||
result = 31 * result + value.hashCode();
|
||||
result = 31 * result + (creator != null ? creator.hashCode() : 0);
|
||||
result = 31 * result + (lastModifiedBy != null ? lastModifiedBy.hashCode() : 0);
|
||||
result = 31 * result + (lastModification != null ? lastModification.hashCode() : 0);
|
||||
result = 31 * result + (creationDate != null ? creationDate.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.springframework.data.couchbase.repository.auditing;
|
||||
|
||||
import org.springframework.data.couchbase.repository.CouchbaseRepository;
|
||||
|
||||
public interface AuditedRepository extends CouchbaseRepository<AuditedItem, String> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package org.springframework.data.couchbase.repository.auditing;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
import org.springframework.data.couchbase.repository.CouchbaseRepository;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Simon Baslé
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = AuditedApplicationConfig.class)
|
||||
public class AuditingTests {
|
||||
|
||||
@Autowired
|
||||
private AuditedRepository repository;
|
||||
|
||||
@Autowired
|
||||
private AuditedAuditorAware auditorAware;
|
||||
|
||||
private static final String KEY = "auditedTest";
|
||||
|
||||
@After
|
||||
public void cleanupAuditedEntity() {
|
||||
repository.getCouchbaseOperations().getCouchbaseBucket().remove(KEY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreationEventIsRegistered() {
|
||||
assertFalse(repository.exists(KEY));
|
||||
Date start = new Date();
|
||||
AuditedItem item = new AuditedItem(KEY, "creation");
|
||||
|
||||
auditorAware.setAuditor("auditor");
|
||||
repository.save(item);
|
||||
AuditedItem persisted = repository.findOne(KEY);
|
||||
|
||||
assertNotNull("expected entity to be persisted", persisted);
|
||||
assertNotNull("expected creation date audit trail", persisted.getCreationDate());
|
||||
assertEquals("expected creation user audit trail", "auditor", persisted.getCreator());
|
||||
|
||||
assertTrue("creation date is too early", persisted.getCreationDate().after(start));
|
||||
assertTrue("creation date is too late", persisted.getCreationDate().before(new Date()));
|
||||
|
||||
assertNull("expected modification date to be empty", persisted.getLastModification());
|
||||
assertNull("expected modification user to be empty", persisted.getLastModifiedBy());
|
||||
|
||||
assertNotNull("expected version to be non null", persisted.getVersion());
|
||||
assertTrue("expected version to be greater than 0", persisted.getVersion() > 0L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateEventIsRegistered() {
|
||||
assertFalse(repository.exists(KEY));
|
||||
|
||||
String expectedCreator = "user1";
|
||||
String expectedUpdater = "user2";
|
||||
AuditedItem item = new AuditedItem(KEY, "creation");
|
||||
auditorAware.setAuditor(expectedCreator);
|
||||
|
||||
repository.save(item);
|
||||
AuditedItem created = repository.findOne(KEY);
|
||||
|
||||
auditorAware.setAuditor(expectedUpdater);
|
||||
repository.save(item);
|
||||
AuditedItem updated = repository.findOne(KEY);
|
||||
|
||||
assertNotNull("expected entity to be persisted", updated);
|
||||
assertNotNull("expected creation date audit trail", updated.getCreationDate());
|
||||
assertEquals("expected creation user audit trail", expectedCreator, updated.getCreator());
|
||||
|
||||
assertNotNull("expected modification date audit trail", updated.getLastModification());
|
||||
assertTrue("expected modification date to be after creation date", updated.getCreationDate().before(updated.getLastModification()));
|
||||
assertEquals("expected modification user to be the modifier", expectedUpdater, updated.getLastModifiedBy());
|
||||
|
||||
assertNotNull("expected version to be non null", updated.getVersion());
|
||||
assertTrue("expected version to be greater than 0", updated.getVersion() > 0L);
|
||||
assertTrue("expected updated version to be different from the one at creation", created.getVersion() != updated.getVersion());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user