From 1e708e119638025c2d85c34c52dba75a8b1c2a02 Mon Sep 17 00:00:00 2001 From: Ethan Katnic Date: Wed, 4 Sep 2024 10:30:56 -0700 Subject: [PATCH 1/7] Add tests to validate create() method providers and StsAssumeRoleCredentialsProvider --- ...tialsProviderPropertyValueDecoderTest.java | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/config/AWSCredentialsProviderPropertyValueDecoderTest.java b/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/config/AWSCredentialsProviderPropertyValueDecoderTest.java index 58bca383..71f97d18 100644 --- a/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/config/AWSCredentialsProviderPropertyValueDecoderTest.java +++ b/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/config/AWSCredentialsProviderPropertyValueDecoderTest.java @@ -40,6 +40,7 @@ public class AWSCredentialsProviderPropertyValueDecoderTest { private final String credentialName1 = AlwaysSucceedCredentialsProvider.class.getName(); private final String credentialName2 = ConstructorCredentialsProvider.class.getName(); + private final String createCredentialClass = CreateProvider.class.getName(); private final AwsCredentialsProviderPropertyValueDecoder decoder = new AwsCredentialsProviderPropertyValueDecoder(); @ToString @@ -119,13 +120,31 @@ public class AWSCredentialsProviderPropertyValueDecoderTest { public void testKclAuthProvider() { for (final String className : Arrays.asList( KclStsAssumeRoleCredentialsProvider.class.getName(), // fully-qualified name - KclStsAssumeRoleCredentialsProvider.class.getSimpleName() // name-only; needs prefix - )) { + KclStsAssumeRoleCredentialsProvider.class.getSimpleName(), // name-only; needs prefix + "software.amazon.awssdk.auth.credentials.StsAssumeRoleCredentialsProvider")) { final AwsCredentialsProvider provider = decoder.decodeValue(className + "|arn|sessionName"); assertNotNull(className, provider); } } + /** + * Test that OneArgCreateProvider in the SDK v2 can process a create() method + */ + @Test + public void testEmptyCreateProvider() { + AwsCredentialsProvider provider = decoder.decodeValue(createCredentialClass); + assertThat(provider, hasCredentials(TEST_ACCESS_KEY_ID, TEST_SECRET_KEY)); + } + + /** + * Test that OneArgCreateProvider in the SDK v2 can process a create(arg1) method + */ + @Test + public void testOneArgCreateProvider() { + AwsCredentialsProvider provider = decoder.decodeValue(createCredentialClass + "|testCreateProperty"); + assertThat(provider, hasCredentials("testCreateProperty", TEST_SECRET_KEY)); + } + /** * Test that a provider can be instantiated by its varargs constructor. */ @@ -188,4 +207,28 @@ public class AWSCredentialsProviderPropertyValueDecoderTest { return AwsBasicCredentials.create(flattenedArgs, flattenedArgs); } } + + /** + * Credentials provider to test AWS SDK v2 create() methods for providers like ProfileCredentialsProvider + */ + public static class CreateProvider implements AwsCredentialsProvider { + private String accessKeyId; + + private CreateProvider(String accessKeyId) { + this.accessKeyId = accessKeyId; + } + + public static CreateProvider create() { + return new CreateProvider(TEST_ACCESS_KEY_ID); + } + + public static CreateProvider create(String accessKeyId) { + return new CreateProvider(accessKeyId); + } + + @Override + public AwsCredentials resolveCredentials() { + return AwsBasicCredentials.create(accessKeyId, TEST_SECRET_KEY); + } + } } From 892cc79dfcca7d6a249f189227ec06259e255014 Mon Sep 17 00:00:00 2001 From: Ethan Katnic Date: Wed, 4 Sep 2024 10:31:43 -0700 Subject: [PATCH 2/7] Add functionality to decoder for create(arg) providers and refactor provider creation --- ...edentialsProviderPropertyValueDecoder.java | 138 +++++++++++++----- 1 file changed, 98 insertions(+), 40 deletions(-) diff --git a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java index 112fb52c..e42d1942 100644 --- a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java +++ b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java @@ -79,58 +79,24 @@ class AwsCredentialsProviderPropertyValueDecoder implements IPropertyValueDecode for (String providerName : providerNames) { final String[] nameAndArgs = providerName.split("\\" + ARG_DELIMITER); - final Class clazz; - try { - final Class c = Class.forName(nameAndArgs[0]); - if (!AwsCredentialsProvider.class.isAssignableFrom(c)) { - continue; - } - clazz = (Class) c; - } catch (ClassNotFoundException cnfe) { - // Providers are a product of prefixed Strings to cover multiple - // namespaces (e.g., "Foo" -> { "some.auth.Foo", "kcl.auth.Foo" }). - // It's expected that many class names will not resolve. + final Class clazz = getClass(nameAndArgs[0]); + if (clazz == null) { continue; } - log.info("Attempting to construct {}", clazz); - AwsCredentialsProvider provider = null; if (nameAndArgs.length > 1) { final String[] varargs = Arrays.copyOfRange(nameAndArgs, 1, nameAndArgs.length); - - // attempt to invoke an explicit N-arg constructor of FooClass(String, String, ...) - provider = constructProvider(providerName, () -> { - Class[] argTypes = new Class[nameAndArgs.length - 1]; - Arrays.fill(argTypes, String.class); - return clazz.getConstructor(argTypes).newInstance(varargs); - }); - + provider = tryConstructorWithArgs(providerName, clazz, varargs); if (provider == null) { - // attempt to invoke a public varargs/array constructor of FooClass(String[]) - provider = constructProvider(providerName, () -> clazz.getConstructor(String[].class) - .newInstance((Object) varargs)); + provider = tryCreateWithArgs(providerName, clazz, varargs); } } - if (provider == null) { - // regardless of parameters, fallback to invoke a public no-arg constructor - provider = constructProvider(providerName, clazz::newInstance); + provider = tryConstructorWithNoArgs(providerName, clazz); } - if (provider == null) { - // if still not found, try empty create() method - try { - Method createMethod = clazz.getDeclaredMethod("create"); - if (Modifier.isStatic(createMethod.getModifiers())) { - provider = constructProvider(providerName, () -> clazz.cast(createMethod.invoke(null))); - } else { - log.warn("Found non-static create() method in {}", providerName); - } - } catch (NoSuchMethodException e) { - // No create() method found for class - } + provider = tryCreateWithNoArgs(providerName, clazz); } - if (provider != null) { credentialsProviders.add(provider); } @@ -138,6 +104,98 @@ class AwsCredentialsProviderPropertyValueDecoder implements IPropertyValueDecode return credentialsProviders; } + private static AwsCredentialsProvider tryConstructorWithArgs( + String providerName, Class clazz, String[] varargs) { + AwsCredentialsProvider provider = + constructProvider(providerName, () -> getConstructorWithVarArgs(clazz, varargs)); + if (provider == null) { + provider = constructProvider(providerName, () -> getConstructorWithArgs(clazz, varargs)); + } + return provider; + } + + private static AwsCredentialsProvider tryCreateWithArgs( + String providerName, Class clazz, String[] varargs) { + AwsCredentialsProvider provider = + constructProvider(providerName, () -> getCreateMethod(clazz, (Object) varargs)); + if (provider == null) { + provider = constructProvider(providerName, () -> getCreateMethod(clazz, varargs)); + } + return provider; + } + + private static AwsCredentialsProvider tryConstructorWithNoArgs( + String providerName, Class clazz) { + return constructProvider(providerName, clazz::newInstance); + } + + private static AwsCredentialsProvider tryCreateWithNoArgs( + String providerName, Class clazz) { + return constructProvider(providerName, () -> getCreateMethod(clazz)); + } + + private static AwsCredentialsProvider getConstructorWithVarArgs( + Class clazz, String[] varargs) { + try { + return clazz.getConstructor(String[].class).newInstance((Object) varargs); + } catch (Exception e) { + return null; + } + } + + private static AwsCredentialsProvider getConstructorWithArgs( + Class clazz, String[] varargs) { + try { + Class[] argTypes = new Class[varargs.length]; + Arrays.fill(argTypes, String.class); + return clazz.getConstructor(argTypes).newInstance((Object[]) varargs); + } catch (Exception e) { + return null; + } + } + + private static AwsCredentialsProvider getCreateMethod( + Class clazz, Object... args) { + try { + Class[] argTypes = new Class[args.length]; + for (int i = 0; i < args.length; i++) { + argTypes[i] = args[i].getClass(); + } + Method createMethod = clazz.getDeclaredMethod("create", argTypes); + if (Modifier.isStatic(createMethod.getModifiers())) { + return clazz.cast(createMethod.invoke(null, args)); + } else { + log.warn("Found non-static create() method in {}", clazz.getName()); + } + } catch (NoSuchMethodException e) { + // No matching create method found for class + } catch (Exception e) { + log.warn("Failed to invoke create() method in {}", clazz.getName(), e); + } + return null; + } + + private static Class getClass(String providerName) { + String className = providerName.replace( + "software.amazon.awssdk.auth.credentials.StsAssumeRoleCredentialsProvider", + "software.amazon.kinesis.multilang.auth.KclStsAssumeRoleCredentialsProvider"); + final Class clazz; + try { + final Class c = Class.forName(className); + if (!AwsCredentialsProvider.class.isAssignableFrom(c)) { + return null; + } + clazz = (Class) c; + } catch (ClassNotFoundException cnfe) { + // Providers are a product of prefixed Strings to cover multiple + // namespaces (e.g., "Foo" -> { "some.auth.Foo", "kcl.auth.Foo" }). + // It's expected that many class names will not resolve. + return null; + } + log.info("Attempting to construct {}", clazz); + return clazz; + } + private static List getProviderNames(String property) { // assume list delimiter is "," String[] elements = property.split(LIST_DELIMITER); From 90d984b67048576cc0358b04bdd74aa93c690856 Mon Sep 17 00:00:00 2001 From: Ethan Katnic Date: Wed, 4 Sep 2024 10:38:15 -0700 Subject: [PATCH 3/7] Add method header for getClass helper --- .../AwsCredentialsProviderPropertyValueDecoder.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java index e42d1942..ff1b19e7 100644 --- a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java +++ b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java @@ -175,6 +175,14 @@ class AwsCredentialsProviderPropertyValueDecoder implements IPropertyValueDecode return null; } + /** + * Resolves the class for the given provider name and arguments. + * + * @param providerName A string containing the provider name. + * + * @return The Class object representing the resolved AwsCredentialsProvider implementation, + * or null if the class cannot be resolved or does not extend AwsCredentialsProvider. + */ private static Class getClass(String providerName) { String className = providerName.replace( "software.amazon.awssdk.auth.credentials.StsAssumeRoleCredentialsProvider", From 3923eb8beee4e417a182f3f95fc7cc64285a60bd Mon Sep 17 00:00:00 2001 From: Ethan Katnic Date: Wed, 4 Sep 2024 10:58:50 -0700 Subject: [PATCH 4/7] Rewrite credentials doc to be consistent with v2 changes --- .../configuring-credential-providers.md | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/docs/multilang/configuring-credential-providers.md b/docs/multilang/configuring-credential-providers.md index c8401d9e..55318d4f 100644 --- a/docs/multilang/configuring-credential-providers.md +++ b/docs/multilang/configuring-credential-providers.md @@ -7,23 +7,28 @@ However, KCL now provides better extensibility to handle, and be enhanced to han This document should help multilang customers configure a suitable `CredentialProvider` (or contribute changes to support a new use case!). ## Sample Provider Configuration -DEPRECATED: StsAssumeRoleCredentialsProvider can no longer be constructed in this way: -``` -AWSCredentialsProvider = StsAssumeRoleCredentialsProvider||` -``` -To create a [StsAssumeRoleCredentialsProvider][sts-assume-provider], see KclStsAssumeRoleCredentialsProvider below. +In a Properties file, an `AWSCredentialsProperty` configuration might look like: +``` +AWSCredentialsProvider = StsAssumeRoleCredentialsProvider|| +``` +This basic configuration creates an [StsAssumeRoleCredentialsProvider][sts-assume-provider] with an ARN and session name. -You can create a default [DefaultCredentialsProvider][default-credentials-provider] or [AnonymousCredentialsProvider][anonymous-credentials-provider] -by passing it in the config like: +While functional, this configuration is limited. +For example, this configuration cannot set a regional endpoint (e.g., VPC use case). + +Leveraging nested properties, an `AWSCredentialsProperty` value might change to: +``` +AWSCredentialsProvider = KclSTSAssumeRoleSessionCredentialsProvider||\ + |endpointRegion=us-east-1|externalId=spartacus +``` +N.B. Backslash (`\`) is for multi-line legibility and is not required. + +You can create a default [DefaultCredentialsProvider][default-credentials-provider] by passing it in the config like: ``` AWSCredentialsProvider = DefaultCredentialsProvider ``` -If you wish to customize properties on an AWS SDK provider that uses a builder, like the StsASsumeRoleCredentialsProvider, -you will need to wrap this provider class, provide a constructor, and manage the build of the provider. -See implementation of [KclStsAssumeRoleCredentialsProvider][kcl-sts-provider] - ## Nested Properties KCL multilang supports "nested properties" on the `AWSCredentialsProvider` key in the properties file. @@ -37,6 +42,10 @@ The [Backus-Naur form][bnf] of the value: # this depends on the nested key ``` +In general, required parameters are passed directly to the class' constructor or .create() method +(e.g., [ProfileCredentialsProvider(String)][profile-credentials-provider-create]). However, most of these providers +require builders and will require a custom implementation similar to `KclStsAssumeRoleCredentialsProvider` for customization + Nested properties are a custom mapping provided by KCL multilang, and do not exist in the AWS SDK. See [NestedPropertyKey][nested-property-key] for the supported keys, and details on their expected values. @@ -73,5 +82,5 @@ AWSCredentialsProvider = KclStsAssumeRoleCredentialsProvider|| [nested-property-key]: /amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/NestedPropertyKey.java [nested-property-processor]: /amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/NestedPropertyProcessor.java [sts-assume-provider]: https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sts/auth/StsAssumeRoleCredentialsProvider.html +[profile-credentials-provider-create]: https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/ProfileCredentialsProvider.html#create(java.lang.String) [default-credentials-provider]: https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/DefaultCredentialsProvider.html -[anonymous-credentials-provider]: https://sdk.amazonaws.com/java/api/2.0.0-preview-11/software/amazon/awssdk/auth/credentials/AnonymousCredentialsProvider.html From 4d5a3995f0a3a7381b944d13efa0ff958a92d1ff Mon Sep 17 00:00:00 2001 From: Ethan Katnic Date: Thu, 5 Sep 2024 08:53:50 -0700 Subject: [PATCH 5/7] Fix method header to remove unused param description --- .../config/AwsCredentialsProviderPropertyValueDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java index ff1b19e7..777448f8 100644 --- a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java +++ b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java @@ -176,7 +176,7 @@ class AwsCredentialsProviderPropertyValueDecoder implements IPropertyValueDecode } /** - * Resolves the class for the given provider name and arguments. + * Resolves the class for the given provider name. * * @param providerName A string containing the provider name. * From ac7d975c5fd2c56e26b6f6aeac4ce0c59119df46 Mon Sep 17 00:00:00 2001 From: Ethan Katnic Date: Thu, 5 Sep 2024 09:39:22 -0700 Subject: [PATCH 6/7] Specify sts provider path for conversion to kclStsProvider --- .../AwsCredentialsProviderPropertyValueDecoder.java | 12 ++++++++---- ...SCredentialsProviderPropertyValueDecoderTest.java | 4 +++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java index 777448f8..fc0ff58f 100644 --- a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java +++ b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java @@ -27,6 +27,8 @@ import java.util.stream.Stream; import lombok.extern.slf4j.Slf4j; import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; import software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain; +import software.amazon.awssdk.services.sts.auth.StsAssumeRoleCredentialsProvider; +import software.amazon.kinesis.multilang.auth.KclStsAssumeRoleCredentialsProvider; /** * Get AwsCredentialsProvider property. @@ -184,12 +186,14 @@ class AwsCredentialsProviderPropertyValueDecoder implements IPropertyValueDecode * or null if the class cannot be resolved or does not extend AwsCredentialsProvider. */ private static Class getClass(String providerName) { - String className = providerName.replace( - "software.amazon.awssdk.auth.credentials.StsAssumeRoleCredentialsProvider", - "software.amazon.kinesis.multilang.auth.KclStsAssumeRoleCredentialsProvider"); + // Convert any form of StsAssumeRoleCredentialsProvider string to KclStsAssumeRoleCredentialsProvider + if (providerName.equals(StsAssumeRoleCredentialsProvider.class.getSimpleName()) + || providerName.equals(StsAssumeRoleCredentialsProvider.class.getName())) { + providerName = KclStsAssumeRoleCredentialsProvider.class.getName(); + } final Class clazz; try { - final Class c = Class.forName(className); + final Class c = Class.forName(providerName); if (!AwsCredentialsProvider.class.isAssignableFrom(c)) { return null; } diff --git a/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/config/AWSCredentialsProviderPropertyValueDecoderTest.java b/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/config/AWSCredentialsProviderPropertyValueDecoderTest.java index 71f97d18..f56c5407 100644 --- a/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/config/AWSCredentialsProviderPropertyValueDecoderTest.java +++ b/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/config/AWSCredentialsProviderPropertyValueDecoderTest.java @@ -25,6 +25,7 @@ import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; import software.amazon.awssdk.auth.credentials.AwsCredentials; import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; import software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain; +import software.amazon.awssdk.services.sts.auth.StsAssumeRoleCredentialsProvider; import software.amazon.kinesis.multilang.auth.KclStsAssumeRoleCredentialsProvider; import static org.hamcrest.CoreMatchers.equalTo; @@ -121,7 +122,8 @@ public class AWSCredentialsProviderPropertyValueDecoderTest { for (final String className : Arrays.asList( KclStsAssumeRoleCredentialsProvider.class.getName(), // fully-qualified name KclStsAssumeRoleCredentialsProvider.class.getSimpleName(), // name-only; needs prefix - "software.amazon.awssdk.auth.credentials.StsAssumeRoleCredentialsProvider")) { + StsAssumeRoleCredentialsProvider.class.getName(), // user passes full sts package path + StsAssumeRoleCredentialsProvider.class.getSimpleName())) { final AwsCredentialsProvider provider = decoder.decodeValue(className + "|arn|sessionName"); assertNotNull(className, provider); } From f87bf83deb3e6b3fdb6cd43454fff78eb90d0d37 Mon Sep 17 00:00:00 2001 From: Ethan Katnic Date: Mon, 9 Sep 2024 13:26:51 -0700 Subject: [PATCH 7/7] Reorganize getValidCredentialsProviders to simplify calls --- ...edentialsProviderPropertyValueDecoder.java | 42 +++++++------------ 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java index fc0ff58f..c134be59 100644 --- a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java +++ b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java @@ -85,19 +85,12 @@ class AwsCredentialsProviderPropertyValueDecoder implements IPropertyValueDecode if (clazz == null) { continue; } - AwsCredentialsProvider provider = null; - if (nameAndArgs.length > 1) { - final String[] varargs = Arrays.copyOfRange(nameAndArgs, 1, nameAndArgs.length); - provider = tryConstructorWithArgs(providerName, clazz, varargs); - if (provider == null) { - provider = tryCreateWithArgs(providerName, clazz, varargs); - } - } + log.info("Attempting to construct {}", clazz); + final String[] varargs = + nameAndArgs.length > 1 ? Arrays.copyOfRange(nameAndArgs, 1, nameAndArgs.length) : new String[0]; + AwsCredentialsProvider provider = tryConstructor(providerName, clazz, varargs); if (provider == null) { - provider = tryConstructorWithNoArgs(providerName, clazz); - } - if (provider == null) { - provider = tryCreateWithNoArgs(providerName, clazz); + provider = tryCreate(providerName, clazz, varargs); } if (provider != null) { credentialsProviders.add(provider); @@ -106,36 +99,32 @@ class AwsCredentialsProviderPropertyValueDecoder implements IPropertyValueDecode return credentialsProviders; } - private static AwsCredentialsProvider tryConstructorWithArgs( + private static AwsCredentialsProvider tryConstructor( String providerName, Class clazz, String[] varargs) { AwsCredentialsProvider provider = constructProvider(providerName, () -> getConstructorWithVarArgs(clazz, varargs)); if (provider == null) { provider = constructProvider(providerName, () -> getConstructorWithArgs(clazz, varargs)); } + if (provider == null) { + provider = constructProvider(providerName, clazz::newInstance); + } return provider; } - private static AwsCredentialsProvider tryCreateWithArgs( + private static AwsCredentialsProvider tryCreate( String providerName, Class clazz, String[] varargs) { AwsCredentialsProvider provider = constructProvider(providerName, () -> getCreateMethod(clazz, (Object) varargs)); if (provider == null) { provider = constructProvider(providerName, () -> getCreateMethod(clazz, varargs)); } + if (provider == null) { + provider = constructProvider(providerName, () -> getCreateMethod(clazz)); + } return provider; } - private static AwsCredentialsProvider tryConstructorWithNoArgs( - String providerName, Class clazz) { - return constructProvider(providerName, clazz::newInstance); - } - - private static AwsCredentialsProvider tryCreateWithNoArgs( - String providerName, Class clazz) { - return constructProvider(providerName, () -> getCreateMethod(clazz)); - } - private static AwsCredentialsProvider getConstructorWithVarArgs( Class clazz, String[] varargs) { try { @@ -191,21 +180,18 @@ class AwsCredentialsProviderPropertyValueDecoder implements IPropertyValueDecode || providerName.equals(StsAssumeRoleCredentialsProvider.class.getName())) { providerName = KclStsAssumeRoleCredentialsProvider.class.getName(); } - final Class clazz; try { final Class c = Class.forName(providerName); if (!AwsCredentialsProvider.class.isAssignableFrom(c)) { return null; } - clazz = (Class) c; + return (Class) c; } catch (ClassNotFoundException cnfe) { // Providers are a product of prefixed Strings to cover multiple // namespaces (e.g., "Foo" -> { "some.auth.Foo", "kcl.auth.Foo" }). // It's expected that many class names will not resolve. return null; } - log.info("Attempting to construct {}", clazz); - return clazz; } private static List getProviderNames(String property) {