AWS: update test cases to verify credentials for the prefixed S3 client#13118
Conversation
| assertThat(actualConfiguration).isNotNull(); | ||
| try { | ||
| actualConfiguration.credentialsProvider().resolveIdentity(); | ||
| } catch (SdkClientException e) { |
There was a problem hiding this comment.
please use assertThatThrownBy(..).isInstanceOf(..).hasMessage(..) instead of a try-catch block
There was a problem hiding this comment.
please use
assertThatThrownBy(..).isInstanceOf(..).hasMessage(..)instead of a try-catch block
thanks for your advice, updated.
| // Do not override s3 client if it was provided | ||
| if (s3 == null) { | ||
| Object clientFactory = S3FileIOAwsClientFactories.initialize(props); | ||
| Object clientFactory = S3FileIOAwsClientFactories.initialize(propertiesWithCredentials); |
There was a problem hiding this comment.
FYI this is going to be fixed by #12799 but it's still good to get the tests in
There was a problem hiding this comment.
FYI this is going to be fixed by #12799 but it's still good to get the tests in
Thanks for the reminder, this feature looks great!
|
#12799 has been merged before I had the chance to merge your PR. Can you rebase this please so that we can get the tests in |
667dcc5 to
25380da
Compare
sure, I've reverted the change. |
d177782 to
7eb6fa0
Compare
53823a2 to
6101aae
Compare
nastra
left a comment
There was a problem hiding this comment.
we pretty much have already existing tests where the storage credentials (and the credentials in the properties) are configured. So rather than introducing new test methods I would suggest to just add the important assertion to the existing tests. This would then look like the following diff and should cover all cases that are needed.
Also please make sure to update the PR title to reflect the scope/intention (since it's not passing storage credentials anymore)
diff --git a/aws/src/integration/java/org/apache/iceberg/aws/s3/TestS3FileIO.java b/aws/src/integration/java/org/apache/iceberg/aws/s3/TestS3FileIO.java
index 85453cba97..965e1c6068 100644
--- a/aws/src/integration/java/org/apache/iceberg/aws/s3/TestS3FileIO.java
+++ b/aws/src/integration/java/org/apache/iceberg/aws/s3/TestS3FileIO.java
@@ -41,6 +41,7 @@ import java.util.Random;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.UUID;
+import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
@@ -89,8 +90,12 @@ import org.mockito.Mockito;
import org.testcontainers.containers.MinIOContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
+import software.amazon.awssdk.awscore.AwsServiceClientConfiguration;
+import software.amazon.awssdk.core.exception.SdkClientException;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient;
+import software.amazon.awssdk.identity.spi.AwsSessionCredentialsIdentity;
+import software.amazon.awssdk.identity.spi.IdentityProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.S3Client;
@@ -730,10 +735,23 @@ public class TestS3FileIO {
s3FileIOProperties
.extracting(S3FileIOProperties::sessionToken)
.isEqualTo("sessionTokenFromProperties");
+
+ // verify that the credentials identity gets the correct credentials for the prefixed S3 client
+ assertThat(fileIO.client("s3://my-bucket/table1").serviceClientConfiguration())
+ .extracting(AwsServiceClientConfiguration::credentialsProvider)
+ .extracting(IdentityProvider::resolveIdentity)
+ .satisfies(
+ x -> {
+ AwsSessionCredentialsIdentity identity = (AwsSessionCredentialsIdentity) x.get();
+ assertThat(identity).isNotNull();
+ assertThat(identity.accessKeyId()).isEqualTo("keyIdFromProperties");
+ assertThat(identity.secretAccessKey()).isEqualTo("accessKeyFromProperties");
+ assertThat(identity.sessionToken()).isEqualTo("sessionTokenFromProperties");
+ });
}
@Test
- public void singleStorageCredentialConfigured() {
+ public void singleStorageCredentialConfigured() throws ExecutionException, InterruptedException {
StorageCredential s3Credential =
StorageCredential.create(
"s3://custom-uri",
@@ -782,6 +800,32 @@ public class TestS3FileIO {
s3FileIOProperties
.extracting(S3FileIOProperties::sessionToken)
.isEqualTo("sessionTokenFromCredential");
+
+ // verify that the credentials identity gets the correct credentials for the generic S3 client
+ assertThat(fileIO.client().serviceClientConfiguration())
+ .extracting(AwsServiceClientConfiguration::credentialsProvider)
+ .extracting(IdentityProvider::resolveIdentity)
+ .satisfies(
+ x -> {
+ AwsSessionCredentialsIdentity identity = (AwsSessionCredentialsIdentity) x.get();
+ assertThat(identity).isNotNull();
+ assertThat(identity.accessKeyId()).isEqualTo("keyIdFromProperties");
+ assertThat(identity.secretAccessKey()).isEqualTo("accessKeyFromProperties");
+ assertThat(identity.sessionToken()).isEqualTo("sessionTokenFromProperties");
+ });
+
+ // verify that the credentials identity gets the correct credentials for the prefixed S3 client
+ assertThat(fileIO.client("s3://custom-uri/table2").serviceClientConfiguration())
+ .extracting(AwsServiceClientConfiguration::credentialsProvider)
+ .extracting(IdentityProvider::resolveIdentity)
+ .satisfies(
+ x -> {
+ AwsSessionCredentialsIdentity identity = (AwsSessionCredentialsIdentity) x.get();
+ assertThat(identity).isNotNull();
+ assertThat(identity.accessKeyId()).isEqualTo("keyIdFromCredential");
+ assertThat(identity.secretAccessKey()).isEqualTo("accessKeyFromCredential");
+ assertThat(identity.sessionToken()).isEqualTo("sessionTokenFromCredential");
+ });
}
@Test
@@ -851,6 +895,19 @@ public class TestS3FileIO {
.extracting(S3FileIOProperties::sessionToken)
.isEqualTo("sessionTokenFromCredential1");
+ // verify that the credentials identity gets the correct credentials for the prefixed S3 client
+ assertThat(fileIO.client("s3://custom-uri/1").serviceClientConfiguration())
+ .extracting(AwsServiceClientConfiguration::credentialsProvider)
+ .extracting(IdentityProvider::resolveIdentity)
+ .satisfies(
+ x -> {
+ AwsSessionCredentialsIdentity identity = (AwsSessionCredentialsIdentity) x.get();
+ assertThat(identity).isNotNull();
+ assertThat(identity.accessKeyId()).isEqualTo("keyIdFromCredential1");
+ assertThat(identity.secretAccessKey()).isEqualTo("accessKeyFromCredential1");
+ assertThat(identity.sessionToken()).isEqualTo("sessionTokenFromCredential1");
+ });
+
ObjectAssert<S3FileIOProperties> s3FileIOProperties2 =
assertThat(fileIO.clientForStoragePath("s3://custom-uri/2/table1").s3FileIOProperties());
s3FileIOProperties2
@@ -862,6 +919,62 @@ public class TestS3FileIO {
s3FileIOProperties2
.extracting(S3FileIOProperties::sessionToken)
.isEqualTo("sessionTokenFromCredential2");
+
+ // verify that the credentials identity gets the correct credentials for the prefixed S3 client
+ assertThat(fileIO.client("s3://custom-uri/2").serviceClientConfiguration())
+ .extracting(AwsServiceClientConfiguration::credentialsProvider)
+ .extracting(IdentityProvider::resolveIdentity)
+ .satisfies(
+ x -> {
+ AwsSessionCredentialsIdentity identity = (AwsSessionCredentialsIdentity) x.get();
+ assertThat(identity).isNotNull();
+ assertThat(identity.accessKeyId()).isEqualTo("keyIdFromCredential2");
+ assertThat(identity.secretAccessKey()).isEqualTo("accessKeyFromCredential2");
+ assertThat(identity.sessionToken()).isEqualTo("sessionTokenFromCredential2");
+ });
+ }
+
+ @Test
+ public void storageCredentialsConfiguredWithoutCredentialsInProperties() {
+ StorageCredential s3Credential =
+ StorageCredential.create(
+ "s3://custom-uri/1",
+ ImmutableMap.of(
+ "s3.access-key-id",
+ "keyIdFromCredential",
+ "s3.secret-access-key",
+ "accessKeyFromCredential",
+ "s3.session-token",
+ "sessionTokenFromCredential"));
+
+ S3FileIO fileIO = new S3FileIO();
+ fileIO.setCredentials(ImmutableList.of(s3Credential));
+ fileIO.initialize(ImmutableMap.of("client.region", "us-east-1"));
+
+ // verify that the credentials identity gets the correct credentials for the prefixed S3 client
+ assertThat(fileIO.client("s3://custom-uri/1").serviceClientConfiguration())
+ .extracting(AwsServiceClientConfiguration::credentialsProvider)
+ .extracting(IdentityProvider::resolveIdentity)
+ .satisfies(
+ x -> {
+ AwsSessionCredentialsIdentity identity = (AwsSessionCredentialsIdentity) x.get();
+ assertThat(identity).isNotNull();
+ assertThat(identity.accessKeyId()).isEqualTo("keyIdFromCredential");
+ assertThat(identity.secretAccessKey()).isEqualTo("accessKeyFromCredential");
+ assertThat(identity.sessionToken()).isEqualTo("sessionTokenFromCredential");
+ });
+
+ // there are no credentials for the generic S3 client configured, since there are no credentials
+ // passed in the properties
+ assertThatThrownBy(
+ () ->
+ fileIO
+ .client()
+ .serviceClientConfiguration()
+ .credentialsProvider()
+ .resolveIdentity())
+ .isInstanceOf(SdkClientException.class)
+ .hasMessageContaining("Unable to load credentials from any of the providers");
}
private void createRandomObjects(String prefix, int count) {
| } | ||
|
|
||
| @Test | ||
| public void storageCredentialsConfiguredOverwriteCredentialsInProperties() |
There was a problem hiding this comment.
this is already covered in existing tests
| } | ||
|
|
||
| @Test | ||
| public void storageCredentialsConfiguredWithoutCredentialsInProperties() { |
There was a problem hiding this comment.
this is already covered in existing tests
nastra
left a comment
There was a problem hiding this comment.
LGTM but I would remove the two test methods that I commented on, since those are already covered in existing tests
Pass the storage credential when initializing S3FileIOAwsClientFactories.