7 changed files with 0 additions and 451 deletions
@ -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 @@ |
|||||||
/* |
|
||||||
* 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 @@ |
|||||||
/* |
|
||||||
* 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 @@ |
|||||||
/* |
|
||||||
* 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 @@ |
|||||||
/* |
|
||||||
* 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 @@ |
|||||||
/* |
|
||||||
* 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 @@ |
|||||||
/* |
|
||||||
* 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