-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MultiLang AWS SDK v1 to v2 #1
Conversation
...ang/src/main/java/software/amazon/kinesis/multilang/config/MultiLangDaemonConfiguration.java
Outdated
Show resolved
Hide resolved
...esis-client-multilang/src/main/java/software/amazon/kinesis/multilang/NestedPropertyKey.java
Show resolved
Hide resolved
...rc/main/java/software/amazon/kinesis/multilang/auth/KclStsAssumeRoleCredentialsProvider.java
Show resolved
Hide resolved
return constructor.construct(); | ||
} catch (InstantiationException e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is sloppy and needs a second look. The issue here is that we relied on this provider constructor to create any provider class that is passed to this function.
However, in our tests, we use software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider
. This used to be invoked like new DefaultCredentialsProvider
but now is constructed with DefaultCredentialsProvider.create()
- https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/migration-client-credentials.html
I tried to generalize this to work with both, but its quite sloppy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that we just want v2 support now and the v2 credential providers are either created using create
or builder
do we still need this check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Users can still create classes that implement the v2 AwsCredentialsProvider
that use a default constructor clazz::newInstance
instead of a builder
/create
.
For instance, we create a basic AwsCredentialsProvider that relies on a default constructor in our testing.
Since this is still a valid way to create v2 providers, I think this code should support both a .create()
method and a constructor method of instantiating providers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another thing to consider is that we currently support passing args to default constructors through the config like ConstructorCredentialsProvider|arg1|arg2
. This eventually calls a constructor like provider = ConstructorCredentialsProvider(arg1, arg2)
, allowing the user to pass in a provider string with constructor args. This still works as expected for classes with public static constructors.
I don't think this is possible for the providers that require builders, though. For instance, if a user wanted to create a DefaultCredentialsProvider with profileName = "test-profile"
like DefaultCredentialsProvider.builder().profileName("Test").build()
, the code currently doesn't support this.
In this version of the code DefaultCredentialsProvider|test-profile
, we would try and fail to call a new instance like DefaultCredentialsProvider("test-profile"), and so it would invoke DefaultCredentialsProvider.create() to create a default instance of the class.
So currently, that .create() block is just to create a default builder instance if there's no basic constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we should come up with a way that's easy for customer to use the default credential providers without having to peek into the multilang code or documentation to pick the providers. Let's iterate on this
.../src/main/java/software/amazon/kinesis/multilang/config/credentials/V2CredentialWrapper.java
Outdated
Show resolved
Hide resolved
...rc/main/java/software/amazon/kinesis/multilang/auth/KclStsAssumeRoleCredentialsProvider.java
Outdated
Show resolved
Hide resolved
...ain/java/software/amazon/kinesis/multilang/auth/StsAssumeRoleCredentialsProviderFactory.java
Outdated
Show resolved
Hide resolved
...ain/java/software/amazon/kinesis/multilang/auth/StsAssumeRoleCredentialsProviderFactory.java
Outdated
Show resolved
Hide resolved
...rc/main/java/software/amazon/kinesis/multilang/auth/KclStsAssumeRoleCredentialsProvider.java
Show resolved
Hide resolved
...ava/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java
Show resolved
Hide resolved
provider = constructProvider( | ||
providerName, | ||
() -> { | ||
Class<?>[] argTypes = new Class<?>[nameAndArgs.length - 1]; | ||
Arrays.fill(argTypes, String.class); | ||
return clazz.getConstructor(argTypes).newInstance(varargs); | ||
}, | ||
clazz); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new V2 providers are constructed using builders correct? Are they able use the same constructing logic as v1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New providers are constructed with builders / a create()
call to build a generic instance, old providers were created with simple constructors.
To build the old providers generically, we used clazz::newInstance
. This will fail for the v2 versions and throw a InstantiationException
. To build the new providers generically, my only idea was to catch this InstantiationException
and try something like
Method createMethod = clazz.getDeclaredMethod("create");
Object provider = createMethod.invoke(null);
This makes things a bit complicated, as we are trying to generically build these classes in 2 different ways in one function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simplified this a bit. Now added an additional attempt to construct create() without touching constructProvider().
return constructor.construct(); | ||
} catch (InstantiationException e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that we just want v2 support now and the v2 credential providers are either created using create
or builder
do we still need this check?
...ava/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java
Outdated
Show resolved
Hide resolved
import software.amazon.kinesis.multilang.NestedPropertyKey; | ||
import software.amazon.kinesis.multilang.NestedPropertyProcessor; | ||
|
||
public class KclStsAssumeRoleCredentialsProvider implements AwsCredentialsProvider, NestedPropertyProcessor { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not a blocker for this PR - This class is an extension of the StsProvider. I feel like the users should not have to pick between the normal stsProvider and KCLstsProvider if they want to add extra fields like externalId etc... We can direct all construction of stsProvider to this class internally so users can use all of its feature by declaring the generic stsProvider in the property file.
I think this is especially important for sdk v2 because credential providers don't provide constructors anymore and this stsProvider doesn't have a create() method either meaning that we will need to rely on this class to build stsProvider
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, agreed. The old docs described creating an STSAssumeRoleSessionCredentialsProvider from the config, which relied on a deprecated constructor for the STSAssumeRoleSessionCredentialsProvider.
As you said, this is no longer possible because the v2 StsAssumeRoleCredentialsProvider requires a builder, so we can't use a simple constructor. In that way, we are forcing users to use the KclStsAssumeRoleCredentialsProvider as I mentioned in the documentation changes.
@@ -113,6 +117,20 @@ private static List<AWSCredentialsProvider> getValidCredentialsProviders(List<St | |||
provider = constructProvider(providerName, clazz::newInstance); | |||
} | |||
|
|||
if (provider == null) { | |||
// if still not found, try empty create() method |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we could try passing in all the args that are in the property file to the create() method? This provides more flexibility and It might not create the expected credential provider if not taking the extra args anyway. But let's see what solution we decide to use for builder based credential providers and we can iterate on it
return constructor.construct(); | ||
} catch (InstantiationException e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we should come up with a way that's easy for customer to use the default credential providers without having to peek into the multilang code or documentation to pick the providers. Let's iterate on this
No description provided.