Skip to content

Commit fe5424b

Browse files
kwondh5217philwebb
authored andcommitted
Include @bean method annotations in ContainerConnectionSource
Update `ServiceConnectionAutoConfigurationRegistrar` to include annotations from `@Bean` methods. See gh-50033 Signed-off-by: Daeho Kwon <trewq231@naver.com>
1 parent 019eb63 commit fe5424b

6 files changed

Lines changed: 180 additions & 1 deletion

File tree

spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ServiceConnectionAutoConfigurationRegistrar.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.boot.testcontainers.service.connection;
1818

19+
import java.lang.reflect.Method;
1920
import java.util.LinkedHashSet;
2021
import java.util.Set;
2122

@@ -26,6 +27,7 @@
2627
import org.springframework.beans.factory.config.BeanDefinition;
2728
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
2829
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
30+
import org.springframework.beans.factory.support.RootBeanDefinition;
2931
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactories;
3032
import org.springframework.boot.origin.Origin;
3133
import org.springframework.boot.testcontainers.beans.TestcontainerBeanDefinition;
@@ -39,6 +41,7 @@
3941
* {@link ServiceConnectionAutoConfiguration}.
4042
*
4143
* @author Phillip Webb
44+
* @author Daeho Kwon
4245
*/
4346
class ServiceConnectionAutoConfigurationRegistrar implements ImportBeanDefinitionRegistrar {
4447

@@ -61,7 +64,7 @@ private void registerBeanDefinitions(ConfigurableListableBeanFactory beanFactory
6164
for (String beanName : beanFactory.getBeanNamesForType(Container.class)) {
6265
BeanDefinition beanDefinition = getBeanDefinition(beanFactory, beanName);
6366
MergedAnnotations annotations = (beanDefinition instanceof TestcontainerBeanDefinition testcontainerBeanDefinition)
64-
? testcontainerBeanDefinition.getAnnotations() : null;
67+
? testcontainerBeanDefinition.getAnnotations() : getAnnotationsFromFactoryMethod(beanDefinition);
6568
for (ServiceConnection serviceConnection : getServiceConnections(beanFactory, beanName, annotations)) {
6669
ContainerConnectionSource<?> source = createSource(beanFactory, beanName, beanDefinition, annotations,
6770
serviceConnection);
@@ -70,6 +73,16 @@ private void registerBeanDefinitions(ConfigurableListableBeanFactory beanFactory
7073
}
7174
}
7275

76+
private MergedAnnotations getAnnotationsFromFactoryMethod(BeanDefinition beanDefinition) {
77+
if (beanDefinition instanceof RootBeanDefinition rootBeanDefinition) {
78+
Method factoryMethod = rootBeanDefinition.getResolvedFactoryMethod();
79+
if (factoryMethod != null) {
80+
return MergedAnnotations.from(factoryMethod, MergedAnnotations.SearchStrategy.DIRECT);
81+
}
82+
}
83+
return null;
84+
}
85+
7386
private Set<ServiceConnection> getServiceConnections(ConfigurableListableBeanFactory beanFactory, String beanName,
7487
MergedAnnotations annotations) {
7588
Set<ServiceConnection> serviceConnections = beanFactory.findAllAnnotationsOnBean(beanName,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright 2012-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.testcontainers.service.connection;
18+
19+
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
20+
21+
public interface DatabaseConnectionDetails extends ConnectionDetails {
22+
23+
String getJdbcUrl();
24+
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright 2012-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.testcontainers.service.connection;
18+
19+
import org.testcontainers.containers.JdbcDatabaseContainer;
20+
21+
public class DatabaseContainerDatabaseConnectionDetails
22+
extends ContainerConnectionDetailsFactory<JdbcDatabaseContainer<?>, DatabaseConnectionDetails> {
23+
24+
@Override
25+
protected DatabaseConnectionDetails getContainerConnectionDetails(
26+
ContainerConnectionSource<JdbcDatabaseContainer<?>> source) {
27+
return new TestDatabaseConnectionDetails(source);
28+
}
29+
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright 2012-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.testcontainers.service.connection;
18+
19+
import org.junit.jupiter.api.Test;
20+
import org.testcontainers.containers.PostgreSQLContainer;
21+
22+
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
23+
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory.ContainerConnectionDetails;
24+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
25+
import org.springframework.context.annotation.Bean;
26+
import org.springframework.context.annotation.Configuration;
27+
28+
import static org.assertj.core.api.Assertions.assertThat;
29+
import static org.mockito.Mockito.mock;
30+
31+
/**
32+
* Tests for {@link ServiceConnectionAutoConfigurationRegistrar} to verify that
33+
* annotations on {@link Bean @Bean} methods are available in
34+
* {@link ContainerConnectionSource}.
35+
*
36+
* @author Daeho Kwon
37+
*/
38+
class ServiceConnectionAutoConfigurationRegistrarTests {
39+
40+
@Test
41+
void sslAnnotationOnBeanMethodShouldBeDetectedInContainerConnectionSource() {
42+
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
43+
context.register(WithServiceConnectionAutoConfiguration.class, ContainerConfiguration.class);
44+
context.refresh();
45+
ContainerConnectionDetails<?> details = (ContainerConnectionDetails<?>) context
46+
.getBean(DatabaseConnectionDetails.class);
47+
assertThat(details.hasAnnotation(Ssl.class)).isTrue();
48+
}
49+
}
50+
51+
@Configuration(proxyBeanMethods = false)
52+
@ImportAutoConfiguration(ServiceConnectionAutoConfiguration.class)
53+
static class WithServiceConnectionAutoConfiguration {
54+
55+
}
56+
57+
@Configuration(proxyBeanMethods = false)
58+
static class ContainerConfiguration {
59+
60+
@Bean
61+
@ServiceConnection
62+
@Ssl
63+
PostgreSQLContainer container() {
64+
return mock(PostgreSQLContainer.class);
65+
}
66+
67+
}
68+
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2012-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.testcontainers.service.connection;
18+
19+
import org.testcontainers.containers.JdbcDatabaseContainer;
20+
21+
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory.ContainerConnectionDetails;
22+
23+
class TestDatabaseConnectionDetails extends ContainerConnectionDetails<JdbcDatabaseContainer<?>>
24+
implements DatabaseConnectionDetails {
25+
26+
TestDatabaseConnectionDetails(ContainerConnectionSource<JdbcDatabaseContainer<?>> source) {
27+
super(source);
28+
}
29+
30+
@Override
31+
public String getJdbcUrl() {
32+
return getContainer().getJdbcUrl();
33+
}
34+
35+
JdbcDatabaseContainer<?> callGetContainer() {
36+
return super.getContainer();
37+
}
38+
39+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Test Connection Details Factories
2+
org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\
3+
org.springframework.boot.testcontainers.service.connection.DatabaseContainerDatabaseConnectionDetails

0 commit comments

Comments
 (0)