Using Testcontainers at Development Time I have
@TestConfiguration(proxyBeanMethods = false)
public class ContainersConfiguration {
@Bean
public KeycloakContainer keycloakContainer(DynamicPropertyRegistry registry) {
KeycloakContainer keycloakContainer = new KeycloakContainer()...
keycloakContainer.start();
registry.add("keycloak.server.external-url", () -> keycloakContainer.getAuthServerUrl());
registry.add("keycloak.server.internal-url", () -> keycloakContainer.getAuthServerUrl());
registry.add("keycloak.dev-portal-realm", () -> "master");
return keycloakContainer;
}
}
with
public class DMATestApplication {
public static void main(String[] args) {
SpringApplication.from(DeveloperManagerApplication::main).with(ContainersConfiguration.class).run(args);;
}
Upon running
gradle bootTestRun it throws
No qualifying bean of type 'org.springframework.test.context.DynamicPropertyRegistry' available:
```Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.test.context.DynamicPropertyRegistry' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1824) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1383)
While reading the docs it suggests it is possible, when @ServiceConnection isn't supported
Using a @ServiceConnection is recommended whenever possible, however, dynamic properties can be a useful fallback for technologies that don’t yet have @ServiceConnection support.
Does anyone know if dynamic properties are supported?
**Comment From: wilkinsona**
The `DynamicPropertyRegistry` should be auto-configured by `TestcontainersPropertySourceAutoConfiguration`. It's not clear from what you've described thus far why that isn't happening. If you would like us to spend some more time investigating, please spend some time providing a complete yet minimal sample that reproduces the problem. You can share it with us by pushing it to a separate repository on GitHub or by zipping it up and attaching it to this issue.
**Comment From: jbeaken**
Hi, thanks for the speedy reply. Yes, I was about to create a sample project, but during the process I discovered the problem. It is due to the project using spring cloud kubernetes
```java
implementation 'org.springframework.cloud:spring-cloud-starter-kubernetes-client-config'
implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap' //Use bootstrap.yml to load configmap and secret
The introduction of the bootstrap context from spring cloud for some reason prevents TestcontainersPropertySourceAutoConfiguration from kicking in. I am looking into it further
My guess is that
@ConditionalOnClass(DynamicPropertyRegistry.class)
public class TestcontainersPropertySourceAutoConfiguration {
As the bootstrap classpath doesn't include DynamicPropertyRegistry.class, the condition is failing
Comment From: jbeaken
Defining the bean in the bootstrap phase by using
@Bean
DynamicPropertyRegistry dynamicPropertyRegistry(ConfigurableEnvironment environment) {
return TestcontainersPropertySource.attach(environment);
}
doesn't work as there is then a conflict when the normal application context phase kicks in and tries to create a DynamicPropertyRegistry again, so failing
The bean 'dynamicPropertyRegistry', defined in class path resource [org/springframework/boot/testcontainers/properties/TestcontainersPropertySourceAutoConfiguration.class], could not be registered. A bean with that name has already been defined in com.elsevier.titan.developermanager.application.ContainersConfiguration and overriding is disabled.
Does this just mean you cannot combine DynamicPropertyRegistry with spring cloud bootstrap?
Comment From: jbeaken
Using
spring:
main:
allow-bean-definition-overriding: true
allows the above to work, that is
@TestConfiguration(proxyBeanMethods = false)
public class ContainersConfiguration {
@Bean
@Primary
DynamicPropertyRegistry dynamicPropertyRegistry(ConfigurableEnvironment environment) {
return TestcontainersPropertySource.attach(environment);
}
@Bean
public KeycloakContainer keycloakContainer(DynamicPropertyRegistry registry) {....
But this doesn't work, as the properties are lost some how,
anyhow, I really can't see what else to try, except remove spring cloud bootstrap.
Comment From: wilkinsona
the bootstrap classpath
AFAIK, there's no separation between the classes that are available to the bootstrap context and the classes that are available to the main context.
anyhow, I really can't see what else to try, except remove spring cloud bootstrap.
We might be able to suggest something if you provide the minimal sample that was requested above.
Comment From: jbeaken
thanks, here's a minimal : https://github.com/jbeaken/dynamic
run
gradle bootTestRun
Comment From: wilkinsona
Thanks for the sample.
The problem's caused by a bug in the new SpringApplication.from support that causes Spring Cloud's bootstrap context to be polluted with your ContainerConfiguration class. You can work around that by not using from:
public static void main(String[] args) {
new SpringApplicationBuilder(DemoApplication.class).sources(ContainerConfiguration.class).run(args);
}
This avoids the problem but comes at the cost of not being able to reuse the main method in your application's main code.