Open maciejwalkowiak opened 8 months ago
@rieckpil @spencergibb perhaps you have some ideas how this can be done in a better way?
The issue is, Parameter Store and Secrets Manager integrations run in the bootstrap phase - for spring.config.import
. Service connections kick in too late in the process and @SpringBootTest
does not pick up BootstrapRegistryInitializers
created through spring.factory
. So having custom "main" class and @SpringBootTest
with useMainMethod
was the only way to get it working.
Good point, I guess I'm lacking some in-depth knowledge of the Spring bootstrap phase here, maybe @sbrannen has a quick idea
I don't have anything else to add. Maybe @philwebb might.
Hi, @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class)
should be added at class level. I have some examples running for parameter store and secrets manager working with @DynamicPropertySource
and it should work with @ServiceConnection
as well. Looking forward for the release :)
So far there is no issues with spring-cloud-aws but if ConfigDataMissingEnvironmentPostProcessor
has been implemented for those integrations recently look at this issue in other spring-cloud projects.
@eddumelendez thanks for chiming in. With ConfigDataApplicationContextInitializer
, service connections are initialized indeed before the config data loaders, BUT the connection details beans are not available in the bootstrap context.
Considering that the amount of boilerplate required to use bootstrap context initializers in tests is so high, I think sticking to @DynamicPropertySource
provides better dev experience.
Perhaps we can provide a static method like this just to make it a bit simpler:
static void configureLocalStack(DynamicPropertyRegistry registry, LocalStackContainer localstack) {
registry.add("spring.cloud.aws.credentials.access-key", localstack::getAccessKey);
registry.add("spring.cloud.aws.credentials.secret-key", localstack::getSecretKey);
registry.add("spring.cloud.aws.region.static", localstack::getRegion);
registry.add("spring.cloud.aws.endpoint", localstack::getEndpoint);
}
Sample usage:
@Container
private static LocalStackContainer localstack = new LocalStackContainer(
DockerImageName.parse("localstack/localstack:3.2.0"));
@DynamicPropertySource
static void properties(DynamicPropertyRegistry registry) {
configureLocalStack(registry, localstack);
}
I don't have anything else to add. Maybe @philwebb might.
Sorry, not off the top of my head. The bootstrap logic is always quite difficult to get right.
@ServiceConnection
support that's being added in https://github.com/awspring/spring-cloud-aws/pull/1075 does not help with ParameterStore and SecretsManager, as those integration are initiated in the bootstrap phase, before service connection related factories kick in.We can provide a
BootstrapRegistryInitializer
implementation for Localstack:that can be used like this: