DATACMNS-1322 - Adapt auditing handler API to support immutable entities.

We've changed the APIs in the auditing subsystem so that we support immutable entities, mostly through MappingAuditableBeanWrapperFactory that uses a PersistentPropertyAccessor.
This commit is contained in:
Oliver Gierke
2018-06-18 15:16:35 +02:00
parent 85b507ce10
commit 6cb3587ba3
8 changed files with 109 additions and 79 deletions

View File

@@ -23,7 +23,6 @@ import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalField;
import java.util.Optional;
import org.junit.Test;
@@ -31,7 +30,6 @@ import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.auditing.DefaultAuditableBeanWrapperFactory.AuditableInterfaceBeanWrapper;
import org.springframework.data.auditing.DefaultAuditableBeanWrapperFactory.ReflectionAuditingBeanWrapper;
import org.springframework.data.domain.Auditable;
/**
* Unit tests for {@link DefaultAuditableBeanWrapperFactory}.
@@ -75,7 +73,7 @@ public class DefaultAuditableBeanWrapperFactoryUnitTests {
Jsr310ThreeTenBpAuditedUser user = new Jsr310ThreeTenBpAuditedUser();
Instant instant = Instant.now();
Optional<AuditableBeanWrapper> wrapper = factory.getBeanWrapperFor(user);
Optional<AuditableBeanWrapper<Jsr310ThreeTenBpAuditedUser>> wrapper = factory.getBeanWrapperFor(user);
assertThat(wrapper).hasValueSatisfying(it -> {
@@ -93,7 +91,7 @@ public class DefaultAuditableBeanWrapperFactoryUnitTests {
Jsr310ThreeTenBpAuditedUser user = new Jsr310ThreeTenBpAuditedUser();
ZonedDateTime zonedDateTime = ZonedDateTime.now();
Optional<AuditableBeanWrapper> wrapper = factory.getBeanWrapperFor(user);
Optional<AuditableBeanWrapper<Jsr310ThreeTenBpAuditedUser>> wrapper = factory.getBeanWrapperFor(user);
assertThat(wrapper).hasValueSatisfying(it -> it.setLastModifiedDate(zonedDateTime));
}
@@ -104,21 +102,19 @@ public class DefaultAuditableBeanWrapperFactoryUnitTests {
LongBasedAuditable source = new LongBasedAuditable();
source.dateModified = 42000L;
Optional<AuditableBeanWrapper> beanWrapper = factory.getBeanWrapperFor(source);
assertThat(beanWrapper).isPresent();
Optional<Long> result = factory.getBeanWrapperFor(source) //
.flatMap(AuditableBeanWrapper::getLastModifiedDate) //
.map(ta -> ta.getLong(ChronoField.INSTANT_SECONDS));
assertThat(beanWrapper.flatMap(AuditableBeanWrapper::getLastModifiedDate).get()) //
.extracting(ta -> ta.getLong(ChronoField.INSTANT_SECONDS)) //
.containsExactly(42L);
assertThat(result).hasValue(42L);
}
@Test // DATACMNS-1259
public void canSetLastModifiedDateAsInstantViaWrapperOnLongField() {
LongBasedAuditable source = new LongBasedAuditable();
Optional<AuditableBeanWrapper> beanWrapper = factory.getBeanWrapperFor(source);
Optional<AuditableBeanWrapper<LongBasedAuditable>> beanWrapper = factory.getBeanWrapperFor(source);
assertThat(beanWrapper).isPresent();
beanWrapper.get().setLastModifiedDate(Instant.ofEpochMilli(42L));
@@ -131,15 +127,14 @@ public class DefaultAuditableBeanWrapperFactoryUnitTests {
LongBasedAuditable source = new LongBasedAuditable();
Optional<AuditableBeanWrapper> beanWrapper = factory.getBeanWrapperFor(source);
assertThat(beanWrapper).isPresent();
Optional<Long> result = factory.getBeanWrapperFor(source).map(it -> {
it.setLastModifiedDate(LocalDateTime.ofInstant(Instant.ofEpochMilli(42L), ZoneOffset.systemDefault()));
return it.getBean().dateModified;
});
beanWrapper.get().setLastModifiedDate(LocalDateTime.ofInstant(Instant.ofEpochMilli(42L), ZoneOffset.systemDefault()));
assertThat(source.dateModified).isEqualTo(42L);
assertThat(result).hasValue(42L);
}
@Test // DATACMNS-1259
public void lastModifiedAsLocalDateTimeDateIsAvailableViaWrapperAsLocalDateTime() {
@@ -148,19 +143,16 @@ public class DefaultAuditableBeanWrapperFactoryUnitTests {
AuditedUser source = new AuditedUser();
source.setLastModifiedDate(now);
Optional<AuditableBeanWrapper> beanWrapper = factory.getBeanWrapperFor(source);
assertThat(beanWrapper).isPresent();
Optional<TemporalAccessor> result = factory.getBeanWrapperFor(source) //
.flatMap(AuditableBeanWrapper::getLastModifiedDate);
assertThat(beanWrapper.flatMap(AuditableBeanWrapper::getLastModifiedDate).get()) //
.isEqualTo(now);
assertThat(result).hasValue(now);
}
public static class LongBasedAuditable {
@CreatedDate
public Long dateCreated;
@CreatedDate public Long dateCreated;
@LastModifiedDate
public Long dateModified;
@LastModifiedDate public Long dateModified;
}
}

View File

@@ -71,12 +71,12 @@ public class MappingAuditableBeanWrapperFactoryUnitTests {
Sample sample = new Sample();
Optional<AuditableBeanWrapper> wrapper = factory.getBeanWrapperFor(sample);
Optional<AuditableBeanWrapper<Sample>> wrapper = factory.getBeanWrapperFor(sample);
assertThat(wrapper).hasValueSatisfying(it -> {
it.setCreatedBy(Optional.of("Me!"));
assertThat(sample.createdBy).isNotNull();
assertThat(it.getBean().createdBy).isNotNull();
});
}
@@ -85,12 +85,12 @@ public class MappingAuditableBeanWrapperFactoryUnitTests {
Sample sample = new Sample();
Optional<AuditableBeanWrapper> wrapper = factory.getBeanWrapperFor(sample);
Optional<AuditableBeanWrapper<Sample>> wrapper = factory.getBeanWrapperFor(sample);
assertThat(wrapper).hasValueSatisfying(it -> {
it.setLastModifiedBy(Optional.of("Me, too!"));
assertThat(sample.lastModifiedBy).isNotNull();
assertThat(it.getBean().lastModifiedBy).isNotNull();
});
}
@@ -99,7 +99,7 @@ public class MappingAuditableBeanWrapperFactoryUnitTests {
Sample sample = new Sample();
Optional<AuditableBeanWrapper> wrapper = factory.getBeanWrapperFor(sample);
Optional<AuditableBeanWrapper<Sample>> wrapper = factory.getBeanWrapperFor(sample);
assertThat(wrapper).hasValueSatisfying(it -> it.setLastModifiedDate(Instant.now()));
}
@@ -169,8 +169,10 @@ public class MappingAuditableBeanWrapperFactoryUnitTests {
SampleWithInstant sample = new SampleWithInstant();
sample.modified = Instant.now();
Optional<AuditableBeanWrapper> wrapper = factory.getBeanWrapperFor(sample);
assertThat(wrapper.flatMap(it -> it.getLastModifiedDate())).hasValue(sample.modified);
Optional<TemporalAccessor> result = factory.getBeanWrapperFor(sample) //
.flatMap(it -> it.getLastModifiedDate());
assertThat(result).hasValue(sample.modified);
}
@Test // DATACMNS-1259
@@ -187,7 +189,7 @@ public class MappingAuditableBeanWrapperFactoryUnitTests {
WithEmbedded target = new WithEmbedded();
target.embedded = new Embedded();
Optional<AuditableBeanWrapper> wrapper = factory.getBeanWrapperFor(target);
Optional<AuditableBeanWrapper<WithEmbedded>> wrapper = factory.getBeanWrapperFor(target);
assertThat(wrapper).hasValueSatisfying(it -> {
@@ -199,7 +201,7 @@ public class MappingAuditableBeanWrapperFactoryUnitTests {
it.setLastModifiedDate(now);
it.setCreatedDate(now);
Embedded embedded = target.embedded;
Embedded embedded = it.getBean().embedded;
assertThat(embedded.created).isEqualTo(now);
assertThat(embedded.creator).isEqualTo(user);
@@ -215,11 +217,10 @@ public class MappingAuditableBeanWrapperFactoryUnitTests {
Sample sample = new Sample();
sample.lastModifiedDate = source;
Optional<AuditableBeanWrapper> wrapper = factory.getBeanWrapperFor(sample);
Optional<TemporalAccessor> result = factory.getBeanWrapperFor(sample) //
.flatMap(it -> it.getLastModifiedDate());
assertThat(wrapper.flatMap(it -> it.getLastModifiedDate())).hasValueSatisfying(ta -> {
compareTemporalAccessors(expected, ta);
});
assertThat(result).hasValueSatisfying(ta -> compareTemporalAccessors(expected, ta));
}
private static AbstractLongAssert<?> compareTemporalAccessors(TemporalAccessor expected, TemporalAccessor actual) {