问题
I have multiple Java spring boot services (around 20 of them) using Amazon SDKs for S3, SQS, DynamoDB, etc..
Currently, to use Amazon Web Service I only need to specify my AWS key & secret.
ACCESS_AWS_KEY=<MY_KEY>
ACCESS_AWS_SECRET=<MY_SECRET>
However, I wanted to setup offline dev enviroment so I started to dockerize my services and set up a single multi-docker container with all my services dockerized and localstack should be used instead of remote AWS service to allow complete offline development.
docker-compose.yml looks something like this
version: '3'
services:
service_1:
build: ./repos/service_1
links:
- service_2:
- localstack
service_2:
build: ./repos/service_2
links:
- localstack
service_3:
build: ./repos/service_3
links:
- localstack
localstack:
image: localstack/localstack
Amazon SDK provides AWS_REGION env variable, but not an endpoint environment variable which I can easily use in all services.
I also don't want to make code changes in my services to accommodate the new non-default endpoint.
I want a generic solution to forward requests like this:
dynamodb.eu-west-1.amazonaws.com => localstack_1:4569
s3-eu-west-1.amazonaws.com => localstack_1:4572
where localstack_1 is a linked docker container of localstack and reachable by other containers.
I came across extra_hosts: in docker-compose, but it only redirects to IPs and has no hostname resolving.
Also, notice that I have dozens of ports exposed in localstack from 4569 to 4582.
I thought about running a script on each machine setting up a vhost in some way, or forwarding all outgoing connections from all containers to a centralized request forwarder service, but have no clue where to start.
This will only used as a offline dev environment and will not receive any real traffic.
回答1:
Ok, I was able to finally find a solution for this. I had to actually go through localstack code base to be able to find the solution. Couple of quick things :
- Localstack is not integrated with IAM. So it just simply ignores the secret key or password.
- If you're using IAM, you now need to have a flag to override the endpoint. You can probably have a flag to indicate localstack mode.
Couple of classes which I found helpful if you're debugging issues :
https://github.com/atlassian/localstack/blob/master/localstack/ext/java/src/test/java/com/atlassian/localstack/SQSMessagingTest.java
https://github.com/atlassian/localstack/blob/master/localstack/ext/java/src/test/java/com/atlassian/localstack/TestUtils.java
Now for the solution :
AwsClientBuilder.EndpointConfiguration endpoint = new AwsClientBuilder.EndpointConfiguration("http://localhost:4576/", awsRegion.getName());
AmazonSQSClient client = (AmazonSQSClient) AmazonSQSClientBuilder.standard()
.withCredentials(configuration.getSqsConfiguration().getCredentialsProvider())
.withEndpointConfiguration(endpoint)
.build();
Here http://localhost:4576/ is where localstacks runs SQS. Don't miss the trailing slash. For using this in camel route is same as using AWS resources. Hopefully this helps!
来源:https://stackoverflow.com/questions/45551496/redirect-aws-sdks-default-endpoint-to-mocked-localstack-endpoints