Browse Source

Polishing.

Consistent ConfigurationSource usage across tests to avoid nullability.

See #5107
Original pull request: #5108
pull/4831/merge
Mark Paluch 6 days ago
parent
commit
942cca616e
No known key found for this signature in database
GPG Key ID: 55BC6374BAA9D973
  1. 22
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/aot/MongoRepositoryContributor.java
  2. 63
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/aot/AotFragmentTestConfigurationSupport.java
  3. 24
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/aot/MongoRepositoryContributorUnitTests.java
  4. 8
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/aot/MongoRepositoryMetadataTests.java
  5. 18
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/aot/TestMongoAotRepositoryContext.java

22
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/aot/MongoRepositoryContributor.java

@ -68,11 +68,11 @@ public class MongoRepositoryContributor extends RepositoryContributor { @@ -68,11 +68,11 @@ public class MongoRepositoryContributor extends RepositoryContributor {
private static final Log logger = LogFactory.getLog(MongoRepositoryContributor.class);
private final AotRepositoryContext repositoryContext;
private final AotQueryCreator queryCreator;
private final SimpleTypeHolder simpleTypeHolder;
private final MongoMappingContext mappingContext;
private final NamedQueries namedQueries;
private final @Nullable String mongoOperationsRef;
public MongoRepositoryContributor(AotRepositoryContext repositoryContext) {
@ -83,8 +83,8 @@ public class MongoRepositoryContributor extends RepositoryContributor { @@ -83,8 +83,8 @@ public class MongoRepositoryContributor extends RepositoryContributor {
classLoader = getClass().getClassLoader();
}
this.repositoryContext = repositoryContext;
this.namedQueries = getNamedQueries(repositoryContext.getConfigurationSource(), classLoader);
this.mongoOperationsRef = getMongoTemplateRef(repositoryContext.getConfigurationSource());
// avoid Java Time (JSR-310) Type introspection
MongoCustomConversions mongoCustomConversions = MongoCustomConversions
@ -100,14 +100,6 @@ public class MongoRepositoryContributor extends RepositoryContributor { @@ -100,14 +100,6 @@ public class MongoRepositoryContributor extends RepositoryContributor {
this.queryCreator = new AotQueryCreator(this.mappingContext);
}
private @Nullable String getMongoTemplateRef(@Nullable RepositoryConfigurationSource configSource) {
if (configSource == null) {
return null;
}
return configSource.getAttribute("mongoTemplateRef").filter(it -> !"mongoTemplate".equals(it)).orElse(null);
}
@SuppressWarnings("NullAway")
private NamedQueries getNamedQueries(@Nullable RepositoryConfigurationSource configSource, ClassLoader classLoader) {
@ -145,9 +137,10 @@ public class MongoRepositoryContributor extends RepositoryContributor { @@ -145,9 +137,10 @@ public class MongoRepositoryContributor extends RepositoryContributor {
constructorBuilder.addParameter("operations", MongoOperations.class, customizer -> {
String mongoOperationsRef = getMongoTemplateRef();
customizer.bindToField()
.origin(StringUtils.hasText(this.mongoOperationsRef)
? new RuntimeBeanReference(this.mongoOperationsRef, MongoOperations.class)
.origin(StringUtils.hasText(mongoOperationsRef)
? new RuntimeBeanReference(mongoOperationsRef, MongoOperations.class)
: new RuntimeBeanReference(MongoOperations.class));
});
@ -158,6 +151,11 @@ public class MongoRepositoryContributor extends RepositoryContributor { @@ -158,6 +151,11 @@ public class MongoRepositoryContributor extends RepositoryContributor {
});
}
private @Nullable String getMongoTemplateRef() {
return repositoryContext.getConfigurationSource().getAttribute("mongoTemplateRef")
.filter(it -> !"mongoTemplate".equals(it)).orElse(null);
}
@Override
@SuppressWarnings("NullAway")
protected @Nullable MethodContributor<? extends QueryMethod> contributeQueryMethod(Method method) {

63
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/aot/AotFragmentTestConfigurationSupport.java

@ -18,6 +18,8 @@ package org.springframework.data.mongodb.repository.aot; @@ -18,6 +18,8 @@ package org.springframework.data.mongodb.repository.aot;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.mockito.Mockito;
import org.springframework.aot.test.generate.TestGenerationContext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
@ -27,12 +29,26 @@ import org.springframework.beans.factory.config.RuntimeBeanReference; @@ -27,12 +29,26 @@ import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultBeanNameGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.test.tools.TestCompiler;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.expression.ValueExpressionParser;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource;
import org.springframework.data.repository.config.RepositoryConfigurationSource;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
import org.springframework.data.repository.query.QueryMethodValueEvaluationContextAccessor;
@ -53,23 +69,54 @@ import org.springframework.util.ReflectionUtils; @@ -53,23 +69,54 @@ import org.springframework.util.ReflectionUtils;
public class AotFragmentTestConfigurationSupport implements BeanFactoryPostProcessor {
private final Class<?> repositoryInterface;
private final RepositoryConfigurationSource configSource;
private final boolean registerFragmentFacade;
public AotFragmentTestConfigurationSupport(Class<?> repositoryInterface) {
this(repositoryInterface, true);
this(repositoryInterface, SampleConfiguration.class, true);
}
public AotFragmentTestConfigurationSupport(Class<?> repositoryInterface, Class<?> configClass) {
this(repositoryInterface, configClass, true);
}
public AotFragmentTestConfigurationSupport(Class<?> repositoryInterface, boolean registerFragmentFacade) {
this(repositoryInterface, SampleConfiguration.class, registerFragmentFacade);
}
public AotFragmentTestConfigurationSupport(Class<?> repositoryInterface, Class<?> configClass,
boolean registerFragmentFacade) {
this.repositoryInterface = repositoryInterface;
this.registerFragmentFacade = registerFragmentFacade;
this.configSource = new AnnotationRepositoryConfigurationSource(AnnotationMetadata.introspect(configClass),
EnableMongoRepositories.class, new DefaultResourceLoader(), new StandardEnvironment(),
Mockito.mock(BeanDefinitionRegistry.class), DefaultBeanNameGenerator.INSTANCE);
}
@Bean
MongoCustomConversions customConversions() {
return MongoCustomConversions.create(adapter -> adapter.useSpringDataJavaTimeCodecs());
}
@Bean
MongoMappingContext mongoMappingContext(MongoCustomConversions conversions) {
MongoMappingContext context = new MongoMappingContext();
context.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
return context;
}
@Bean
MongoConverter mongoConverter(MongoMappingContext context, MongoCustomConversions conversions) {
MappingMongoConverter converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, context);
converter.setCustomConversions(conversions);
return converter;
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
TestMongoAotRepositoryContext repositoryContext = new TestMongoAotRepositoryContext(beanFactory,
repositoryInterface, null);
TestMongoAotRepositoryContext repositoryContext = getRepositoryContext(beanFactory);
TestGenerationContext generationContext = new TestGenerationContext(repositoryInterface);
new MongoRepositoryContributor(repositoryContext).contribute(generationContext);
@ -101,6 +148,10 @@ public class AotFragmentTestConfigurationSupport implements BeanFactoryPostProce @@ -101,6 +148,10 @@ public class AotFragmentTestConfigurationSupport implements BeanFactoryPostProce
beanFactory.registerSingleton("generationContext", generationContext);
}
public TestMongoAotRepositoryContext getRepositoryContext(ConfigurableListableBeanFactory beanFactory) {
return new TestMongoAotRepositoryContext(beanFactory, repositoryInterface, configSource);
}
private Object getFragmentFacadeProxy(Object fragment) {
return Proxy.newProxyInstance(repositoryInterface.getClassLoader(), new Class<?>[] { repositoryInterface },
@ -157,4 +208,10 @@ public class AotFragmentTestConfigurationSupport implements BeanFactoryPostProce @@ -157,4 +208,10 @@ public class AotFragmentTestConfigurationSupport implements BeanFactoryPostProce
}
}
@EnableMongoRepositories(considerNestedRepositories = true, includeFilters = {
@ComponentScan.Filter(classes = SampleConfiguration.class, type = FilterType.ASSIGNABLE_TYPE) })
public static class SampleConfiguration {
}
}

24
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/aot/MongoRepositoryContributorUnitTests.java

@ -15,8 +15,8 @@ @@ -15,8 +15,8 @@
*/
package org.springframework.data.mongodb.repository.aot;
import static org.mockito.Mockito.mock;
import static org.springframework.data.mongodb.test.util.Assertions.assertThat;
import static org.mockito.Mockito.*;
import static org.springframework.data.mongodb.test.util.Assertions.*;
import example.aot.User;
import example.aot.UserRepository;
@ -25,15 +25,20 @@ import java.io.IOException; @@ -25,15 +25,20 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import org.junit.jupiter.api.Test;
import org.springframework.aot.generate.GeneratedFiles;
import org.springframework.aot.test.generate.TestGenerationContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.InputStreamSource;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.repository.Meta;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.data.repository.CrudRepository;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
@ -47,15 +52,19 @@ import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; @@ -47,15 +52,19 @@ import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
class MongoRepositoryContributorUnitTests {
@Configuration
@EnableMongoRepositories(considerNestedRepositories = true, mongoTemplateRef = "mongoOperations",
includeFilters = { @ComponentScan.Filter(classes = MetaUserRepository.class, type = FilterType.ASSIGNABLE_TYPE) })
static class MongoRepositoryContributorConfiguration extends AotFragmentTestConfigurationSupport {
public MongoRepositoryContributorConfiguration() {
super(MetaUserRepository.class);
super(MetaUserRepository.class, MongoRepositoryContributorConfiguration.class);
}
@Bean
MongoOperations mongoOperations() {
return mock(MongoOperations.class);
MongoOperations mongoOperations(MongoConverter mongoConverter) {
MongoOperations operations = mock(MongoOperations.class);
when(operations.getConverter()).thenReturn(mongoConverter);
return operations;
}
}
@ -66,7 +75,8 @@ class MongoRepositoryContributorUnitTests { @@ -66,7 +75,8 @@ class MongoRepositoryContributorUnitTests {
void shouldConsiderMetaAnnotation() throws IOException {
InputStreamSource aotFragment = generationContext.getGeneratedFiles().getGeneratedFile(GeneratedFiles.Kind.SOURCE,
MetaUserRepository.class.getPackageName().replace('.', '/') + "/MetaUserRepositoryImpl__AotRepository.java");
AotFragmentTestConfigurationSupport.getAotImplFragmentName(MetaUserRepository.class).replace('.', '/')
+ ".java");
String content = new InputStreamResource(aotFragment).getContentAsString(StandardCharsets.UTF_8);
@ -76,7 +86,7 @@ class MongoRepositoryContributorUnitTests { @@ -76,7 +86,7 @@ class MongoRepositoryContributorUnitTests {
assertThat(content).contains("filterQuery.diskUse(DiskUse.DENY)");
}
interface MetaUserRepository extends CrudRepository<User, String> {
public interface MetaUserRepository extends CrudRepository<User, String> {
@Meta
User findAllByLastname(String lastname);

8
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/aot/MongoRepositoryMetadataTests.java

@ -34,6 +34,7 @@ import org.springframework.context.support.AbstractApplicationContext; @@ -34,6 +34,7 @@ import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
/**
@ -41,7 +42,6 @@ import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; @@ -41,7 +42,6 @@ import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
*
* @author Mark Paluch
*/
@SpringJUnitConfig(classes = MongoRepositoryMetadataTests.MongoRepositoryContributorConfiguration.class)
class MongoRepositoryMetadataTests {
@ -53,8 +53,10 @@ class MongoRepositoryMetadataTests { @@ -53,8 +53,10 @@ class MongoRepositoryMetadataTests {
}
@Bean
MongoOperations mongoOperations() {
return mock(MongoOperations.class);
MongoOperations mongoOperations(MongoConverter mongoConverter) {
MongoOperations operations = mock(MongoOperations.class);
when(operations.getConverter()).thenReturn(mongoConverter);
return operations;
}
}

18
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/aot/TestMongoAotRepositoryContext.java

@ -18,8 +18,6 @@ package org.springframework.data.mongodb.repository.aot; @@ -18,8 +18,6 @@ package org.springframework.data.mongodb.repository.aot;
import java.lang.annotation.Annotation;
import java.util.Set;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.env.StandardEnvironment;
@ -41,21 +39,20 @@ import org.springframework.data.repository.core.support.RepositoryComposition; @@ -41,21 +39,20 @@ import org.springframework.data.repository.core.support.RepositoryComposition;
public class TestMongoAotRepositoryContext extends AotRepositoryContextSupport {
private final AotRepositoryInformation repositoryInformation;
private final Class<?> repositoryInterface;
private final RepositoryConfigurationSource configurationSource;
public TestMongoAotRepositoryContext(BeanFactory beanFactory, Class<?> repositoryInterface,
@Nullable RepositoryComposition composition) {
super(AotContext.from(beanFactory, new StandardEnvironment()));
RepositoryConfigurationSource configurationSource) {
this.repositoryInterface = repositoryInterface;
super(AotContext.from(beanFactory, new StandardEnvironment()));
RepositoryMetadata metadata = AnnotationRepositoryMetadata.getMetadata(repositoryInterface);
RepositoryComposition.RepositoryFragments fragments = MongoRepositoryFragmentsContributor.DEFAULT
.describe(metadata);
this.repositoryInformation = new AotRepositoryInformation(metadata, SimpleMongoRepository.class,
fragments.stream().toList());
this.configurationSource = configurationSource;
}
@Override
@ -65,12 +62,7 @@ public class TestMongoAotRepositoryContext extends AotRepositoryContextSupport { @@ -65,12 +62,7 @@ public class TestMongoAotRepositoryContext extends AotRepositoryContextSupport {
@Override
public RepositoryConfigurationSource getConfigurationSource() {
return null;
}
@Override
public Set<String> getBasePackages() {
return Set.of(repositoryInterface.getPackageName());
return configurationSource;
}
@Override

Loading…
Cancel
Save