Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 29 additions & 6 deletions src/main/java/software/amazon/nio/spi/s3/S3ClientProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@

package software.amazon.nio.spi.s3;

import java.lang.reflect.InvocationTargetException;
import java.time.Duration;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import java.time.Duration;

import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
import software.amazon.awssdk.core.client.config.SdkAdvancedClientOption;
import software.amazon.awssdk.core.interceptor.Context;
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
import software.amazon.awssdk.core.signer.Signer;
import software.amazon.awssdk.http.SdkHttpRequest;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3AsyncClient;
Expand Down Expand Up @@ -68,6 +73,11 @@ public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context, Execu
* Flag to determine if we should use CRT client or regular client with custom headers
*/
private boolean useCustomHeaders = false;

/**
* Class-name of the signer which should be used.
*/
private String customerSigner = null;


private final Cache<String, CacheableS3Client> bucketClientCache = Caffeine.newBuilder()
Expand All @@ -81,6 +91,7 @@ public S3ClientProvider(S3NioSpiConfiguration c) {
this.useCustomHeaders = Boolean.parseBoolean(
System.getProperty("s3.spi.client.custom-headers.enabled", "false")
);
this.customerSigner = System.getProperty("s3.spi.client.custom-signer", null);
}

public void asyncClientBuilder(final S3CrtAsyncClientBuilder builder) {
Expand Down Expand Up @@ -112,7 +123,7 @@ protected S3AsyncClient generateClient(String bucket) {
if (client != null && client.isClosed()) {
bucketClientCache.invalidate(bucket); // remove the closed client from the cache
}
if (useCustomHeaders) {
if (useCustomHeaders || customerSigner != null) {
return bucketClientCache.get(bucket, b -> new CacheableS3Client(configureRegularClient().build()));
} else {
return bucketClientCache.get(bucket, b -> new CacheableS3Client(configureCrtClient().build()));
Expand Down Expand Up @@ -161,11 +172,23 @@ S3AsyncClientBuilder configureRegularClient() {
}

// Add custom headers to identify requests from this library
var clientOverrideConfig = ClientOverrideConfiguration.builder()
.addExecutionInterceptor(new S3NioSpiInterceptor())
.build();
var clientOverrideConfigBuilder = ClientOverrideConfiguration.builder();

if (useCustomHeaders) {
clientOverrideConfigBuilder.addExecutionInterceptor(new S3NioSpiInterceptor());
}
if (customerSigner != null) {
try {
@SuppressWarnings("deprecation")
Signer signer = (Signer) Class.forName(customerSigner).getDeclaredConstructor().newInstance();
clientOverrideConfigBuilder.putAdvancedOption(SdkAdvancedClientOption.SIGNER, signer);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException | ClassNotFoundException e) {
throw new RuntimeException(e);
}
}

builder.overrideConfiguration(clientOverrideConfig);
builder.overrideConfiguration(clientOverrideConfigBuilder.build());
builder.forcePathStyle(configuration.getForcePathStyle());

return builder;
Expand Down