From 4e2bc77fd148c9482d75bff0793ab371d92f4969 Mon Sep 17 00:00:00 2001
From: vincentvilo-aws <142546855+vincentvilo-aws@users.noreply.github.com>
Date: Mon, 10 Mar 2025 16:20:38 -0700
Subject: [PATCH] Remove SDK v1 from KCL v2 (#1444)
* update dependabot to check for dependencies in v2.x
* exclude v1 sdk from glue dependency
* remove sdk v1 dependency from multilang pom.xml
* remove dependency on Regions class from sdk v1
* remove sdk v1 dependencies
* update docs for credential provider
* update documentation for NestedPropertyProcessor
* update KclStsAssumeRoleCredentialsProvider to have resolveCredentials()
* fix casing within AwsCredentialsProviderPropertyValueDecoderTest
* update unit tests to have endpointRegion
* update docs with endpointRegion
---
.github/dependabot.yml | 13 +-
amazon-kinesis-client-multilang/pom.xml | 30 --
.../kinesis/multilang/MultiLangDaemon.java | 6 +-
.../kinesis/multilang/NestedPropertyKey.java | 12 +-
.../multilang/NestedPropertyProcessor.java | 12 +-
...SAssumeRoleSessionCredentialsProvider.java | 86 ------
.../KclStsAssumeRoleCredentialsProvider.java | 75 +++++
...edentialsProviderPropertyValueDecoder.java | 182 ------------
...edentialsProviderPropertyValueDecoder.java | 261 ++++++++++++++++++
.../config/KinesisClientLibConfigurator.java | 17 +-
.../config/MultiLangDaemonConfiguration.java | 13 +-
.../credentials/V2CredentialWrapper.java | 52 ----
.../multilang/MultiLangDaemonConfigTest.java | 4 +-
.../multilang/NestedPropertyKeyTest.java | 6 +-
...StsAssumeRoleCredentialsProviderTest.java} | 14 +-
...ialsProviderPropertyValueDecoderTest.java} | 124 ++++++---
.../KinesisClientLibConfiguratorTest.java | 132 +++++----
.../src/test/resources/multilang.properties | 8 +-
amazon-kinesis-client/pom.xml | 6 +
.../configuring-credential-providers.md | 53 ++--
20 files changed, 599 insertions(+), 507 deletions(-)
delete mode 100644 amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/auth/KclSTSAssumeRoleSessionCredentialsProvider.java
create mode 100644 amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/auth/KclStsAssumeRoleCredentialsProvider.java
delete mode 100644 amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AWSCredentialsProviderPropertyValueDecoder.java
create mode 100644 amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java
delete mode 100644 amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/credentials/V2CredentialWrapper.java
rename amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/auth/{KclSTSAssumeRoleSessionCredentialsProviderTest.java => KclStsAssumeRoleCredentialsProviderTest.java} (80%)
rename amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/config/{AWSCredentialsProviderPropertyValueDecoderTest.java => AwsCredentialsProviderPropertyValueDecoderTest.java} (52%)
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index fd4483ad..2383c5f2 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -1,11 +1,22 @@
version: 2
updates:
+# branch - master
+- package-ecosystem: "maven"
+ directory: "/"
+ labels:
+ - "dependencies"
+ - "v3.x"
+ schedule:
+ interval: "weekly"
+
+# branch - v2.x
- package-ecosystem: "maven"
directory: "/"
labels:
- "dependencies"
- "v2.x"
- schedule:
+ target-branch: "v2.x"
+ schedule:
interval: "weekly"
# branch - v1.x
diff --git a/amazon-kinesis-client-multilang/pom.xml b/amazon-kinesis-client-multilang/pom.xml
index 7ee65595..f944fd5d 100644
--- a/amazon-kinesis-client-multilang/pom.xml
+++ b/amazon-kinesis-client-multilang/pom.xml
@@ -27,10 +27,6 @@
amazon-kinesis-client-multilang
-
- 1.12.668
-
-
software.amazon.kinesis
@@ -43,32 +39,6 @@
${awssdk.version}
-
- com.amazonaws
- aws-java-sdk-core
- ${aws-java-sdk.version}
-
-
- com.fasterxml.jackson.core
- jackson-databind
-
-
- com.fasterxml.jackson.dataformat
- jackson-dataformat-cbor
-
-
- org.apache.httpcomponents
- httpclient
-
-
-
-
-
- com.amazonaws
- aws-java-sdk-sts
- ${aws-java-sdk.version}
-
-
org.projectlombok
lombok
diff --git a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/MultiLangDaemon.java b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/MultiLangDaemon.java
index 4588b246..d70fb1af 100644
--- a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/MultiLangDaemon.java
+++ b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/MultiLangDaemon.java
@@ -61,10 +61,10 @@ import software.amazon.kinesis.coordinator.Scheduler;
* applicationName = PythonKCLSample
*
* # Users can change the credentials provider the KCL will use to retrieve credentials.
- * # The DefaultAWSCredentialsProviderChain checks several other providers, which is
+ * # The DefaultCredentialsProvider checks several other providers, which is
* # described here:
- * # http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.html
- * AWSCredentialsProvider = DefaultAWSCredentialsProviderChain
+ * # https://sdk.amazonaws.com/java/api/2.0.0-preview-11/software/amazon/awssdk/auth/credentials/DefaultCredentialsProvider.html
+ * AwsCredentialsProvider = DefaultCredentialsProvider
*
*/
@Slf4j
diff --git a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/NestedPropertyKey.java b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/NestedPropertyKey.java
index 19211822..13acfeb1 100644
--- a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/NestedPropertyKey.java
+++ b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/NestedPropertyKey.java
@@ -15,13 +15,14 @@
package software.amazon.kinesis.multilang;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
-import com.amazonaws.regions.Regions;
import com.google.common.base.CaseFormat;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
+import software.amazon.awssdk.regions.Region;
/**
* Key-Value pairs which may be nested in, and extracted from, a property value
@@ -73,8 +74,13 @@ public enum NestedPropertyKey {
* @see Available Regions
*/
ENDPOINT_REGION {
- void visit(final NestedPropertyProcessor processor, final String region) {
- processor.acceptEndpointRegion(Regions.fromName(region));
+ void visit(final NestedPropertyProcessor processor, final String regionName) {
+ List validRegions = Region.regions();
+ Region region = Region.of(regionName);
+ if (!validRegions.contains(region)) {
+ throw new IllegalArgumentException("Invalid region name: " + regionName);
+ }
+ processor.acceptEndpointRegion(region);
}
},
diff --git a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/NestedPropertyProcessor.java b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/NestedPropertyProcessor.java
index f7587297..fee33514 100644
--- a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/NestedPropertyProcessor.java
+++ b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/NestedPropertyProcessor.java
@@ -14,7 +14,7 @@
*/
package software.amazon.kinesis.multilang;
-import com.amazonaws.regions.Regions;
+import software.amazon.awssdk.regions.Region;
/**
* Defines methods to process {@link NestedPropertyKey}s.
@@ -26,11 +26,11 @@ public interface NestedPropertyProcessor {
*
* @param serviceEndpoint the service endpoint either with or without the protocol
* (e.g., https://sns.us-west-1.amazonaws.com, sns.us-west-1.amazonaws.com)
- * @param signingRegion the region to use for SigV4 signing of requests (e.g. us-west-1)
+ * @param signingRegion the region to use for the client (e.g. us-west-1)
*
- * @see #acceptEndpointRegion(Regions)
- * @see
- * AwsClientBuilder.EndpointConfiguration
+ * @see #acceptEndpointRegion(Region)
+ * @see
+ * AwsClientBuilder.endpointOverride
*/
void acceptEndpoint(String serviceEndpoint, String signingRegion);
@@ -42,7 +42,7 @@ public interface NestedPropertyProcessor {
*
* @see #acceptEndpoint(String, String)
*/
- void acceptEndpointRegion(Regions region);
+ void acceptEndpointRegion(Region region);
/**
* Set the external id, an optional field to designate who can assume an IAM role.
diff --git a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/auth/KclSTSAssumeRoleSessionCredentialsProvider.java b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/auth/KclSTSAssumeRoleSessionCredentialsProvider.java
deleted file mode 100644
index b5b9f924..00000000
--- a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/auth/KclSTSAssumeRoleSessionCredentialsProvider.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package software.amazon.kinesis.multilang.auth;
-
-import java.util.Arrays;
-
-import com.amazonaws.auth.AWSSessionCredentials;
-import com.amazonaws.auth.AWSSessionCredentialsProvider;
-import com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider;
-import com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider.Builder;
-import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration;
-import com.amazonaws.regions.Regions;
-import com.amazonaws.services.securitytoken.AWSSecurityTokenService;
-import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient;
-import software.amazon.kinesis.multilang.NestedPropertyKey;
-import software.amazon.kinesis.multilang.NestedPropertyProcessor;
-
-/**
- * An {@link AWSSessionCredentialsProvider} that is backed by STSAssumeRole.
- */
-public class KclSTSAssumeRoleSessionCredentialsProvider
- implements AWSSessionCredentialsProvider, NestedPropertyProcessor {
-
- private final Builder builder;
-
- private final STSAssumeRoleSessionCredentialsProvider provider;
-
- /**
- *
- * @param params vararg parameters which must include roleArn at index=0,
- * and roleSessionName at index=1
- */
- public KclSTSAssumeRoleSessionCredentialsProvider(final String[] params) {
- this(params[0], params[1], Arrays.copyOfRange(params, 2, params.length));
- }
-
- public KclSTSAssumeRoleSessionCredentialsProvider(
- final String roleArn, final String roleSessionName, final String... params) {
- builder = new Builder(roleArn, roleSessionName);
- NestedPropertyKey.parse(this, params);
- provider = builder.build();
- }
-
- @Override
- public AWSSessionCredentials getCredentials() {
- return provider.getCredentials();
- }
-
- @Override
- public void refresh() {
- // do nothing
- }
-
- @Override
- public void acceptEndpoint(final String serviceEndpoint, final String signingRegion) {
- final EndpointConfiguration endpoint = new EndpointConfiguration(serviceEndpoint, signingRegion);
- final AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClient.builder()
- .withEndpointConfiguration(endpoint)
- .build();
- builder.withStsClient(stsClient);
- }
-
- @Override
- public void acceptEndpointRegion(final Regions region) {
- final AWSSecurityTokenService stsClient =
- AWSSecurityTokenServiceClient.builder().withRegion(region).build();
- builder.withStsClient(stsClient);
- }
-
- @Override
- public void acceptExternalId(final String externalId) {
- builder.withExternalId(externalId);
- }
-}
diff --git a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/auth/KclStsAssumeRoleCredentialsProvider.java b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/auth/KclStsAssumeRoleCredentialsProvider.java
new file mode 100644
index 00000000..96ecfdd6
--- /dev/null
+++ b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/auth/KclStsAssumeRoleCredentialsProvider.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2024 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.amazon.kinesis.multilang.auth;
+
+import java.net.URI;
+import java.util.Arrays;
+
+import software.amazon.awssdk.auth.credentials.AwsCredentials;
+import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.services.sts.StsClient;
+import software.amazon.awssdk.services.sts.StsClientBuilder;
+import software.amazon.awssdk.services.sts.auth.StsAssumeRoleCredentialsProvider;
+import software.amazon.awssdk.services.sts.model.AssumeRoleRequest;
+import software.amazon.awssdk.services.sts.model.AssumeRoleRequest.Builder;
+import software.amazon.kinesis.multilang.NestedPropertyKey;
+import software.amazon.kinesis.multilang.NestedPropertyProcessor;
+
+public class KclStsAssumeRoleCredentialsProvider implements AwsCredentialsProvider, NestedPropertyProcessor {
+ private final Builder assumeRoleRequestBuilder;
+ private final StsClientBuilder stsClientBuilder;
+ private final StsAssumeRoleCredentialsProvider stsAssumeRoleCredentialsProvider;
+
+ public KclStsAssumeRoleCredentialsProvider(String[] params) {
+ this(params[0], params[1], Arrays.copyOfRange(params, 2, params.length));
+ }
+
+ public KclStsAssumeRoleCredentialsProvider(String roleArn, String roleSessionName, String... params) {
+ this.assumeRoleRequestBuilder =
+ AssumeRoleRequest.builder().roleArn(roleArn).roleSessionName(roleSessionName);
+ this.stsClientBuilder = StsClient.builder();
+ NestedPropertyKey.parse(this, params);
+ this.stsAssumeRoleCredentialsProvider = StsAssumeRoleCredentialsProvider.builder()
+ .refreshRequest(assumeRoleRequestBuilder.build())
+ .asyncCredentialUpdateEnabled(true)
+ .stsClient(stsClientBuilder.build())
+ .build();
+ }
+
+ @Override
+ public AwsCredentials resolveCredentials() {
+ return stsAssumeRoleCredentialsProvider.resolveCredentials();
+ }
+
+ @Override
+ public void acceptEndpoint(String serviceEndpoint, String signingRegion) {
+ if (!serviceEndpoint.startsWith("http://") && !serviceEndpoint.startsWith("https://")) {
+ serviceEndpoint = "https://" + serviceEndpoint;
+ }
+ stsClientBuilder.endpointOverride(URI.create(serviceEndpoint));
+ stsClientBuilder.region(Region.of(signingRegion));
+ }
+
+ @Override
+ public void acceptEndpointRegion(Region region) {
+ stsClientBuilder.region(region);
+ }
+
+ @Override
+ public void acceptExternalId(String externalId) {
+ assumeRoleRequestBuilder.externalId(externalId);
+ }
+}
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
deleted file mode 100644
index 8110d4f7..00000000
--- a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AWSCredentialsProviderPropertyValueDecoder.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright 2019 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package software.amazon.kinesis.multilang.config;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import com.amazonaws.auth.AWSCredentialsProvider;
-import com.amazonaws.auth.AWSCredentialsProviderChain;
-import lombok.extern.slf4j.Slf4j;
-
-/**
- * Get AWSCredentialsProvider property.
- */
-@Slf4j
-class AWSCredentialsProviderPropertyValueDecoder implements IPropertyValueDecoder {
- private static final String LIST_DELIMITER = ",";
- private static final String ARG_DELIMITER = "|";
-
- /**
- * Constructor.
- */
- AWSCredentialsProviderPropertyValueDecoder() {}
-
- /**
- * Get AWSCredentialsProvider property.
- *
- * @param value
- * property value as String
- * @return corresponding variable in correct type
- */
- @Override
- public AWSCredentialsProvider decodeValue(String value) {
- if (value != null) {
- List providerNames = getProviderNames(value);
- List providers = getValidCredentialsProviders(providerNames);
- AWSCredentialsProvider[] ps = new AWSCredentialsProvider[providers.size()];
- providers.toArray(ps);
- return new AWSCredentialsProviderChain(providers);
- } else {
- throw new IllegalArgumentException("Property AWSCredentialsProvider is missing.");
- }
- }
-
- /**
- * @return list of supported types
- */
- @Override
- public List> getSupportedTypes() {
- return Collections.singletonList(AWSCredentialsProvider.class);
- }
-
- /**
- * Convert string list to a list of valid credentials providers.
- */
- private static List getValidCredentialsProviders(List providerNames) {
- List credentialsProviders = new ArrayList<>();
-
- for (String providerName : providerNames) {
- final String[] nameAndArgs = providerName.split("\\" + ARG_DELIMITER);
- final Class extends AWSCredentialsProvider> clazz;
- try {
- final Class> c = Class.forName(nameAndArgs[0]);
- if (!AWSCredentialsProvider.class.isAssignableFrom(c)) {
- continue;
- }
- clazz = (Class extends AWSCredentialsProvider>) 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.
- 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);
- });
-
- if (provider == null) {
- // attempt to invoke a public varargs/array constructor of FooClass(String[])
- provider = constructProvider(providerName, () -> clazz.getConstructor(String[].class)
- .newInstance((Object) varargs));
- }
- }
-
- if (provider == null) {
- // regardless of parameters, fallback to invoke a public no-arg constructor
- provider = constructProvider(providerName, clazz::newInstance);
- }
-
- if (provider != null) {
- credentialsProviders.add(provider);
- }
- }
- return credentialsProviders;
- }
-
- private static List getProviderNames(String property) {
- // assume list delimiter is ","
- String[] elements = property.split(LIST_DELIMITER);
- List result = new ArrayList<>();
- for (int i = 0; i < elements.length; i++) {
- String string = elements[i].trim();
- if (!string.isEmpty()) {
- // find all possible names and add them to name list
- result.addAll(getPossibleFullClassNames(string));
- }
- }
- return result;
- }
-
- private static List getPossibleFullClassNames(final String provider) {
- return Stream.of(
- // Customer provides a short name of common providers in com.amazonaws.auth package
- // (e.g., any classes implementing the AWSCredentialsProvider interface)
- // @see
- // http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/AWSCredentialsProvider.html
- "com.amazonaws.auth.",
-
- // Customer provides a short name of a provider offered by this multi-lang package
- "software.amazon.kinesis.multilang.auth.",
-
- // Customer provides a fully-qualified provider name, or a custom credentials provider
- // (e.g., com.amazonaws.auth.ClasspathFileCredentialsProvider, org.mycompany.FooProvider)
- "")
- .map(prefix -> prefix + provider)
- .collect(Collectors.toList());
- }
-
- @FunctionalInterface
- private interface CredentialsProviderConstructor {
- T construct()
- throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException;
- }
-
- /**
- * Attempts to construct an {@link AWSCredentialsProvider}.
- *
- * @param providerName Raw, unmodified provider name. Should there be an
- * Exeception during construction, this parameter will be logged.
- * @param constructor supplier-like function that will perform the construction
- * @return the constructed provider, if successful; otherwise, null
- *
- * @param type of the CredentialsProvider to construct
- */
- private static T constructProvider(
- final String providerName, final CredentialsProviderConstructor constructor) {
- try {
- return constructor.construct();
- } catch (NoSuchMethodException ignored) {
- // ignore
- } catch (IllegalAccessException | InstantiationException | InvocationTargetException | RuntimeException e) {
- log.warn("Failed to construct {}", providerName, e);
- }
- return null;
- }
-}
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
new file mode 100644
index 00000000..fd29a3db
--- /dev/null
+++ b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoder.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2019 Amazon.com, Inc. or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package software.amazon.kinesis.multilang.config;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+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.
+ */
+@Slf4j
+class AwsCredentialsProviderPropertyValueDecoder implements IPropertyValueDecoder {
+ private static final String LIST_DELIMITER = ",";
+ private static final String ARG_DELIMITER = "|";
+
+ /**
+ * Constructor.
+ */
+ AwsCredentialsProviderPropertyValueDecoder() {}
+
+ /**
+ * Get AwsCredentialsProvider property.
+ *
+ * @param value
+ * property value as String
+ * @return corresponding variable in correct type
+ */
+ @Override
+ public AwsCredentialsProvider decodeValue(String value) {
+ if (value != null) {
+ List providerNames = getProviderNames(value);
+ List providers = getValidCredentialsProviders(providerNames);
+ AwsCredentialsProvider[] ps = new AwsCredentialsProvider[providers.size()];
+ providers.toArray(ps);
+ if (providers.isEmpty()) {
+ log.warn("Unable to construct any provider with name {}", value);
+ log.warn("Please verify that all AwsCredentialsProvider properties are passed correctly");
+ }
+ return AwsCredentialsProviderChain.builder()
+ .credentialsProviders(providers)
+ .build();
+ } else {
+ throw new IllegalArgumentException("Property AwsCredentialsProvider is missing.");
+ }
+ }
+
+ /**
+ * @return list of supported types
+ */
+ @Override
+ public List> getSupportedTypes() {
+ return Collections.singletonList(AwsCredentialsProvider.class);
+ }
+
+ /**
+ * Convert string list to a list of valid credentials providers.
+ */
+ private static List getValidCredentialsProviders(List providerNames) {
+ List credentialsProviders = new ArrayList<>();
+
+ for (String providerName : providerNames) {
+ final String[] nameAndArgs = providerName.split("\\" + ARG_DELIMITER);
+ final Class extends AwsCredentialsProvider> clazz = getClass(nameAndArgs[0]);
+ if (clazz == null) {
+ continue;
+ }
+ 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 = tryCreate(providerName, clazz, varargs);
+ }
+ if (provider != null) {
+ log.info("Provider constructed successfully: {}", provider);
+ credentialsProviders.add(provider);
+ }
+ }
+ return credentialsProviders;
+ }
+
+ private static AwsCredentialsProvider tryConstructor(
+ String providerName, Class extends AwsCredentialsProvider> 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 tryCreate(
+ String providerName, Class extends AwsCredentialsProvider> 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 getConstructorWithVarArgs(
+ Class extends AwsCredentialsProvider> clazz, String[] varargs) {
+ try {
+ return clazz.getConstructor(String[].class).newInstance((Object) varargs);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ private static AwsCredentialsProvider getConstructorWithArgs(
+ Class extends AwsCredentialsProvider> 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 extends AwsCredentialsProvider> 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;
+ }
+
+ /**
+ * Resolves the class for the given provider name.
+ *
+ * @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 extends AwsCredentialsProvider> getClass(String providerName) {
+ // Convert any form of StsAssumeRoleCredentialsProvider string to KclStsAssumeRoleCredentialsProvider
+ if (providerName.equals(StsAssumeRoleCredentialsProvider.class.getSimpleName())
+ || providerName.equals(StsAssumeRoleCredentialsProvider.class.getName())) {
+ providerName = KclStsAssumeRoleCredentialsProvider.class.getName();
+ }
+ try {
+ final Class> c = Class.forName(providerName);
+ if (!AwsCredentialsProvider.class.isAssignableFrom(c)) {
+ return null;
+ }
+ return (Class extends AwsCredentialsProvider>) 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;
+ }
+ }
+
+ private static List getProviderNames(String property) {
+ // assume list delimiter is ","
+ String[] elements = property.split(LIST_DELIMITER);
+ List result = new ArrayList<>();
+ for (int i = 0; i < elements.length; i++) {
+ String string = elements[i].trim();
+ if (!string.isEmpty()) {
+ // find all possible names and add them to name list
+ result.addAll(getPossibleFullClassNames(string));
+ }
+ }
+ return result;
+ }
+
+ private static List getPossibleFullClassNames(final String provider) {
+ return Stream.of(
+ // Customer provides a short name of a provider offered by this multi-lang package
+ "software.amazon.kinesis.multilang.auth.",
+ // Customer provides a short name of common providers in software.amazon.awssdk.auth.credentials
+ // package (e.g., any classes implementing the AwsCredentialsProvider interface)
+ // @see
+ // https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/AwsCredentialsProvider.html
+ "software.amazon.awssdk.auth.credentials.",
+ // Customer provides a fully-qualified provider name, or a custom credentials provider
+ // (e.g., org.mycompany.FooProvider)
+ "")
+ .map(prefix -> prefix + provider)
+ .collect(Collectors.toList());
+ }
+
+ @FunctionalInterface
+ private interface CredentialsProviderConstructor {
+ T construct()
+ throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException;
+ }
+
+ /**
+ * Attempts to construct an {@link AwsCredentialsProvider}.
+ *
+ * @param providerName Raw, unmodified provider name. Should there be an
+ * Exception during construction, this parameter will be logged.
+ * @param constructor supplier-like function that will perform the construction
+ * @return the constructed provider, if successful; otherwise, null
+ *
+ * @param type of the CredentialsProvider to construct
+ */
+ private static T constructProvider(
+ final String providerName, final CredentialsProviderConstructor constructor) {
+ try {
+ return constructor.construct();
+ } catch (NoSuchMethodException
+ | IllegalAccessException
+ | InstantiationException
+ | InvocationTargetException
+ | RuntimeException ignored) {
+ // ignore
+ }
+ return null;
+ }
+}
diff --git a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/KinesisClientLibConfigurator.java b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/KinesisClientLibConfigurator.java
index 42b617a0..0d897efa 100644
--- a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/KinesisClientLibConfigurator.java
+++ b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/KinesisClientLibConfigurator.java
@@ -28,7 +28,7 @@ import software.amazon.kinesis.common.StreamIdentifier;
/**
* KinesisClientLibConfigurator constructs a KinesisClientLibConfiguration from java properties file. The following
- * three properties must be provided. 1) "applicationName" 2) "streamName" 3) "AWSCredentialsProvider"
+ * three properties must be provided. 1) "applicationName" 2) "streamName" 3) "AwsCredentialsProvider"
* KinesisClientLibConfigurator will help to automatically assign the value of "workerId" if this property is not
* provided. In the specified properties file, any properties, which matches the variable name in
* KinesisClientLibConfiguration and has a corresponding "with{variableName}" setter method, will be read in, and its
@@ -62,7 +62,7 @@ public class KinesisClientLibConfigurator {
properties.entrySet().forEach(e -> {
try {
log.info("Processing (key={}, value={})", e.getKey(), e.getValue());
- utilsBean.setProperty(configuration, (String) e.getKey(), e.getValue());
+ utilsBean.setProperty(configuration, processKey((String) e.getKey()), e.getValue());
} catch (IllegalAccessException | InvocationTargetException ex) {
throw new RuntimeException(ex);
}
@@ -110,4 +110,17 @@ public class KinesisClientLibConfigurator {
}
return getConfiguration(properties);
}
+
+ /**
+ * Processes a configuration key to normalize AWS credentials provider naming. Necessary to conform to
+ * autogenerated setters.
+ * @param key the config param key
+ * @return case-configured param key name
+ */
+ String processKey(String key) {
+ if (key.toLowerCase().startsWith("awscredentialsprovider")) {
+ key = key.replaceAll("(?i)awscredentialsprovider", "awsCredentialsProvider");
+ }
+ return key;
+ }
}
diff --git a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/MultiLangDaemonConfiguration.java b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/MultiLangDaemonConfiguration.java
index 3336be88..5a4c3092 100644
--- a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/MultiLangDaemonConfiguration.java
+++ b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/MultiLangDaemonConfiguration.java
@@ -55,7 +55,6 @@ import software.amazon.kinesis.leases.ShardPrioritization;
import software.amazon.kinesis.lifecycle.LifecycleConfig;
import software.amazon.kinesis.metrics.MetricsConfig;
import software.amazon.kinesis.metrics.MetricsLevel;
-import software.amazon.kinesis.multilang.config.credentials.V2CredentialWrapper;
import software.amazon.kinesis.processor.ProcessorConfig;
import software.amazon.kinesis.processor.ShardRecordProcessorFactory;
import software.amazon.kinesis.retrieval.RetrievalConfig;
@@ -196,19 +195,19 @@ public class MultiLangDaemonConfiguration {
private final BuilderDynaBean kinesisCredentialsProvider;
- public void setAWSCredentialsProvider(String providerString) {
+ public void setAwsCredentialsProvider(String providerString) {
kinesisCredentialsProvider.set("", providerString);
}
private final BuilderDynaBean dynamoDBCredentialsProvider;
- public void setAWSCredentialsProviderDynamoDB(String providerString) {
+ public void setAwsCredentialsProviderDynamoDB(String providerString) {
dynamoDBCredentialsProvider.set("", providerString);
}
private final BuilderDynaBean cloudWatchCredentialsProvider;
- public void setAWSCredentialsProviderCloudWatch(String providerString) {
+ public void setAwsCredentialsProviderCloudWatch(String providerString) {
cloudWatchCredentialsProvider.set("", providerString);
}
@@ -282,9 +281,9 @@ public class MultiLangDaemonConfiguration {
ArrayConverter arrayConverter = new ArrayConverter(String[].class, new StringConverter());
arrayConverter.setDelimiter(',');
convertUtilsBean.register(arrayConverter, String[].class);
- AWSCredentialsProviderPropertyValueDecoder oldCredentialsDecoder =
- new AWSCredentialsProviderPropertyValueDecoder();
- Function converter = s -> new V2CredentialWrapper(oldCredentialsDecoder.decodeValue(s));
+ AwsCredentialsProviderPropertyValueDecoder credentialsDecoder =
+ new AwsCredentialsProviderPropertyValueDecoder();
+ Function converter = credentialsDecoder::decodeValue;
this.kinesisCredentialsProvider = new BuilderDynaBean(
AwsCredentialsProvider.class, convertUtilsBean, converter, CREDENTIALS_DEFAULT_SEARCH_PATH);
diff --git a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/credentials/V2CredentialWrapper.java b/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/credentials/V2CredentialWrapper.java
deleted file mode 100644
index e1b6072a..00000000
--- a/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/config/credentials/V2CredentialWrapper.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2019 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package software.amazon.kinesis.multilang.config.credentials;
-
-import com.amazonaws.auth.AWSCredentials;
-import com.amazonaws.auth.AWSCredentialsProvider;
-import com.amazonaws.auth.AWSSessionCredentials;
-import lombok.RequiredArgsConstructor;
-import software.amazon.awssdk.auth.credentials.AwsCredentials;
-import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
-import software.amazon.awssdk.auth.credentials.AwsSessionCredentials;
-
-@RequiredArgsConstructor
-public class V2CredentialWrapper implements AwsCredentialsProvider {
-
- private final AWSCredentialsProvider oldCredentialsProvider;
-
- @Override
- public AwsCredentials resolveCredentials() {
- AWSCredentials current = oldCredentialsProvider.getCredentials();
- if (current instanceof AWSSessionCredentials) {
- return AwsSessionCredentials.create(
- current.getAWSAccessKeyId(),
- current.getAWSSecretKey(),
- ((AWSSessionCredentials) current).getSessionToken());
- }
- return new AwsCredentials() {
- @Override
- public String accessKeyId() {
- return current.getAWSAccessKeyId();
- }
-
- @Override
- public String secretAccessKey() {
- return current.getAWSSecretKey();
- }
- };
- }
-}
diff --git a/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/MultiLangDaemonConfigTest.java b/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/MultiLangDaemonConfigTest.java
index de5a1405..53b7f2d8 100644
--- a/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/MultiLangDaemonConfigTest.java
+++ b/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/MultiLangDaemonConfigTest.java
@@ -65,7 +65,7 @@ public class MultiLangDaemonConfigTest {
String properties = String.format(
"executableName = %s\n"
+ "applicationName = %s\n"
- + "AWSCredentialsProvider = DefaultAWSCredentialsProviderChain\n"
+ + "AwsCredentialsProvider = DefaultCredentialsProvider\n"
+ "processingLanguage = malbolge\n"
+ "regionName = %s\n",
EXE, APPLICATION_NAME, "us-east-1");
@@ -182,7 +182,7 @@ public class MultiLangDaemonConfigTest {
@Test
public void testPropertyValidation() {
String propertiesNoExecutableName = "applicationName = testApp \n" + "streamName = fakeStream \n"
- + "AWSCredentialsProvider = DefaultAWSCredentialsProviderChain\n" + "processingLanguage = malbolge";
+ + "AwsCredentialsProvider = DefaultCredentialsProvider\n" + "processingLanguage = malbolge";
ClassLoader classLoader = Mockito.mock(ClassLoader.class);
Mockito.doReturn(new ByteArrayInputStream(propertiesNoExecutableName.getBytes()))
diff --git a/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/NestedPropertyKeyTest.java b/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/NestedPropertyKeyTest.java
index fbffee81..3c2de9c9 100644
--- a/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/NestedPropertyKeyTest.java
+++ b/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/NestedPropertyKeyTest.java
@@ -14,11 +14,11 @@
*/
package software.amazon.kinesis.multilang;
-import com.amazonaws.regions.Regions;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
+import software.amazon.awssdk.regions.Region;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.verify;
@@ -64,9 +64,9 @@ public class NestedPropertyKeyTest {
@Test
public void testEndpointRegion() {
- final Regions expectedRegion = Regions.GovCloud;
+ final Region expectedRegion = Region.US_GOV_WEST_1;
- parse(mockProcessor, createKey(ENDPOINT_REGION, expectedRegion.getName()));
+ parse(mockProcessor, createKey(ENDPOINT_REGION, expectedRegion.id()));
verify(mockProcessor).acceptEndpointRegion(expectedRegion);
}
diff --git a/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/auth/KclSTSAssumeRoleSessionCredentialsProviderTest.java b/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/auth/KclStsAssumeRoleCredentialsProviderTest.java
similarity index 80%
rename from amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/auth/KclSTSAssumeRoleSessionCredentialsProviderTest.java
rename to amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/auth/KclStsAssumeRoleCredentialsProviderTest.java
index c27a425d..9a4d5b0c 100644
--- a/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/auth/KclSTSAssumeRoleSessionCredentialsProviderTest.java
+++ b/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/auth/KclStsAssumeRoleCredentialsProviderTest.java
@@ -20,7 +20,7 @@ import org.junit.Test;
import static org.junit.Assert.assertEquals;
-public class KclSTSAssumeRoleSessionCredentialsProviderTest {
+public class KclStsAssumeRoleCredentialsProviderTest {
private static final String ARN = "arn";
private static final String SESSION_NAME = "sessionName";
@@ -31,29 +31,29 @@ public class KclSTSAssumeRoleSessionCredentialsProviderTest {
*/
@Test
public void testConstructorWithoutOptionalParams() {
- new KclSTSAssumeRoleSessionCredentialsProvider(new String[] {ARN, SESSION_NAME});
+ new KclStsAssumeRoleCredentialsProvider(new String[] {ARN, SESSION_NAME, "endpointRegion=us-east-1"});
}
@Test
public void testAcceptEndpoint() {
// discovered exception during e2e testing; therefore, this test is
// to simply verify the constructed STS client doesn't go *boom*
- final KclSTSAssumeRoleSessionCredentialsProvider provider =
- new KclSTSAssumeRoleSessionCredentialsProvider(ARN, SESSION_NAME);
+ final KclStsAssumeRoleCredentialsProvider provider =
+ new KclStsAssumeRoleCredentialsProvider(ARN, SESSION_NAME, "endpointRegion=us-east-1");
provider.acceptEndpoint("endpoint", "us-east-1");
}
@Test
public void testVarArgs() {
for (final String[] varargs : Arrays.asList(
- new String[] {ARN, SESSION_NAME, "externalId=eid", "foo"},
- new String[] {ARN, SESSION_NAME, "foo", "externalId=eid"})) {
+ new String[] {ARN, SESSION_NAME, "externalId=eid", "foo", "endpointRegion=us-east-1"},
+ new String[] {ARN, SESSION_NAME, "foo", "externalId=eid", "endpointRegion=us-east-1"})) {
final VarArgsSpy provider = new VarArgsSpy(varargs);
assertEquals("eid", provider.externalId);
}
}
- private static class VarArgsSpy extends KclSTSAssumeRoleSessionCredentialsProvider {
+ private static class VarArgsSpy extends KclStsAssumeRoleCredentialsProvider {
private String externalId;
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
similarity index 52%
rename from amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/config/AWSCredentialsProviderPropertyValueDecoderTest.java
rename to amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/config/AwsCredentialsProviderPropertyValueDecoderTest.java
index ba5a0925..3e9380e6 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
@@ -16,16 +16,17 @@ package software.amazon.kinesis.multilang.config;
import java.util.Arrays;
-import com.amazonaws.auth.AWSCredentials;
-import com.amazonaws.auth.AWSCredentialsProvider;
-import com.amazonaws.auth.AWSCredentialsProviderChain;
-import com.amazonaws.auth.BasicAWSCredentials;
import lombok.ToString;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeDiagnosingMatcher;
import org.junit.Test;
-import software.amazon.kinesis.multilang.auth.KclSTSAssumeRoleSessionCredentialsProvider;
+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;
import static org.hamcrest.CoreMatchers.instanceOf;
@@ -33,31 +34,32 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
-public class AWSCredentialsProviderPropertyValueDecoderTest {
+public class AwsCredentialsProviderPropertyValueDecoderTest {
private static final String TEST_ACCESS_KEY_ID = "123";
private static final String TEST_SECRET_KEY = "456";
private final String credentialName1 = AlwaysSucceedCredentialsProvider.class.getName();
private final String credentialName2 = ConstructorCredentialsProvider.class.getName();
- private final AWSCredentialsProviderPropertyValueDecoder decoder = new AWSCredentialsProviderPropertyValueDecoder();
+ private final String createCredentialClass = CreateProvider.class.getName();
+ private final AwsCredentialsProviderPropertyValueDecoder decoder = new AwsCredentialsProviderPropertyValueDecoder();
@ToString
- private static class AWSCredentialsMatcher extends TypeSafeDiagnosingMatcher {
+ private static class AwsCredentialsMatcher extends TypeSafeDiagnosingMatcher {
private final Matcher akidMatcher;
private final Matcher secretMatcher;
private final Matcher> classMatcher;
- public AWSCredentialsMatcher(String akid, String secret) {
+ public AwsCredentialsMatcher(String akid, String secret) {
this.akidMatcher = equalTo(akid);
this.secretMatcher = equalTo(secret);
- this.classMatcher = instanceOf(AWSCredentialsProviderChain.class);
+ this.classMatcher = instanceOf(AwsCredentialsProviderChain.class);
}
@Override
- protected boolean matchesSafely(AWSCredentialsProvider item, Description mismatchDescription) {
- AWSCredentials actual = item.getCredentials();
+ protected boolean matchesSafely(AwsCredentialsProvider item, Description mismatchDescription) {
+ AwsCredentials actual = item.resolveCredentials();
boolean matched = true;
if (!classMatcher.matches(item)) {
@@ -65,12 +67,12 @@ public class AWSCredentialsProviderPropertyValueDecoderTest {
matched = false;
}
- if (!akidMatcher.matches(actual.getAWSAccessKeyId())) {
- akidMatcher.describeMismatch(actual.getAWSAccessKeyId(), mismatchDescription);
+ if (!akidMatcher.matches(actual.accessKeyId())) {
+ akidMatcher.describeMismatch(actual.accessKeyId(), mismatchDescription);
matched = false;
}
- if (!secretMatcher.matches(actual.getAWSSecretKey())) {
- secretMatcher.describeMismatch(actual.getAWSSecretKey(), mismatchDescription);
+ if (!secretMatcher.matches(actual.secretAccessKey())) {
+ secretMatcher.describeMismatch(actual.secretAccessKey(), mismatchDescription);
matched = false;
}
return matched;
@@ -84,31 +86,31 @@ public class AWSCredentialsProviderPropertyValueDecoderTest {
}
}
- private static AWSCredentialsMatcher hasCredentials(String akid, String secret) {
- return new AWSCredentialsMatcher(akid, secret);
+ private static AwsCredentialsMatcher hasCredentials(String akid, String secret) {
+ return new AwsCredentialsMatcher(akid, secret);
}
@Test
public void testSingleProvider() {
- AWSCredentialsProvider provider = decoder.decodeValue(credentialName1);
+ AwsCredentialsProvider provider = decoder.decodeValue(credentialName1);
assertThat(provider, hasCredentials(TEST_ACCESS_KEY_ID, TEST_SECRET_KEY));
}
@Test
public void testTwoProviders() {
- AWSCredentialsProvider provider = decoder.decodeValue(credentialName1 + "," + credentialName1);
+ AwsCredentialsProvider provider = decoder.decodeValue(credentialName1 + "," + credentialName1);
assertThat(provider, hasCredentials(TEST_ACCESS_KEY_ID, TEST_SECRET_KEY));
}
@Test
public void testProfileProviderWithOneArg() {
- AWSCredentialsProvider provider = decoder.decodeValue(credentialName2 + "|arg");
+ AwsCredentialsProvider provider = decoder.decodeValue(credentialName2 + "|arg");
assertThat(provider, hasCredentials("arg", "blank"));
}
@Test
public void testProfileProviderWithTwoArgs() {
- AWSCredentialsProvider provider = decoder.decodeValue(credentialName2 + "|arg1|arg2");
+ AwsCredentialsProvider provider = decoder.decodeValue(credentialName2 + "|arg1|arg2");
assertThat(provider, hasCredentials("arg1", "arg2"));
}
@@ -118,14 +120,34 @@ public class AWSCredentialsProviderPropertyValueDecoderTest {
@Test
public void testKclAuthProvider() {
for (final String className : Arrays.asList(
- KclSTSAssumeRoleSessionCredentialsProvider.class.getName(), // fully-qualified name
- KclSTSAssumeRoleSessionCredentialsProvider.class.getSimpleName() // name-only; needs prefix
- )) {
- final AWSCredentialsProvider provider = decoder.decodeValue(className + "|arn|sessionName");
+ KclStsAssumeRoleCredentialsProvider.class.getName(), // fully-qualified name
+ KclStsAssumeRoleCredentialsProvider.class.getSimpleName(), // name-only; needs prefix
+ StsAssumeRoleCredentialsProvider.class.getName(), // user passes full sts package path
+ StsAssumeRoleCredentialsProvider.class.getSimpleName())) {
+ final AwsCredentialsProvider provider =
+ decoder.decodeValue(className + "|arn|sessionName|endpointRegion=us-east-1");
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.
*/
@@ -135,28 +157,25 @@ public class AWSCredentialsProviderPropertyValueDecoderTest {
final String className = VarArgCredentialsProvider.class.getName();
final String encodedValue = className + "|" + String.join("|", args);
- final AWSCredentialsProvider provider = decoder.decodeValue(encodedValue);
- assertEquals(Arrays.toString(args), provider.getCredentials().getAWSAccessKeyId());
+ final AwsCredentialsProvider provider = decoder.decodeValue(encodedValue);
+ assertEquals(Arrays.toString(args), provider.resolveCredentials().accessKeyId());
}
/**
* This credentials provider will always succeed
*/
- public static class AlwaysSucceedCredentialsProvider implements AWSCredentialsProvider {
+ public static class AlwaysSucceedCredentialsProvider implements AwsCredentialsProvider {
@Override
- public AWSCredentials getCredentials() {
- return new BasicAWSCredentials(TEST_ACCESS_KEY_ID, TEST_SECRET_KEY);
+ public AwsCredentials resolveCredentials() {
+ return AwsBasicCredentials.create(TEST_ACCESS_KEY_ID, TEST_SECRET_KEY);
}
-
- @Override
- public void refresh() {}
}
/**
* This credentials provider needs a constructor call to instantiate it
*/
- public static class ConstructorCredentialsProvider implements AWSCredentialsProvider {
+ public static class ConstructorCredentialsProvider implements AwsCredentialsProvider {
private String arg1;
private String arg2;
@@ -172,15 +191,12 @@ public class AWSCredentialsProviderPropertyValueDecoderTest {
}
@Override
- public AWSCredentials getCredentials() {
- return new BasicAWSCredentials(arg1, arg2);
+ public AwsCredentials resolveCredentials() {
+ return AwsBasicCredentials.create(arg1, arg2);
}
-
- @Override
- public void refresh() {}
}
- private static class VarArgCredentialsProvider implements AWSCredentialsProvider {
+ private static class VarArgCredentialsProvider implements AwsCredentialsProvider {
private final String[] args;
@@ -189,13 +205,33 @@ public class AWSCredentialsProviderPropertyValueDecoderTest {
}
@Override
- public AWSCredentials getCredentials() {
+ public AwsCredentials resolveCredentials() {
// KISS solution to surface the constructor args
final String flattenedArgs = Arrays.toString(args);
- return new BasicAWSCredentials(flattenedArgs, flattenedArgs);
+ 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 void refresh() {}
+ public AwsCredentials resolveCredentials() {
+ return AwsBasicCredentials.create(accessKeyId, TEST_SECRET_KEY);
+ }
}
}
diff --git a/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/config/KinesisClientLibConfiguratorTest.java b/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/config/KinesisClientLibConfiguratorTest.java
index b0e3b870..4a19dfdc 100644
--- a/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/config/KinesisClientLibConfiguratorTest.java
+++ b/amazon-kinesis-client-multilang/src/test/java/software/amazon/kinesis/multilang/config/KinesisClientLibConfiguratorTest.java
@@ -22,15 +22,14 @@ import java.util.Date;
import java.util.HashSet;
import java.util.Set;
-import com.amazonaws.auth.AWSCredentials;
-import com.amazonaws.auth.AWSCredentialsProvider;
-import com.amazonaws.auth.BasicAWSCredentials;
import com.google.common.collect.ImmutableSet;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
+import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
+import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.kinesis.common.InitialPositionInStream;
import software.amazon.kinesis.metrics.MetricsLevel;
@@ -60,7 +59,7 @@ public class KinesisClientLibConfiguratorTest {
new String[] {
"streamName = a",
"applicationName = b",
- "AWSCredentialsProvider = " + credentialName1,
+ "AwsCredentialsProvider = " + credentialName1,
"workerId = 123"
},
'\n'));
@@ -77,7 +76,7 @@ public class KinesisClientLibConfiguratorTest {
new String[] {
"applicationName = app",
"streamName = 123",
- "AWSCredentialsProvider = " + credentialName1 + ", " + credentialName2,
+ "AwsCredentialsProvider = " + credentialName1 + ", " + credentialName2,
"workerId = 123",
"failoverTimeMillis = 100",
"shardSyncIntervalMillis = 500"
@@ -98,7 +97,7 @@ public class KinesisClientLibConfiguratorTest {
new String[] {
"applicationName = app",
"streamName = 123",
- "AWSCredentialsProvider = " + credentialName1 + ", " + credentialName2,
+ "AwsCredentialsProvider = " + credentialName1 + ", " + credentialName2,
"initialPositionInStreamExtended = " + epochTimeInSeconds
},
'\n'));
@@ -116,7 +115,7 @@ public class KinesisClientLibConfiguratorTest {
new String[] {
"applicationName = app",
"streamName = 123",
- "AWSCredentialsProvider = " + credentialName1 + ", " + credentialName2,
+ "AwsCredentialsProvider = " + credentialName1 + ", " + credentialName2,
"initialPositionInStream = AT_TIMESTAMP"
},
'\n'));
@@ -136,7 +135,7 @@ public class KinesisClientLibConfiguratorTest {
new String[] {
"applicationName = app",
"streamName = 123",
- "AWSCredentialsProvider = " + credentialName1 + ", " + credentialName2,
+ "AwsCredentialsProvider = " + credentialName1 + ", " + credentialName2,
"initialPositionInStreamExtended = null"
},
'\n'));
@@ -151,7 +150,7 @@ public class KinesisClientLibConfiguratorTest {
public void testWithUnsupportedClientConfigurationVariables() {
MultiLangDaemonConfiguration config = getConfiguration(StringUtils.join(
new String[] {
- "AWSCredentialsProvider = " + credentialName1 + ", " + credentialName2,
+ "AwsCredentialsProvider = " + credentialName1 + ", " + credentialName2,
"workerId = id",
"kinesisClientConfig = {}",
"streamName = stream",
@@ -170,7 +169,7 @@ public class KinesisClientLibConfiguratorTest {
MultiLangDaemonConfiguration config = getConfiguration(StringUtils.join(
new String[] {
"streamName = kinesis",
- "AWSCredentialsProvider = " + credentialName2 + ", " + credentialName1,
+ "AwsCredentialsProvider = " + credentialName2 + ", " + credentialName1,
"workerId = w123",
"maxRecords = 10",
"metricsMaxQueueSize = 20",
@@ -195,7 +194,7 @@ public class KinesisClientLibConfiguratorTest {
new String[] {
"streamName = a",
"applicationName = b",
- "AWSCredentialsProvider = ABCD, " + credentialName1,
+ "AwsCredentialsProvider = ABCD, " + credentialName1,
"workerId = 0",
"cleanupLeasesUponShardCompletion = false",
"validateSequenceNumberBeforeCheckpointing = true"
@@ -233,7 +232,7 @@ public class KinesisClientLibConfiguratorTest {
new String[] {
"streamName = a",
"applicationName = b",
- "AWSCredentialsProvider = ABCD," + credentialName1,
+ "AwsCredentialsProvider = ABCD," + credentialName1,
"workerId = 1",
"metricsEnabledDimensions = ShardId, WorkerIdentifier"
},
@@ -253,7 +252,7 @@ public class KinesisClientLibConfiguratorTest {
new String[] {
"streamName = a",
"applicationName = b",
- "AWSCredentialsProvider = ABCD," + credentialName1,
+ "AwsCredentialsProvider = ABCD," + credentialName1,
"workerId = 123",
"initialPositionInStream = TriM_Horizon"
},
@@ -268,7 +267,7 @@ public class KinesisClientLibConfiguratorTest {
new String[] {
"streamName = a",
"applicationName = b",
- "AWSCredentialsProvider = ABCD," + credentialName1,
+ "AwsCredentialsProvider = ABCD," + credentialName1,
"workerId = 123",
"initialPositionInStream = LateSt"
},
@@ -283,7 +282,7 @@ public class KinesisClientLibConfiguratorTest {
new String[] {
"streamName = a",
"applicationName = b",
- "AWSCredentialsProvider = ABCD," + credentialName1,
+ "AwsCredentialsProvider = ABCD," + credentialName1,
"workerId = 123",
"initialPositionInStream = TriM_Horizon",
"abc = 1"
@@ -302,7 +301,7 @@ public class KinesisClientLibConfiguratorTest {
new String[] {
"streamName = a",
"applicationName = b",
- "AWSCredentialsProvider = ABCD," + credentialName1,
+ "AwsCredentialsProvider = ABCD," + credentialName1,
"workerId = 123",
"initialPositionInStream = TriM_Horizon",
"maxGetRecordsThreadPool = 1"
@@ -318,7 +317,7 @@ public class KinesisClientLibConfiguratorTest {
new String[] {
"streamName = a",
"applicationName = b",
- "AWSCredentialsProvider = ABCD," + credentialName1,
+ "AwsCredentialsProvider = ABCD," + credentialName1,
"workerId = 123",
"initialPositionInStream = TriM_Horizon",
"maxGetRecordsThreadPool = 0",
@@ -334,7 +333,7 @@ public class KinesisClientLibConfiguratorTest {
new String[] {
"streamName = a",
"applicationName = b",
- "AWSCredentialsProvider = " + credentialName1,
+ "AwsCredentialsProvider = " + credentialName1,
"workerId = 123",
"failoverTimeMillis = 100nf"
},
@@ -348,7 +347,7 @@ public class KinesisClientLibConfiguratorTest {
new String[] {
"streamName = a",
"applicationName = b",
- "AWSCredentialsProvider = " + credentialName1,
+ "AwsCredentialsProvider = " + credentialName1,
"workerId = 123",
"failoverTimeMillis = -12"
},
@@ -380,7 +379,7 @@ public class KinesisClientLibConfiguratorTest {
new String[] {
"streamName = a",
"applicationName = b",
- "AWSCredentialsProvider = " + credentialName1,
+ "AwsCredentialsProvider = " + credentialName1,
"failoverTimeMillis = 100",
"shardSyncIntervalMillis = 500"
},
@@ -397,7 +396,7 @@ public class KinesisClientLibConfiguratorTest {
String test = StringUtils.join(
new String[] {
"applicationName = b",
- "AWSCredentialsProvider = " + credentialName1,
+ "AwsCredentialsProvider = " + credentialName1,
"workerId = 123",
"failoverTimeMillis = 100"
},
@@ -410,7 +409,7 @@ public class KinesisClientLibConfiguratorTest {
String test = StringUtils.join(
new String[] {
"applicationName = b",
- "AWSCredentialsProvider = " + credentialName1,
+ "AwsCredentialsProvider = " + credentialName1,
"workerId = 123",
"failoverTimeMillis = 100",
"streamName = ",
@@ -425,7 +424,7 @@ public class KinesisClientLibConfiguratorTest {
String test = StringUtils.join(
new String[] {
"streamName = a",
- "AWSCredentialsProvider = " + credentialName1,
+ "AwsCredentialsProvider = " + credentialName1,
"workerId = 123",
"failoverTimeMillis = 100"
},
@@ -434,12 +433,12 @@ public class KinesisClientLibConfiguratorTest {
}
@Test
- public void testWithAWSCredentialsFailed() {
+ public void testWithAwsCredentialsFailed() {
String test = StringUtils.join(
new String[] {
"streamName = a",
"applicationName = b",
- "AWSCredentialsProvider = " + credentialName2,
+ "AwsCredentialsProvider = " + credentialName2,
"failoverTimeMillis = 100",
"shardSyncIntervalMillis = 500"
},
@@ -457,6 +456,34 @@ public class KinesisClientLibConfiguratorTest {
}
}
+ @Test
+ public void testProcessKeyWithExpectedCasing() {
+ String key = "AwsCredentialsProvider";
+ String result = configurator.processKey(key);
+ assertEquals("awsCredentialsProvider", result);
+ }
+
+ @Test
+ public void testProcessKeyWithOldCasing() {
+ String key = "AWSCredentialsProvider";
+ String result = configurator.processKey(key);
+ assertEquals("awsCredentialsProvider", result);
+ }
+
+ @Test
+ public void testProcessKeyWithMixedCasing() {
+ String key = "AwScReDeNtIaLsPrOvIdEr";
+ String result = configurator.processKey(key);
+ assertEquals("awsCredentialsProvider", result);
+ }
+
+ @Test
+ public void testProcessKeyWithSuffix() {
+ String key = "awscredentialsproviderDynamoDB";
+ String result = configurator.processKey(key);
+ assertEquals("awsCredentialsProviderDynamoDB", result);
+ }
+
// TODO: fix this test
@Test
public void testWithDifferentAWSCredentialsForDynamoDBAndCloudWatch() {
@@ -464,9 +491,9 @@ public class KinesisClientLibConfiguratorTest {
new String[] {
"streamName = a",
"applicationName = b",
- "AWSCredentialsProvider = " + credentialNameKinesis,
- "AWSCredentialsProviderDynamoDB = " + credentialNameDynamoDB,
- "AWSCredentialsProviderCloudWatch = " + credentialNameCloudWatch,
+ "AwsCredentialsProvider = " + credentialNameKinesis,
+ "AwsCredentialsProviderDynamoDB = " + credentialNameDynamoDB,
+ "AwsCredentialsProviderCloudWatch = " + credentialNameCloudWatch,
"failoverTimeMillis = 100",
"shardSyncIntervalMillis = 500"
},
@@ -492,9 +519,9 @@ public class KinesisClientLibConfiguratorTest {
new String[] {
"streamName = a",
"applicationName = b",
- "AWSCredentialsProvider = " + credentialNameKinesis,
- "AWSCredentialsProviderDynamoDB = " + credentialName2,
- "AWSCredentialsProviderCloudWatch = " + credentialName2,
+ "AwsCredentialsProvider = " + credentialNameKinesis,
+ "AwsCredentialsProviderDynamoDB = " + credentialName2,
+ "AwsCredentialsProviderCloudWatch = " + credentialName2,
"failoverTimeMillis = 100",
"shardSyncIntervalMillis = 500"
},
@@ -526,71 +553,56 @@ public class KinesisClientLibConfiguratorTest {
/**
* This credentials provider will always succeed
*/
- public static class AlwaysSucceedCredentialsProvider implements AWSCredentialsProvider {
+ public static class AlwaysSucceedCredentialsProvider implements AwsCredentialsProvider {
@Override
- public AWSCredentials getCredentials() {
- return new BasicAWSCredentials("a", "b");
+ public AwsCredentials resolveCredentials() {
+ return AwsBasicCredentials.create("a", "b");
}
-
- @Override
- public void refresh() {}
}
/**
* This credentials provider will always succeed
*/
- public static class AlwaysSucceedCredentialsProviderKinesis implements AWSCredentialsProvider {
+ public static class AlwaysSucceedCredentialsProviderKinesis implements AwsCredentialsProvider {
@Override
- public AWSCredentials getCredentials() {
- return new BasicAWSCredentials("", "");
+ public AwsCredentials resolveCredentials() {
+ return AwsBasicCredentials.create("DUMMY_ACCESS_KEY_ID", "DUMMY_SECRET_ACCESS_KEY");
}
-
- @Override
- public void refresh() {}
}
/**
* This credentials provider will always succeed
*/
- public static class AlwaysSucceedCredentialsProviderDynamoDB implements AWSCredentialsProvider {
+ public static class AlwaysSucceedCredentialsProviderDynamoDB implements AwsCredentialsProvider {
@Override
- public AWSCredentials getCredentials() {
- return new BasicAWSCredentials("", "");
+ public AwsCredentials resolveCredentials() {
+ return AwsBasicCredentials.create("DUMMY_ACCESS_KEY_ID", "DUMMY_SECRET_ACCESS_KEY");
}
-
- @Override
- public void refresh() {}
}
/**
* This credentials provider will always succeed
*/
- public static class AlwaysSucceedCredentialsProviderCloudWatch implements AWSCredentialsProvider {
+ public static class AlwaysSucceedCredentialsProviderCloudWatch implements AwsCredentialsProvider {
@Override
- public AWSCredentials getCredentials() {
- return new BasicAWSCredentials("", "");
+ public AwsCredentials resolveCredentials() {
+ return AwsBasicCredentials.create("DUMMY_ACCESS_KEY_ID", "DUMMY_SECRET_ACCESS_KEY");
}
-
- @Override
- public void refresh() {}
}
/**
* This credentials provider will always fail
*/
- public static class AlwaysFailCredentialsProvider implements AWSCredentialsProvider {
+ public static class AlwaysFailCredentialsProvider implements AwsCredentialsProvider {
@Override
- public AWSCredentials getCredentials() {
+ public AwsCredentials resolveCredentials() {
throw new IllegalArgumentException();
}
-
- @Override
- public void refresh() {}
}
private MultiLangDaemonConfiguration getConfiguration(String configString) {
diff --git a/amazon-kinesis-client-multilang/src/test/resources/multilang.properties b/amazon-kinesis-client-multilang/src/test/resources/multilang.properties
index 34cb0c1a..8ded9bc9 100644
--- a/amazon-kinesis-client-multilang/src/test/resources/multilang.properties
+++ b/amazon-kinesis-client-multilang/src/test/resources/multilang.properties
@@ -17,10 +17,12 @@ streamName = kclpysample
applicationName = MultiLangTest
# Users can change the credentials provider the KCL will use to retrieve credentials.
-# The DefaultAWSCredentialsProviderChain checks several other providers, which is
+# Expected key name (case-sensitive):
+# AwsCredentialsProvider / AwsCredentialsProviderDynamoDB / AwsCredentialsProviderCloudWatch
+# The DefaultCredentialsProvider checks several other providers, which is
# described here:
-# http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.html
-AWSCredentialsProvider = DefaultAWSCredentialsProviderChain
+# https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/DefaultCredentialsProvider.html
+AwsCredentialsProvider = DefaultCredentialsProvider
# Appended to the user agent of the KCL. Does not impact the functionality of the
# KCL in any other way.
diff --git a/amazon-kinesis-client/pom.xml b/amazon-kinesis-client/pom.xml
index a185756b..4106a09f 100644
--- a/amazon-kinesis-client/pom.xml
+++ b/amazon-kinesis-client/pom.xml
@@ -82,6 +82,12 @@
software.amazon.glue
schema-registry-serde
${gsr.version}
+
+
+ com.amazonaws
+ aws-java-sdk-sts
+
+
software.amazon.glue
diff --git a/docs/multilang/configuring-credential-providers.md b/docs/multilang/configuring-credential-providers.md
index 9b85baaa..56bde627 100644
--- a/docs/multilang/configuring-credential-providers.md
+++ b/docs/multilang/configuring-credential-providers.md
@@ -8,24 +8,35 @@ This document should help multilang customers configure a suitable `CredentialPr
## Sample Provider Configuration
-In a Properties file, an `AWSCredentialsProperty` configuration might look like:
+In a Properties file, an `AwsCredentialsProperty` configuration might look like:
```
-AWSCredentialsProvider = STSAssumeRoleSessionCredentialsProvider||
+AwsCredentialsProvider = StsAssumeRoleCredentialsProvider|||endpointRegion=us-east-1
```
-This basic configuration creates an [STSAssumeRoleSessionCredentialsProvider][sts-assume-provider] with an ARN and session name.
+This basic configuration creates an [StsAssumeRoleCredentialsProvider][sts-assume-provider] with an ARN and session name.
+If `endpointRegion` is not specified, the provider will use the region defined in the AWS config file.
+If no region is found in the config file, the credentials provider will fail.
+
+The providers generated by this config property will be [AWS SDK v2 AwsCredentialsProviders][aws-credentials-provider].
+These differ from the SDK v1 AWSCredentialsProviders in a number of ways. See [Credentials Provider Changes][credentials-provider-changes].
+
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:
+Leveraging nested properties, an `AwsCredentialsProperty` value might change to:
```
-AWSCredentialsProvider = KclSTSAssumeRoleSessionCredentialsProvider||\
+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
+```
+
## Nested Properties
-KCL multilang supports "nested properties" on the `AWSCredentialsProvider` key in the properties file.
+KCL multilang supports "nested properties" on the `AwsCredentialsProvider` key in the properties file.
The [Backus-Naur form][bnf] of the value:
```
::= ["|" ]* ["|" ]*
@@ -36,8 +47,9 @@ 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
-(e.g., [STSAssumeRoleSessionCredentialsProvider(String, String)][sts-assume-provider-constructor]).
+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.
@@ -54,18 +66,27 @@ A backwards-compatible addition might look like:
}
```
-### KclSTSAssumeRoleSessionCredentialsProvider
-
-KCL multilang includes a [custom nested property processor for `STSAssumeRole`][kcl-sts-provider].
-Multilang configurations that use `STSAssumeRoleSessionCredentialsProvider` need only prefix `Kcl` to exercise this new provider:
+Leveraging nested properties, an `AwsCredentialsProperty` value might look like:
```
-AWSCredentialsProvider = KclSTSAssumeRoleSessionCredentialsProvider||
+AwsCredentialsProvider = KclSTSAssumeRoleSessionCredentialsProvider||\
+ |endpointRegion=us-east-1|externalId=spartacus
+```
+
+N.B. Backslash (`\`) is for multi-line legibility and is not required.
+### KclStsAssumeRoleCredentialsProvider
+
+KCL multilang includes a [custom nested property processor for `StsAssumeRole`][kcl-sts-provider].
+Multilang configurations that use `StsAssumeRoleSessionCredentialsProvider` need only prefix `Kcl` to exercise this new provider:
+```
+AwsCredentialsProvider = KclStsAssumeRoleCredentialsProvider|||endpointRegion=us-east-1
```
[aws-credentials-provider]: https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/AwsCredentialsProvider.html
[bnf]: https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form
-[kcl-sts-provider]: /amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/auth/KclSTSAssumeRoleSessionCredentialsProvider.java
+[kcl-sts-provider]: /amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/auth/KclStsAssumeRoleCredentialsProvider.java
[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://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/STSAssumeRoleSessionCredentialsProvider.html
-[sts-assume-provider-constructor]: https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/STSAssumeRoleSessionCredentialsProvider.html#STSAssumeRoleSessionCredentialsProvider-java.lang.String-java.lang.String-
+[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
+[credentials-provider-changes]: https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/migration-client-credentials.html
\ No newline at end of file