我有一个 Spring Boot 应用程序,用于管理存储在 Wasabi 存储桶中的文件。我需要将文件从存储桶中的一个位置复制到另一个位置,因此我使用 S3TransferManager 来处理此操作。但是,每当我尝试复制文件时,SDK 都会报告该存储桶不存在,尽管我已通过 Wasabi 控制台直观地验证了该存储桶的存在,并检查了代码中存储桶名称中的拼写错误。
这是创建我用来管理 S3 操作的 Bean 的配置类
@Configuration
public class Config {
@Bean(name = "wasabiCredentialsProvider")
public AwsCredentialsProvider wasabiCredentialProvider(@Value("${the.accessKey}") String accessKey,
@Value("${the.secretKey}") String secretKey) {
return StaticCredentialsProvider.create(AwsBasicCredentials.create(accessKey, secretKey));
}
@Bean(name = "wasabiS3Async")
public S3AsyncClient wasabiS3Async(@Qualifier("wasabiCredentialsProvider") AwsCredentialsProvider awsCredentialsProvider,
@Value("${the.region}") String region,
@Value("${the.endpoint}") String endpoint) throws URISyntaxException {
SdkAsyncHttpClient nettyHttpClient = NettyNioAsyncHttpClient.builder()
.connectionAcquisitionTimeout(Duration.ofHours(3))
.connectionTimeout(Duration.ofHours(3))
.readTimeout(Duration.ofHours(3))
.writeTimeout(Duration.ofHours(3))
.maxConcurrency(100)
.build();
S3AsyncClientBuilder s3AsyncClientBuilder = S3AsyncClient.builder()
.credentialsProvider(awsCredentialsProvider)
.region(Region.of(region))
.httpClient(nettyHttpClient);
if (endpoint.contains("localhost")) {
s3AsyncClientBuilder.endpointOverride(new URI(endpoint))
.serviceConfiguration(S3Configuration.builder().pathStyleAccessEnabled(true).build());
}
return s3AsyncClientBuilder.build();
}
@Bean(name = "wasabiS3TransferManager")
public S3TransferManager wasabiS3TransferManager(final S3AsyncClient wasabiS3Async) {
return S3TransferManager.builder()
.s3Client(wasabiS3Async)
.build();
}
}
现在这是出现问题的方法
private final S3TransferManager wasabiS3TransferManager;
public void copyFile(final String sourceFolder, final String targetFolder, final String sourceFileId, final String bucketName, final String targetFileId) {
S3TransferManager s3TransferManager = wasabiS3TransferManager;
String sourceBucketPath = String.format("%s/%s", sourceFolder, sourceFileId);
String targetBucketPath = String.format("%s/%s", targetFolder, targetFileId);
try {
CopyObjectRequest copyObjectRequest = CopyObjectRequest.builder()
.sourceBucket(bucketName)
.sourceKey(sourceBucketPath)
.destinationBucket(bucketName)
.destinationKey(targetBucketPath)
.build();
CopyRequest copyRequest = CopyRequest.builder()
.copyObjectRequest(copyObjectRequest)
.build();
Copy copy = s3TransferManager.copy(copyRequest);
copy.completionFuture().join();
} catch (Exception exception) {
log.error("There was an error", exception.getMessage());
//Exception handling happens here
}
}
这是异常消息
software.amazon.awssdk.services.s3.model.NoSuchBucketException: The specified bucket does not exist (Service: S3, Status Code: 404, Request ID: <blah>,
Extended Request ID:<blah>)
我曾认为这可能是 S3AsyncClient bean 上设置的区域存在问题,但我注入了正确的值。
如有任何帮助,我们将不胜感激
问题似乎出在 S3TransferManager 类上。如果我只是使用 S3Client 或 S3AsyncClient 复制文件,那么它复制成功(我无法直观地确认文件已正确复制,因为 Dev2 中未部署 Web。但操作完成时没有异常)。
奇怪的是,我正在使用的 S3TransferManager bean 将 S3AsyncClient bean 的实例作为其 S3Client。
所以我不确定为什么 S3AsyncClient 工作正常,但使用 S3AsyncClient 的 S3TransferManager 却不能。