【发布时间】:2022-11-21 05:56:37
【问题描述】:
简而言之:使用 AmazonS3Client 连接到 MinIO 的本地实例会导致抛出 UnknownHostException,因为 url 被解析为 http://{bucket_name}.localhost:port。
问题详细描述:
我正在为使用 AmazonS3Client 库从 S3 检索内容的 Java 服务创建集成测试。我在测试容器内使用 MinIO 来执行 Amazon S3 的角色,如下所示:
@Container
static final GenericContainer<?> minioContainer = new GenericContainer<>("minio/minio:latest")
.withCommand("server /data")
.withEnv(
Map.of(
"MINIO_ACCESS_KEY", AWS_ACCESS_KEY.getValue(),
"MINIO_SECRET_KEY", AWS_SECRET_KEY.getValue()
)
)
.withExposedPorts(MINIO_PORT)
.waitingFor(new HttpWaitStrategy()
.forPath("/minio/health/ready")
.forPort(MINIO_PORT)
.withStartupTimeout(Duration.ofSeconds(10)));
然后我使用如下方式动态导出它的 url(因为测试容器部署在随机端口):
String.format("http://%s:%s", minioContainer.getHost(), minioContainer.getFirstMappedPort())
这反过来会导致这样的网址:
http://localhost:54123
我在测试运行时遇到的问题在于 AmazonS3Client.getObject(String,String) 的实际实现 - 在创建请求时它执行以下验证(类 S3RequestEndpointResolver,方法 resolveRequestEndpoint):
...
if (shouldUseVirtualAddressing(endpoint)) {
request.setEndpoint(convertToVirtualHostEndpoint(endpoint, bucketName));
request.setResourcePath(SdkHttpUtils.urlEncode(getHostStyleResourcePath(), true));
} else {
request.setEndpoint(endpoint);
request.setResourcePath(SdkHttpUtils.urlEncode(getPathStyleResourcePath(), true));
}
}
private boolean shouldUseVirtualAddressing(final URI endpoint) {
return !isPathStyleAccess && BucketNameUtils.isDNSBucketName(bucketName)
&& !isValidIpV4Address(endpoint.getHost());
}
这反过来为 url http://localhost:54123 返回 true,因此这个方法
private static URI convertToVirtualHostEndpoint(URI endpoint, String bucketName) {
try {
return new URI(String.format("%s://%s.%s", endpoint.getScheme(), bucketName, endpoint.getAuthority()));
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Invalid bucket name: " + bucketName, e);
}
}
将存储桶的名称连接到主机,结果为:http://mybucket.localhost:54123,这最终导致抛出 UnknownHostException。我可以通过将主机设置为 0.0.0.0 而不是 localhost 来解决这个问题,但这几乎不是解决方案。
因此我想知道这是否是AmazonS3Client 中的错误/限制? ii)我是那个缺少东西的人,例如配置差?
感谢您的时间
【问题讨论】:
标签: java amazon-s3 minio testcontainers