spring-cloud-aws icon indicating copy to clipboard operation
spring-cloud-aws copied to clipboard

Support ConnectionsDetails and ServiceConnections for Spring Boot 3.1

Open eddumelendez opened this issue 1 year ago • 14 comments

Type: Feature

First of all, congrats for 3.0.0 release! 🎉

Is your feature request related to a problem? Please describe. I'm pretty sure you are already having this in mind but just want to sync. This is not a problem but a nice feature when used with upcoming spring boot 3.1 version which can auto-configure spring cloud aws properties (endpoint, access key, secret key, region) when using LocalStackContainer and it can enable Dev Mode too

Describe the solution you'd like Update existing autoconfigurations to use ConnectionDetails for the properties I mentioned above. Add a new module, spring-cloud-aws-testcontainers which will add a ContainerConnectionsDetailsFactory.

Describe alternatives you've considered Unless, spring cloud aws provides initial support for ConnectionDetails there is no much to be done.

Additional context I can contribute this feature but would like to know the timeline for this 😁

eddumelendez avatar May 02 '23 16:05 eddumelendez

Thanks @eddumelendez! There is no way to make ServiceConnections contribute to environment properties instead of changing autoconfigurations to rely on ConnectionDetails? This would be ideal as we could likely continue to maintain single Springs Cloud AWS version for both Spring Boot 3.0 and 3.1

maciejwalkowiak avatar May 03 '23 19:05 maciejwalkowiak

Now, there is! https://docs.spring.io/spring-boot/docs/3.1.0-SNAPSHOT/reference/htmlsingle/#features.testing.testcontainers.at-development-time.dynamic-properties

It will work until OOTB support is added in spring-cloud-aws.

eddumelendez avatar May 03 '23 20:05 eddumelendez

It still feels suboptimal. I don't get why Spring Boot does not make it easier to extend for 3rd party libraries. To have an option to pass something like a service connection configurer:

@TestConfiguration(proxyBeanMethods = false)
public class MyContainersConfiguration {

    @Bean
    @ServiceConnection(LocalstackServiceConnectionConfigurer.class)
    public LocalstackContainer localstackContainer() {
        return new LocalstackContainer();
    }

}

class LocalstackServiceConnectionConfigurer implements ServiceConnectionConfigurer { // i made up this interface
    void apply(LocalstackContainer container, DynamicPropertyRegistry properties) {
       // set properties
    }
}

Probably there is a reason why such thing does not exist, or maybe its something to discuss with the Spring Boot team. I am trying to come up with reasonable option where we don't end up in maintenance hell with multiple versions of Spring Cloud AWS.

maciejwalkowiak avatar May 04 '23 07:05 maciejwalkowiak

That's something that @philwebb and I have discussed while prototyping ideas around the service accounts. The problem is that ServiceConnection isn't based on properties, but objects. You can, however, do the following:

    @Bean
    public LocalstackContainer localstackContainer(DynamicPropertyRegistry properties) {
        var localstack = new LocalstackContainer();
        // populate properties from the container
        return localstack;
    }

bsideup avatar Jun 06 '23 17:06 bsideup

Some documentation for this is at https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.testing.testcontainers.at-development-time.dynamic-properties

philwebb avatar Jun 06 '23 17:06 philwebb

@bsideup @philwebb thanks, this looks great! I think it wasn't available at the time I wrote my made-up sample.

maciejwalkowiak avatar Jun 07 '23 05:06 maciejwalkowiak

@maciejwalkowiak I was thinking something more, in application-test.yaml having something like this:

spring:
   cloud:
       localstack: 
            enabled: true
            imageName: localstack/localstack:2.2.0
            cloudformation: test-cloudformation.yaml

And this will:

  • Start localstack container using testcontainer
  • Override endpoint based on started container
  • Override AWS Access Key ID and Secret Key based on started container
  • Override region based on started container
  • Create AWS resources using cloudformation provided

Something like this: https://github.com/alikian/localstack-loader

alikian avatar Aug 15 '23 21:08 alikian

How could I help to speed this up? @MatejNedic @maciejwalkowiak

dominik-kovacs avatar Sep 04 '23 12:09 dominik-kovacs

@maciejwalkowiak should we target this for 3.1.0 ?

MatejNedic avatar Nov 06 '23 20:11 MatejNedic

I think the date for 3.1 will be dictated by Spring Boot and Spring Cloud release, but yes it would be nice to have in 3.1. I guess this shouldn't be much work the question is who has time ;)

maciejwalkowiak avatar Nov 06 '23 20:11 maciejwalkowiak

@maciejwalkowiak @MatejNedic I could try

dominik-kovacs avatar Nov 06 '23 20:11 dominik-kovacs

@poklakni go for it. PRs welcome!

maciejwalkowiak avatar Nov 06 '23 21:11 maciejwalkowiak

I have a little problem with file placement.

I created AwsConnectionDetails, PropertiesAwsConnectionDetails, and LocalStackContainerConnectionDetailsFactory.

AwsConnectionDetails and PropertiesAwsConnectionDetails depend on spring-boot-autoconfigure therefore I assume it should be placed in spring-cloud-aws-autoconfigure module.

But then where should I create LocalStackContainerConnectionDetailsFactory? If I place it to newly created spring-cloud-aws-testcontainers module I would have to add spring-cloud-aws-autoconfigure which does not seem right.

Right now I have all 3 classes in spring-cloud-aws-autoconfigure module which does not seem right either.

This is what I have so far https://github.com/poklakni/spring-cloud-aws/commit/d13267d0cba7910e4d387e80aa3412d4034f0558

dominik-kovacs avatar Nov 08 '23 17:11 dominik-kovacs

AwsConnectionDetails and PropertiesAwsConnectionDetails depend on spring-boot-autoconfigure therefore I assume it should be placed in spring-cloud-aws-autoconfigure module.

👍🏽

But then where should I create LocalStackContainerConnectionDetailsFactory? If I place it to newly created spring-cloud-aws-testcontainers module I would have to add spring-cloud-aws-autoconfigure which does not seem right.

When I thought about this, I have the same idea about having spring-cloud-aws-testcontainers, which will bring spring-boot-testcontainers as a transitive dependency and depend on spring-cloud-aws-autoconfigure but marked as an optional dependency.

If your concern is about circular dependency between spring-cloud-aws-autoconfigure and spring-cloud-aws-testcontainers because of moving the IT to the new service connection support. Then, I would say not to move those IT, LocalStackContainerConnectionDetailsFactory should be tested on its own module. Those IT in spring-cloud-aws-autoconfigure could be in another module but it's not my call and probably out of scope of this issue.

eddumelendez avatar Dec 04 '23 23:12 eddumelendez

Woop, happy news! :tada:

herder avatar Mar 18 '24 09:03 herder