localstack / localstack-java-utils

☕ Java utilities and JUnit integration for LocalStack
Apache License 2.0
75 stars 43 forks source link

Connection refused on 4597 when using ec2 service #17

Closed errcode1202 closed 4 years ago

errcode1202 commented 4 years ago

Hi,

I'm hitting the following exception when using localstack-java-utils (0.2.1) and Junit5:

software.amazon.awssdk.core.exception.SdkClientException: Unable to execute HTTP request: Connect to localhost:4597 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused (Connection refused)

at software.amazon.awssdk.core.exception.SdkClientException$BuilderImpl.build(SdkClientException.java:97)
at software.amazon.awssdk.core.internal.http.pipeline.stages.RetryableStage$RetryExecutor.handleThrownException(RetryableStage.java:137)
at software.amazon.awssdk.core.internal.http.pipeline.stages.RetryableStage$RetryExecutor.execute(RetryableStage.java:95)
at software.amazon.awssdk.core.internal.http.pipeline.stages.RetryableStage.execute(RetryableStage.java:63)
at software.amazon.awssdk.core.internal.http.pipeline.stages.RetryableStage.execute(RetryableStage.java:43)

I see this error for a test I have when following the pattern described in the readme i.e.

@ExtendWith({LocalstackDockerExtension.class, MockitoExtension.class})
@LocalstackDockerProperties(services = {"ec2"}, imageTag = "0.11.2")
public class MyEc2Test {
   ...
}

If I apply a breakpoint during test execution and check docker ps I can see the relevant containers are up, although the tests still fail

CONTAINER ID        IMAGE                               COMMAND                  CREATED             STATUS              PORTS                                                                 NAMES
35192b6c57c6        quay.io/testcontainers/ryuk:0.2.3   "/app"                   16 seconds ago      Up 16 seconds       0.0.0.0:32900->8080/tcp                                               testcontainers-ryuk-83b761b3-b318-4cae-bbea-d823438e0a22
d2903c7cc267        localstack/localstack:0.11.2        "docker-entrypoint.sh"   32 seconds ago      Up 32 seconds       4566/tcp, 4585-4597/tcp, 8080/tcp, 0.0.0.0:4567-4584->4567-4584/tcp   thirsty_swartz

Interestingly, If I run the localstack manually as below, the tests pass (having removed the annotations @ExtendWith and @LocalstackDockerProperties) and are able to query localhost on port 4597

 docker run -p 4597:4597 -e SERVICES=ec2 -e DEFAULT_REGION=us-east-1 localstack/localstack:0.11.2

It feels like port 4597 isnt being properly mapped/exposed when ec2 is run via @LocalstackDockerProperties?

errcode1202 commented 4 years ago

Confirmed that we hit the same issue when using the new EDGE port and pointing the tests to:

http://localhost:4566

software.amazon.awssdk.core.exception.SdkClientException: Unable to execute HTTP request: Connect to localhost:4566 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused (Connection refused)
cathalking commented 4 years ago

Root cause is the port range defined as a constant here in cloud.localstack.docker.Container:

https://github.com/localstack/localstack-java-utils/blob/73065f6335bd04e44fed4d0a590c0c06cecab61d/src/main/java/cloud/localstack/docker/Container.java#L25

Therefore both the EDGE port and the EC2 port fall outside of that port range + are therefore unreachable when using LocalstackDockerProperties defaults.

I encountered the same problem when trying to use STS (port 4927)

A workaround I settled on is to add a custom port mapping, just for EDGE, and list out the required services that EDGE will be used for:

e.g.

@ExtendWith({LocalstackDockerExtension.class, SpringExtension.class})
@LocalstackDockerProperties(services = {"edge:4566", "sns", "sqs", "sts"})
florianakos commented 4 years ago

I just ran into the same issue with the Java class. I'm loading it from Scala code and did not manage to solve it with that annotation trick from @cathalking

I use S3, KMS and SecretsManager in my setup and KMS was the one falling due to its default port of 4599, which is way out of the hard-coded range 4567-4584.

I almost gave up trying to fix it when I found an env variable for changing the EDGE port, which ultimately saved my evening:

        val dockerConfig = LocalstackDockerConfiguration.builder()
          .randomizePorts(false)
          .environmentVariables(Map("EDGE_PORT" -> "4567",
                                    "SERVICES" -> "s3,kms,secretsmanager", 
                                    "DEBUG" -> "1")).build()
        localstackDocker.startup(dockerConfig)

With this remapping I was able to connect to all 3 services via EDGE port 4567. :)

whummer commented 4 years ago

Thanks for reporting @dylanrathbone @cathalking @florianakos . The default port mapping has been recently updated, and in the latest version all services now map to the edge service (on port 4566 by default). The Java library has been updated accordingly - can you please give it another try with the latest release version 0.2.2? Please report here if the problem persists. Thanks

florianakos commented 4 years ago

Great news, thanks a lot for the update @whummer, I will check the latest release and report back if any issues arise.