Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add LocalStack (V1) container for zio 2.0 #41

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

grouzen
Copy link

@grouzen grouzen commented Apr 11, 2023

This PR adds LocalStack container V1 for ZIO 2.0 only.

I also opened another PR in testcontainers-scala to allow dockerImageName overrides, and not only tag: testcontainers/testcontainers-scala#246. I think it would be good to wait until the testcontainers-scala PR is merged and make changes to this one accordingly.
Update: testcontainers-scala is bumped up to 0.40.15

@grouzen
Copy link
Author

grouzen commented Apr 11, 2023

I'm going to add documentation if this approach is fine.

ZLayer.scoped {
for {
localstack <- ZIO.service[LocalStackContainer]
endpoint <- ZIO.attempt(localstack.container.getEndpointOverride(JavaLocalStackContainer.Service.S3))
Copy link
Author

@grouzen grouzen Apr 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shows an example of overriding endpoints of LocalStack services.

Comment on lines +282 to +283
"com.amazonaws" % "aws-java-sdk-s3" % V.awsV1Version % Provided,
"com.amazonaws" % "aws-java-sdk-sqs" % V.awsV1Version % Provided,
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's the way testcontainers-scala provides these dependencies. I decided to stick to their approach.

@@ -12,6 +12,8 @@ object V {
val zioKafkaVersion = "0.17.1"
val zio2KafkaVersion = "2.0.0"
val zioHttpVersion = "0.0.4"
val zioAwsVersion = "5.20.17.1"
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is the latest version of zio-aws that uses ZIO 2.0.9. Usage of more recent versions causes NoClassDefFoundError. It should be updated after the ZIO version is bumped up.

@grouzen
Copy link
Author

grouzen commented Apr 21, 2023

Fixing the compilation error...

@V-Lamp
Copy link

V-Lamp commented May 20, 2023

Hi, I have implemented something similar and opted to directly integrate it with zio-aws.
It does work and allows for parallel testing, which plays great with zio-test by default parallelism.

The interesting/useful thing is on how to get the actual AWS config as it turns out that you don't need to have service-specific endpoints, therefore you don't need to pass the Service enum value in the TestContainer API to get an endpoint and instead get a layer to be reused by all services, which is great if you have code using multiple services. You just provide the layer 😃

Even though may not want to depend on zio-aws, it would be great to expose the endpoint directly to simplify the usage, as most users will think they need to pass the Service enum to get the endpoint.

  val awsConfig: ZLayer[Any, Throwable, CommonAwsConfig] = ZLayer.scoped {
    for {
      localstack <- makeContainer(LocalStackV2Container.Def(
        tag = "2.0.2",
        // Services are loaded lazily in latest localstack so need to be specific.
        services = Service.values()
      ))
      hostIpAddress <- ZIO.attempt(InetAddress.getByName(localstack.host).getHostAddress)
      // All services are found in the same port in latest locastack, so no service-specific mapping needed
      port <- ZIO.attempt(localstack.mappedPort(4566))
      uri <- ZIO.attempt(new URI(s"http://${hostIpAddress}:${port}"))
    } yield CommonAwsConfig(
      region = Some(Region.EU_WEST_1),
      endpointOverride = Some(uri),
      credentialsProvider = localstack.staticCredentialsProvider,
      commonClientConfig = None
    )
  }

Hope it helps !

TLDR: Updates to Localstack make the API container API from testcontainers outdated, as you don't need to either specify which services you need, nor get service-specific ports. So the org.testcontainers.containers.localstack.LocalStackContainer.Service enum becomes pretty much useless.

Dropping the withServices and endpointOverride methods (as there are very limited reasons to not use the latest localstack version) will help users avoid a legacy API which leads to quite complicated usage, especially when using zio layers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants