Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set proxy on AWS Java SDK v2 Apache client

It look like there is no good source on how to do this, the two places where I have found information are the following:

First link. This looks to be the most up to date version. However I am not able to find the software.amazon.awssdk.http.apache.ApacheHttpClient anywhere in my project even when I have the dependency.

 <groupId>software.amazon.awssdk</groupId>
  <artifactId>aws-sdk-java</artifactId>
  <version>2.3.2</version>
</dependency>
<dependency>
    <artifactId>aws-http-client-apache</artifactId>
    <groupId>software.amazon.awssdk</groupId>
    <version>2.0.0-preview-1</version>
</dependency>

The second link looks to provide an outdated version on how to configure clients. The following code in the example looks not to be valid:

DynamoDBClient client =
        DynamoDBClient.builder()
                      .httpConfiguration(ClientHttpConfiguration.builder()
                                                                .httpClientFactory(apacheClientFactory)
                                                                .build())
                      .build();

ClientHttpConfiguration Is not available and the httpConfiguration method is not available on the clients.

Trying to hack something together gives me the following code:

ProxyConfiguration proxyConfiguration = ProxyConfiguration.builder().endpoint(URI.create("host:port")).username("usr").password("pwd").build();

SdkHttpClient apacheClientFactory =
        ApacheSdkHttpClientFactory.builder()
                .socketTimeout(Duration.ofSeconds(10))
                .connectionTimeout(Duration.ofMillis(750))
                .proxyConfiguration(proxyConfiguration).build().createHttpClient();


this.s3client = S3Client.builder().httpClient(apacheClientFactory).build();

This compiles but I get lots of java.lang.ClassNotFoundException: software.amazon.awssdk.http.ExecutableHttpRequest exceptions that I dont understand where they are coming from or how to fix.

So my question is what is the correct way to setup a proxy for the 2.3.2 version of AWS Java SDK v2 and why is my implementation not working?

Update

When I add the following dependency I get another error:

<dependency>
  <groupId>software.amazon.awssdk</groupId>
  <artifactId>apache-client</artifactId>
  <version>2.3.2</version>
</dependency>

Error:

Caused by: java.lang.ClassNotFoundException: software.amazon.awssdk.http.SdkHttpClient$Builder
like image 387
user3139545 Avatar asked Jan 17 '19 11:01

user3139545


2 Answers

You seem to be bringing in multiple versions of the AWS SDK for Java. Try using the "Bill of Materials" BOM approach using import scope like so:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>software.amazon.awssdk</groupId>
      <artifactId>bom</artifactId>
      <version>2.5.60</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

With that defined, bring the specific parts you want:

<dependencies>
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>iam</artifactId>
    </dependency>
    <dependency>
      <groupId>software.amazon.awssdk</groupId>
      <artifactId>apache-client</artifactId>
    </dependency>
</dependencies>

You won't need to specify the versions as that's being covered by the BOM. Once you have the dependencies set up correctly, you can do something like this:

  final SdkHttpClient httpClient = ApacheHttpClient.builder()
            .proxyConfiguration(ProxyConfiguration.builder()
                    .useSystemPropertyValues(true)
                    .build())
            .build();
  this.s3client = S3Client.builder().httpClient(httpClient).build();

I'm using the useSystemPropertyValues so that it'll pick up the standard system properties for setting the proxy values as a matter of convenience. All of this works for us and the proxies are being used correctly.

like image 117
Ryan J. McDonough Avatar answered Nov 15 '22 19:11

Ryan J. McDonough


To run your Junit tests against dynamoDB from your local system behind Proxy firewall, use the following snippet of code. I used java 8, aws sdk 2x, dynamodb 2.15.x, Maven 4.x and IntelliJ 2020.3.

 private DynamoDbClient createDynamoDbClient() {
    SdkHttpClient apacheClient = ApacheHttpClient.builder()
      .socketTimeout(Duration.ofSeconds(20))
      .connectionTimeout(Duration.ofSeconds(5))
      .proxyConfiguration(ProxyConfiguration.builder()
        .useSystemPropertyValues(false)
        .endpoint(URI.create("http://<proxyip>:<port>"))
        .username("<userId>")
        .password("<pwd>")
        .build())
      .build();

    DynamoDbClient dynamoDbClient = DynamoDbClient.builder()
      .region(Region.US_EAST_1)      
      .httpClient(apacheClient)
      .credentialsProvider(ProfileCredentialsProvider.builder()
        .profileName("default")
        .build())
      .build();

    return dynamoDbClient;
  }
like image 40
Jai Avatar answered Nov 15 '22 20:11

Jai