7 changed files with 0 additions and 451 deletions
@ -1,87 +0,0 @@
@@ -1,87 +0,0 @@
|
||||
/* |
||||
* Copyright 2022 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mongodb.aot; |
||||
|
||||
import static org.assertj.core.api.Assertions.*; |
||||
import static org.springframework.data.mongodb.aot.RepositoryRegistrationAotContributionAssert.*; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
import org.springframework.aot.hint.RuntimeHints; |
||||
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution; |
||||
import org.springframework.beans.factory.config.BeanDefinition; |
||||
import org.springframework.beans.factory.support.RegisteredBean; |
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext; |
||||
import org.springframework.core.annotation.SynthesizedAnnotation; |
||||
import org.springframework.data.annotation.LastModifiedDate; |
||||
import org.springframework.data.annotation.Transient; |
||||
import org.springframework.data.aot.RepositoryRegistrationAotContribution; |
||||
import org.springframework.data.mongodb.aot.configs.ImperativeConfig; |
||||
import org.springframework.data.mongodb.core.convert.LazyLoadingProxy; |
||||
import org.springframework.data.mongodb.core.mapping.Address; |
||||
import org.springframework.data.mongodb.core.mapping.DBRef; |
||||
import org.springframework.data.mongodb.core.mapping.Document; |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
* @since 2022/04 |
||||
*/ |
||||
public class AotMongoRepositoryPostProcessorUnitTests { |
||||
|
||||
@Test |
||||
void contributesProxiesForDataAnnotations() { |
||||
|
||||
RepositoryRegistrationAotContribution repositoryBeanContribution = computeConfiguration(ImperativeConfig.class) |
||||
.forRepository(ImperativeConfig.PersonRepository.class); |
||||
|
||||
assertThatContribution(repositoryBeanContribution) //
|
||||
.codeContributionSatisfies(contribution -> { |
||||
|
||||
contribution.contributesJdkProxy(Transient.class, SynthesizedAnnotation.class); |
||||
contribution.contributesJdkProxy(LastModifiedDate.class, SynthesizedAnnotation.class); |
||||
contribution.contributesJdkProxy(Document.class, SynthesizedAnnotation.class); |
||||
contribution.contributesJdkProxy(DBRef.class, SynthesizedAnnotation.class); |
||||
}); |
||||
} |
||||
|
||||
BeanContributionBuilder computeConfiguration(Class<?> configuration) { |
||||
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); |
||||
ctx.register(configuration); |
||||
ctx.refreshForAotProcessing(new RuntimeHints()); |
||||
|
||||
return it -> { |
||||
|
||||
String[] repoBeanNames = ctx.getBeanNamesForType(it); |
||||
assertThat(repoBeanNames).describedAs("Unable to find repository %s in configuration %s.", it, configuration) |
||||
.hasSize(1); |
||||
|
||||
String beanName = repoBeanNames[0]; |
||||
|
||||
AotMongoRepositoryPostProcessor postProcessor = ctx.getBean(AotMongoRepositoryPostProcessor.class); |
||||
|
||||
postProcessor.setBeanFactory(ctx.getDefaultListableBeanFactory()); |
||||
|
||||
BeanRegistrationAotContribution beanRegistrationAotContribution = postProcessor |
||||
.processAheadOfTime(RegisteredBean.of(ctx.getBeanFactory(), beanName)); |
||||
assertThat(beanRegistrationAotContribution).isInstanceOf(RepositoryRegistrationAotContribution.class); |
||||
return (RepositoryRegistrationAotContribution) beanRegistrationAotContribution; |
||||
}; |
||||
} |
||||
|
||||
interface BeanContributionBuilder { |
||||
RepositoryRegistrationAotContribution forRepository(Class<?> repositoryInterface); |
||||
} |
||||
} |
||||
@ -1,103 +0,0 @@
@@ -1,103 +0,0 @@
|
||||
/* |
||||
* Copyright 2022 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mongodb.aot; |
||||
|
||||
import static org.assertj.core.api.Assertions.*; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.stream.Stream; |
||||
|
||||
import org.assertj.core.api.AbstractAssert; |
||||
import org.springframework.aot.generate.GenerationContext; |
||||
import org.springframework.aot.hint.JdkProxyHint; |
||||
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
* @since 2022/04 |
||||
*/ |
||||
public class CodeContributionAssert extends AbstractAssert<CodeContributionAssert, GenerationContext> { |
||||
|
||||
public CodeContributionAssert(GenerationContext contribution) { |
||||
super(contribution, CodeContributionAssert.class); |
||||
} |
||||
|
||||
public CodeContributionAssert contributesReflectionFor(Class<?>... types) { |
||||
|
||||
for (Class<?> type : types) { |
||||
assertThat(this.actual.getRuntimeHints()) |
||||
.describedAs("No reflection entry found for [%s]", type) |
||||
.matches(RuntimeHintsPredicates.reflection().onType(type)); |
||||
} |
||||
|
||||
return this; |
||||
} |
||||
|
||||
public CodeContributionAssert doesNotContributeReflectionFor(Class<?>... types) { |
||||
|
||||
for (Class<?> type : types) { |
||||
assertThat(this.actual.getRuntimeHints()) |
||||
.describedAs("Reflection entry found for [%s]", type) |
||||
.matches(RuntimeHintsPredicates.reflection().onType(type).negate()); |
||||
} |
||||
|
||||
return this; |
||||
} |
||||
|
||||
public CodeContributionAssert contributesJdkProxyFor(Class<?> entryPoint) { |
||||
|
||||
assertThat(jdkProxiesFor(entryPoint).findFirst()) |
||||
.describedAs("No JDK proxy found for [%s]", entryPoint) |
||||
.isPresent(); |
||||
|
||||
return this; |
||||
} |
||||
|
||||
public CodeContributionAssert doesNotContributeJdkProxyFor(Class<?> entryPoint) { |
||||
|
||||
assertThat(jdkProxiesFor(entryPoint).findFirst()) |
||||
.describedAs("Found JDK proxy matching [%s] though it should not be present", entryPoint) |
||||
.isNotPresent(); |
||||
|
||||
return this; |
||||
} |
||||
|
||||
public CodeContributionAssert contributesJdkProxy(Class<?>... proxyInterfaces) { |
||||
|
||||
assertThat(jdkProxiesFor(proxyInterfaces[0])) |
||||
.describedAs("Unable to find JDK proxy matching [%s]", Arrays.asList(proxyInterfaces)) |
||||
.anySatisfy(it -> new JdkProxyAssert(it).matches(proxyInterfaces)); |
||||
|
||||
return this; |
||||
} |
||||
|
||||
public CodeContributionAssert doesNotContributeJdkProxy(Class<?>... proxyInterfaces) { |
||||
|
||||
assertThat(jdkProxiesFor(proxyInterfaces[0])) |
||||
.describedAs("Found JDK proxy matching [%s] though it should not be present", |
||||
Arrays.asList(proxyInterfaces)) |
||||
.noneSatisfy(it -> new JdkProxyAssert(it).matches(proxyInterfaces)); |
||||
|
||||
return this; |
||||
} |
||||
|
||||
private Stream<JdkProxyHint> jdkProxiesFor(Class<?> entryPoint) { |
||||
|
||||
return this.actual.getRuntimeHints().proxies().jdkProxies() |
||||
.filter(jdkProxyHint -> jdkProxyHint.getProxiedInterfaces().get(0).getCanonicalName() |
||||
.equals(entryPoint.getCanonicalName())); |
||||
} |
||||
} |
||||
@ -1,46 +0,0 @@
@@ -1,46 +0,0 @@
|
||||
/* |
||||
* Copyright 2022 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mongodb.aot; |
||||
|
||||
import static org.assertj.core.api.Assertions.*; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
|
||||
import org.assertj.core.api.AbstractAssert; |
||||
import org.springframework.aot.hint.JdkProxyHint; |
||||
import org.springframework.aot.hint.TypeReference; |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
* @since 2022/04 |
||||
*/ |
||||
public class JdkProxyAssert extends AbstractAssert<JdkProxyAssert, JdkProxyHint> { |
||||
|
||||
public JdkProxyAssert(JdkProxyHint jdkProxyHint) { |
||||
super(jdkProxyHint, JdkProxyAssert.class); |
||||
} |
||||
|
||||
public void matches(Class<?>... proxyInterfaces) { |
||||
assertThat(actual.getProxiedInterfaces().stream().map(TypeReference::getCanonicalName)) |
||||
.containsExactly(Arrays.stream(proxyInterfaces).map(Class::getCanonicalName).toArray(String[]::new)); |
||||
} |
||||
|
||||
public List<TypeReference> getProxiedInterfaces() { |
||||
return actual.getProxiedInterfaces(); |
||||
} |
||||
|
||||
} |
||||
@ -1,111 +0,0 @@
@@ -1,111 +0,0 @@
|
||||
/* |
||||
* Copyright 2022 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mongodb.aot; |
||||
|
||||
import static org.assertj.core.api.Assertions.*; |
||||
import static org.mockito.Mockito.*; |
||||
|
||||
import java.util.LinkedHashSet; |
||||
import java.util.Set; |
||||
import java.util.function.Consumer; |
||||
|
||||
import org.assertj.core.api.AbstractAssert; |
||||
import org.springframework.aot.generate.ClassNameGenerator; |
||||
import org.springframework.aot.generate.DefaultGenerationContext; |
||||
import org.springframework.aot.generate.InMemoryGeneratedFiles; |
||||
import org.springframework.aot.hint.RuntimeHints; |
||||
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution; |
||||
import org.springframework.beans.factory.aot.BeanRegistrationCode; |
||||
import org.springframework.data.aot.RepositoryRegistrationAotContribution; |
||||
import org.springframework.data.repository.core.RepositoryInformation; |
||||
import org.springframework.data.repository.core.support.RepositoryFragment; |
||||
import org.springframework.lang.NonNull; |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
* @since 2022/04 |
||||
*/ |
||||
public class RepositoryRegistrationAotContributionAssert |
||||
extends AbstractAssert<RepositoryRegistrationAotContributionAssert, RepositoryRegistrationAotContribution> { |
||||
|
||||
@NonNull |
||||
public static RepositoryRegistrationAotContributionAssert assertThatContribution( |
||||
@NonNull RepositoryRegistrationAotContribution actual) { |
||||
|
||||
return new RepositoryRegistrationAotContributionAssert(actual); |
||||
} |
||||
|
||||
public RepositoryRegistrationAotContributionAssert(@NonNull RepositoryRegistrationAotContribution actual) { |
||||
super(actual, RepositoryRegistrationAotContributionAssert.class); |
||||
} |
||||
|
||||
public RepositoryRegistrationAotContributionAssert targetRepositoryTypeIs(Class<?> expected) { |
||||
|
||||
assertThat(getRepositoryInformation().getRepositoryInterface()).isEqualTo(expected); |
||||
|
||||
return this.myself; |
||||
} |
||||
|
||||
public RepositoryRegistrationAotContributionAssert hasNoFragments() { |
||||
|
||||
assertThat(getRepositoryInformation().getFragments()).isEmpty(); |
||||
|
||||
return this; |
||||
} |
||||
|
||||
public RepositoryRegistrationAotContributionAssert hasFragments() { |
||||
|
||||
assertThat(getRepositoryInformation().getFragments()).isNotEmpty(); |
||||
|
||||
return this; |
||||
} |
||||
|
||||
public RepositoryRegistrationAotContributionAssert verifyFragments(Consumer<Set<RepositoryFragment<?>>> consumer) { |
||||
|
||||
assertThat(getRepositoryInformation().getFragments()) |
||||
.satisfies(it -> consumer.accept(new LinkedHashSet<>(it))); |
||||
|
||||
return this; |
||||
} |
||||
|
||||
public RepositoryRegistrationAotContributionAssert codeContributionSatisfies( |
||||
Consumer<CodeContributionAssert> assertWith) { |
||||
|
||||
BeanRegistrationCode mockBeanRegistrationCode = mock(BeanRegistrationCode.class); |
||||
|
||||
DefaultGenerationContext generationContext = |
||||
new DefaultGenerationContext(new ClassNameGenerator(Object.class), new InMemoryGeneratedFiles()); |
||||
|
||||
this.actual.applyTo(generationContext, mockBeanRegistrationCode); |
||||
|
||||
assertWith.accept(new CodeContributionAssert(generationContext)); |
||||
|
||||
return this; |
||||
} |
||||
|
||||
private RepositoryInformation getRepositoryInformation() { |
||||
|
||||
assertThat(this.actual) |
||||
.describedAs("No repository interface found on null bean contribution") |
||||
.isNotNull(); |
||||
|
||||
assertThat(this.actual.getRepositoryInformation()) |
||||
.describedAs("No repository interface found on null repository information") |
||||
.isNotNull(); |
||||
|
||||
return this.actual.getRepositoryInformation(); |
||||
} |
||||
} |
||||
@ -1,36 +0,0 @@
@@ -1,36 +0,0 @@
|
||||
/* |
||||
* Copyright 2022 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mongodb.aot.configs; |
||||
|
||||
import org.springframework.context.annotation.ComponentScan.Filter; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.context.annotation.FilterType; |
||||
import org.springframework.data.mongodb.aot.domaintypes.Person; |
||||
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; |
||||
import org.springframework.data.repository.CrudRepository; |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
*/ |
||||
@Configuration |
||||
@EnableMongoRepositories(considerNestedRepositories = true, |
||||
includeFilters = { @Filter(type = FilterType.REGEX, pattern = ".*PersonRepository$") }) |
||||
public class ImperativeConfig { |
||||
|
||||
public interface PersonRepository extends CrudRepository<Person, String> { |
||||
|
||||
} |
||||
} |
||||
@ -1,29 +0,0 @@
@@ -1,29 +0,0 @@
|
||||
/* |
||||
* Copyright 2022 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mongodb.aot.domaintypes; |
||||
|
||||
import org.springframework.data.mongodb.core.mapping.Field; |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
* @since 2022/04 |
||||
*/ |
||||
public class Address { |
||||
|
||||
@Field("the-street") |
||||
String street; |
||||
|
||||
} |
||||
@ -1,39 +0,0 @@
@@ -1,39 +0,0 @@
|
||||
/* |
||||
* Copyright 2022 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mongodb.aot.domaintypes; |
||||
|
||||
import java.time.Instant; |
||||
|
||||
import org.springframework.data.annotation.Id; |
||||
import org.springframework.data.annotation.LastModifiedDate; |
||||
import org.springframework.data.annotation.Transient; |
||||
import org.springframework.data.mongodb.core.mapping.DBRef; |
||||
import org.springframework.data.mongodb.core.mapping.Document; |
||||
|
||||
/** |
||||
* @author Christoph Strobl |
||||
* @since 2022/04 |
||||
*/ |
||||
@Document("persons") |
||||
public class Person { |
||||
|
||||
@Id String id; |
||||
@DBRef(lazy = true) Address address; |
||||
|
||||
@Transient String transientProperty; |
||||
|
||||
@LastModifiedDate Instant modifiedAt; |
||||
} |
||||
Loading…
Reference in new issue