user3139545
user3139545

Reputation: 7394

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

Upvotes: 10

Views: 15015

Answers (3)

Jai
Jai

Reputation: 71

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;
  }

Upvotes: 7

Azimuts
Azimuts

Reputation: 1302

There is some issue when you are trying to use non-system proxy, fe :

final SdkHttpClient httpClient = ApacheHttpClient.builder()
                                                        .proxyConfiguration(ProxyConfiguration.builder()
                                                                                              .useSystemPropertyValues(false)
                                                                                               .endpoint(URI.create("localhost:9090"))
                                                                                               .build()
                                                                            )


                                                    .build();
            clientBuilder = clientBuilder.httpClient(httpClient);

.... For this code the proxy is ignored !!! I have seen this old post (https://github.com/aws/aws-sdk-java-v2/issues/751) and aparentelly has not been fixed !!

Upvotes: -1

Ryan J. McDonough
Ryan J. McDonough

Reputation: 1725

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.

Upvotes: 11

Related Questions