DATAMONGO-2586 - Polishing.

Add tests to ensure no reactive auditing callback is registered when using imperative configuration and vice versa.
Update wording and minor code style tweaks.

Original Pull Request: #877
This commit is contained in:
Christoph Strobl
2020-07-17 10:40:07 +02:00
parent 6bafcea539
commit a8a364c2de
4 changed files with 57 additions and 24 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2020 the original author or authors.
* Copyright 2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,8 @@ import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
*
* @author Oliver Gierke
* @author Mark Paluch
* @author Christoph Strobl
* @since 3.1
*/
class PersistentEntitiesFactoryBean implements FactoryBean<PersistentEntities> {
@@ -44,7 +46,7 @@ class PersistentEntitiesFactoryBean implements FactoryBean<PersistentEntities> {
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
@Override
public PersistentEntities getObject() throws Exception {
public PersistentEntities getObject() {
return PersistentEntities.of(converter.getMappingContext());
}
@@ -56,13 +58,4 @@ class PersistentEntitiesFactoryBean implements FactoryBean<PersistentEntities> {
public Class<?> getObjectType() {
return PersistentEntities.class;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
*/
@Override
public boolean isSingleton() {
return true;
}
}

View File

@@ -21,6 +21,7 @@ import static org.mockito.Mockito.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
@@ -34,12 +35,16 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.ResolvableType;
import org.springframework.data.annotation.Version;
import org.springframework.data.domain.AuditorAware;
import org.springframework.data.mapping.callback.EntityCallback;
import org.springframework.data.mongodb.core.AuditablePerson;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.event.AuditingEntityCallback;
import org.springframework.data.mongodb.core.mapping.event.ReactiveAuditingEntityCallback;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.data.mongodb.test.util.Client;
@@ -48,6 +53,7 @@ import org.springframework.data.mongodb.test.util.MongoTestUtils;
import org.springframework.stereotype.Repository;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.util.ReflectionTestUtils;
import com.mongodb.client.MongoClient;
@@ -60,7 +66,7 @@ import com.mongodb.client.MongoClient;
*/
@ExtendWith({ MongoClientExtension.class, SpringExtension.class })
@ContextConfiguration
public class AuditingViaJavaConfigRepositoriesTests {
class AuditingViaJavaConfigRepositoriesTests {
static @Client MongoClient mongoClient;
@@ -79,6 +85,7 @@ public class AuditingViaJavaConfigRepositoriesTests {
@Override
protected String getDatabaseName() {
return "database";
}
@@ -101,13 +108,13 @@ public class AuditingViaJavaConfigRepositoriesTests {
}
@BeforeEach
public void setup() {
void setup() {
auditablePersonRepository.deleteAll();
this.auditor = auditablePersonRepository.save(new AuditablePerson("auditor"));
}
@Test // DATAMONGO-792, DATAMONGO-883
public void basicAuditing() {
void basicAuditing() {
doReturn(Optional.of(this.auditor)).when(this.auditorAware).getCurrentAuditor();
@@ -122,18 +129,18 @@ public class AuditingViaJavaConfigRepositoriesTests {
@Test // DATAMONGO-843
@SuppressWarnings("resource")
public void auditingUsesFallbackMappingContextIfNoneConfiguredWithRepositories() {
void auditingUsesFallbackMappingContextIfNoneConfiguredWithRepositories() {
new AnnotationConfigApplicationContext(SimpleConfigWithRepositories.class);
}
@Test // DATAMONGO-843
@SuppressWarnings("resource")
public void auditingUsesFallbackMappingContextIfNoneConfigured() {
void auditingUsesFallbackMappingContextIfNoneConfigured() {
new AnnotationConfigApplicationContext(SimpleConfig.class);
}
@Test // DATAMONGO-2139
public void auditingWorksForVersionedEntityWithWrapperVersion() {
void auditingWorksForVersionedEntityWithWrapperVersion() {
verifyAuditingViaVersionProperty(new VersionedAuditablePerson(), //
it -> it.version, //
@@ -143,7 +150,7 @@ public class AuditingViaJavaConfigRepositoriesTests {
}
@Test // DATAMONGO-2179
public void auditingWorksForVersionedEntityBatchWithWrapperVersion() {
void auditingWorksForVersionedEntityBatchWithWrapperVersion() {
verifyAuditingViaVersionProperty(new VersionedAuditablePerson(), //
it -> it.version, //
@@ -153,7 +160,7 @@ public class AuditingViaJavaConfigRepositoriesTests {
}
@Test // DATAMONGO-2139
public void auditingWorksForVersionedEntityWithSimpleVersion() {
void auditingWorksForVersionedEntityWithSimpleVersion() {
verifyAuditingViaVersionProperty(new SimpleVersionedAuditablePerson(), //
it -> it.version, //
@@ -163,7 +170,7 @@ public class AuditingViaJavaConfigRepositoriesTests {
}
@Test // DATAMONGO-2139
public void auditingWorksForVersionedEntityWithWrapperVersionOnTemplate() {
void auditingWorksForVersionedEntityWithWrapperVersionOnTemplate() {
verifyAuditingViaVersionProperty(new VersionedAuditablePerson(), //
it -> it.version, //
@@ -173,7 +180,7 @@ public class AuditingViaJavaConfigRepositoriesTests {
}
@Test // DATAMONGO-2139
public void auditingWorksForVersionedEntityWithSimpleVersionOnTemplate() {
void auditingWorksForVersionedEntityWithSimpleVersionOnTemplate() {
verifyAuditingViaVersionProperty(new SimpleVersionedAuditablePerson(), //
it -> it.version, //
@@ -182,6 +189,19 @@ public class AuditingViaJavaConfigRepositoriesTests {
0L, 1L, 2L);
}
@Test // DATAMONGO-2586
void auditingShouldOnlyRegisterImperativeAuditingCallback() {
Object callbacks = ReflectionTestUtils.getField(operations, "entityCallbacks");
Object callbackDiscoverer = ReflectionTestUtils.getField(callbacks, "callbackDiscoverer");
List<EntityCallback<?>> actualCallbacks = ReflectionTestUtils.invokeMethod(callbackDiscoverer, "getEntityCallbacks",
AuditablePerson.class, ResolvableType.forClass(EntityCallback.class));
assertThat(actualCallbacks) //
.hasAtLeastOneElementOfType(AuditingEntityCallback.class) //
.doesNotHaveAnyElementsOfTypes(ReactiveAuditingEntityCallback.class);
}
private <T extends AuditablePerson> void verifyAuditingViaVersionProperty(T instance,
Function<T, Object> versionExtractor, Function<T, Object> createdDateExtractor, Function<T, T> persister,
Object... expectedValues) {

View File

@@ -17,12 +17,18 @@ package org.springframework.data.mongodb.config;
import static org.assertj.core.api.Assertions.*;
import org.springframework.core.ResolvableType;
import org.springframework.data.mapping.callback.EntityCallback;
import org.springframework.data.mongodb.core.mapping.event.AuditingEntityCallback;
import org.springframework.data.mongodb.core.mapping.event.ReactiveAuditingEntityCallback;
import org.springframework.test.util.ReflectionTestUtils;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
@@ -146,6 +152,19 @@ class ReactiveAuditingTests {
0L, 1L, 2L);
}
@Test // DATAMONGO-2586
void auditingShouldOnlyRegisterReactiveAuditingCallback() {
Object callbacks = ReflectionTestUtils.getField(operations, "entityCallbacks");
Object callbackDiscoverer = ReflectionTestUtils.getField(callbacks, "callbackDiscoverer");
List<EntityCallback<?>> actualCallbacks = ReflectionTestUtils.invokeMethod(callbackDiscoverer, "getEntityCallbacks",
AuditablePerson.class, ResolvableType.forClass(EntityCallback.class));
assertThat(actualCallbacks) //
.hasAtLeastOneElementOfType(ReactiveAuditingEntityCallback.class) //
.doesNotHaveAnyElementsOfTypes(AuditingEntityCallback.class);
}
private <T extends AuditablePerson> void verifyAuditingViaVersionProperty(T instance,
Function<T, Object> versionExtractor, Function<T, Object> createdDateExtractor, Function<T, Mono<T>> persister,
Object... expectedValues) {

View File

@@ -30,9 +30,10 @@ To activate auditing functionality via XML, add the Spring Data Mongo `auditing`
----
====
If you wish to use auditing with the reactive programming model, then enable auditing through `@EnableReactiveMongoAuditing`
To enable auditing, leveraging a reactive programming model, use the `@EnableReactiveMongoAuditing` annotation. +
If you expose a bean of type `ReactiveAuditorAware` to the `ApplicationContext`, the auditing infrastructure picks it up automatically and uses it to determine the current user to be set on domain types. If you have multiple implementations registered in the `ApplicationContext`, you can select the one to be used by explicitly setting the `auditorAwareRef` attribute of `@EnableReactiveMongoAuditing`.
.Activating auditing using JavaConfig
.Activating reactive auditing using JavaConfig
====
[source,java]
----
@@ -47,5 +48,5 @@ class Config {
}
----
====
If you expose a bean of type `ReactiveAuditorAware` to the `ApplicationContext`, the auditing infrastructure picks it up automatically and uses it to determine the current user to be set on domain types. If you have multiple implementations registered in the `ApplicationContext`, you can select the one to be used by explicitly setting the `auditorAwareRef` attribute of `@EnableReactiveMongoAuditing`.