I have a java app that is trying to use an S3Client to save files to an S3 storage space.
After a bit of trial and error, I was able to connect and prove this by creating an S3Client and verifying I'm getting back the expected list of buckets.
String accessKeyId = "MyAccessKeyId";
String secretAccesskey = "MySecretAccessKey";
StaticCredentialsProvider credentialsProvider = StaticCredentialsProvider.create(
AwsBasicCredentials.create(accessKeyId, secretAccesskey));
// Create S3 client
S3Client s3Client = S3Client.builder()
.credentialsProvider(credentialsProvider)
.region(Region.US_EAST_1)
.endpointOverride(URI.create("https://cees3.bhinc.gov:10444"))
.overrideConfiguration(ClientOverrideConfiguration.builder()
.build())
.build();
//I've verified that I'm getting back an expected list of buckets
ListBucketsResponse listBucketsResponse = s3Client.listBuckets();
When I try to actually place a file into one of the buckets, however I get the following error:
software.amazon.awssdk.core.exception.SdkClientException: Received an UnknownHostException
What I don't understand is why I would be getting that particular error, as it seems I would have gotten that same error when trying to list the buckets.
This is my code to try and upload a file - which as you can see is basically the same thing only I'm trying to upload a file to one of the buckets rather than list the buckets.
String accessKeyId = "MyAccessKeyId";
String secretAccesskey = "MySecretAccessKey";
StaticCredentialsProvider credentialsProvider = StaticCredentialsProvider.create(
AwsBasicCredentials.create(accessKeyId, secretAccesskey));
// Create S3 client
S3Client s3Client = S3Client.builder()
.credentialsProvider(credentialsProvider)
.region(Region.US_EAST_1)
.endpointOverride(URI.create("https://cees3.bhinc.gov:10444"))
.overrideConfiguration(ClientOverrideConfiguration.builder()
.build())
.build();
String bucketName = "testbucket2";
String testFilePath = "C:\\Users\\charlie\\Downloads\\test.png";
// Upload a file
File file = new File(testFilePath);
try (FileInputStream fileInputStream = new FileInputStream(file)) {
String fileExtension = Files.probeContentType(Paths.get(testFilePath));
PutObjectRequest request = PutObjectRequest.builder()
.bucket(bucketName)
.key(accessKeyId)
.contentType(fileExtension)
.build();
// Get the file content as a byte array
byte[] bytes = fileInputStream.readAllBytes();
s3Client.putObject(request, RequestBody.fromBytes(bytes));
System.out.println("File uploaded successfully: " + "test.png");
} catch (IOException e) {
System.err.println("Error uploading file: " + e.getMessage());
}
But as soon as it gets to s3Client.putObject it throws the UnknownHostException.
Any ideas as to why I would get that when trying to upload a file but not when just listing the existing buckets?
Thank you
So API Gateways have a policy associated with them that will limit what you can do through that proxy. As you noted https://cees3.bhinc.gov:10444 is an API Gateway, and you are accessing things over https so I suspect there is a custom certificate for this endpoint and that certificate is tied to cees3.bhinc.gov. This is why if you try to access the bucket through normal S3 you get back a certificate that doesn't match the default AWS hostname being used and it throws a SunCertPathBuilderException. Hence why you must override the host being used to the API gateway.
I think the policy attached to the gateway allows you to list the bucket, but doesn't all you to modify it in anyway (putObject, createObject, etc). So my suggestion is if you have access to the AWS console and S3 go check the policy on the gateway. See what it allows. If it doesn't allow putObject add it and see if the exception goes away. If you don't have access you'll need to contact someone who does have access to the policy and you can work with them to set the right permissions on it.