diff --git a/pom.xml b/pom.xml
index f6648d81..b3427bed 100644
--- a/pom.xml
+++ b/pom.xml
@@ -52,6 +52,11 @@
aws-java-sdk-cloudwatch
${aws-java-sdk.version}
+
+ com.amazonaws
+ aws-java-sdk-sts
+ ${aws-java-sdk.version}
+
com.google.guava
guava
diff --git a/src/main/java/com/amazonaws/services/kinesis/clientlibrary/config/AWSCredentialsProviderPropertyValueDecoder.java b/src/main/java/com/amazonaws/services/kinesis/clientlibrary/config/AWSCredentialsProviderPropertyValueDecoder.java
index 1f508771..9976b071 100644
--- a/src/main/java/com/amazonaws/services/kinesis/clientlibrary/config/AWSCredentialsProviderPropertyValueDecoder.java
+++ b/src/main/java/com/amazonaws/services/kinesis/clientlibrary/config/AWSCredentialsProviderPropertyValueDecoder.java
@@ -17,6 +17,7 @@ package com.amazonaws.services.kinesis.clientlibrary.config;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.lang.reflect.Constructor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -30,6 +31,7 @@ class AWSCredentialsProviderPropertyValueDecoder implements IPropertyValueDecode
private static final Log LOG = LogFactory.getLog(AWSCredentialsProviderPropertyValueDecoder.class);
private static final String AUTH_PREFIX = "com.amazonaws.auth.";
private static final String LIST_DELIMITER = ",";
+ private static final String ARG_DELIMITER = "|";
/**
* Constructor.
@@ -39,7 +41,7 @@ class AWSCredentialsProviderPropertyValueDecoder implements IPropertyValueDecode
/**
* Get AWSCredentialsProvider property.
- *
+ *
* @param value property value as String
* @return corresponding variable in correct type
*/
@@ -70,11 +72,25 @@ class AWSCredentialsProviderPropertyValueDecoder implements IPropertyValueDecode
private static List getValidCredentialsProviders(List providerNames) {
List credentialsProviders = new ArrayList();
for (String providerName : providerNames) {
- try {
- Class> className = Class.forName(providerName);
- credentialsProviders.add((AWSCredentialsProvider) className.newInstance());
- } catch (Exception e) {
- LOG.debug("Can't find any credentials provider matching " + providerName + ".");
+ if (providerName.contains(ARG_DELIMITER)) {
+ String[] nameAndArgs = providerName.split("\\" + ARG_DELIMITER);
+ Class>[] argTypes = new Class>[nameAndArgs.length - 1];
+ Arrays.fill(argTypes, String.class);
+ try {
+ Class> className = Class.forName(nameAndArgs[0]);
+ Constructor> c = className.getConstructor(argTypes);
+ credentialsProviders.add((AWSCredentialsProvider) c.newInstance(
+ Arrays.copyOfRange(nameAndArgs, 1, nameAndArgs.length)));
+ } catch (Exception e) {
+ LOG.debug("Can't find any credentials provider matching " + providerName + ".");
+ }
+ } else {
+ try {
+ Class> className = Class.forName(providerName);
+ credentialsProviders.add((AWSCredentialsProvider) className.newInstance());
+ } catch (Exception e) {
+ LOG.debug("Can't find any credentials provider matching " + providerName + ".");
+ }
}
}
return credentialsProviders;
@@ -97,13 +113,13 @@ class AWSCredentialsProviderPropertyValueDecoder implements IPropertyValueDecode
private static List getPossibleFullClassNames(String s) {
/*
* We take care of three cases :
- *
+ *
* 1. Customer provides a short name of common providers in com.amazonaws.auth package i.e. any classes
* implementing the AWSCredentialsProvider interface:
* http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/AWSCredentialsProvider.html
- *
+ *
* 2. Customer provides a full name of common providers e.g. com.amazonaws.auth.ClasspathFileCredentialsProvider
- *
+ *
* 3. Customer provides a custom credentials provider with full name of provider
*/
diff --git a/src/test/java/com/amazonaws/services/kinesis/clientlibrary/config/AWSCredentialsProviderPropertyValueDecoderTest.java b/src/test/java/com/amazonaws/services/kinesis/clientlibrary/config/AWSCredentialsProviderPropertyValueDecoderTest.java
new file mode 100644
index 00000000..23515926
--- /dev/null
+++ b/src/test/java/com/amazonaws/services/kinesis/clientlibrary/config/AWSCredentialsProviderPropertyValueDecoderTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Amazon Software License (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/asl/
+ *
+ * or in the "license" file accompanying this file. This file 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 com.amazonaws.services.kinesis.clientlibrary.config;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.Set;
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.lang.StringUtils;
+import org.junit.Test;
+
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.AWSCredentialsProvider;
+import com.amazonaws.auth.AWSCredentialsProviderChain;
+import com.amazonaws.auth.profile.ProfileCredentialsProvider;
+import com.amazonaws.services.kinesis.clientlibrary.config.AWSCredentialsProviderPropertyValueDecoder;
+
+public class AWSCredentialsProviderPropertyValueDecoderTest {
+
+ private String credentialName1 =
+ "com.amazonaws.services.kinesis.clientlibrary.config.KinesisClientLibConfiguratorTest$AlwaysSucceedCredentialsProvider";
+ private String credentialName2 =
+ "com.amazonaws.services.kinesis.clientlibrary.config.KinesisClientLibConfiguratorTest$AlwaysFailCredentialsProvider";
+ private AWSCredentialsProviderPropertyValueDecoder decoder = new AWSCredentialsProviderPropertyValueDecoder();
+
+ @Test
+ public void testSingleProvider() {
+ AWSCredentialsProvider provider = decoder.decodeValue(credentialName1);
+ assertEquals(provider.getClass(), AWSCredentialsProviderChain.class);
+ }
+
+ @Test
+ public void testTwoProviders() {
+ AWSCredentialsProvider provider = decoder.decodeValue(credentialName1 + "," + credentialName2);
+ assertEquals(provider.getClass(), AWSCredentialsProviderChain.class);
+ }
+
+ @Test
+ public void testProfileProviderWithOneArg() {
+ AWSCredentialsProvider provider = decoder.decodeValue(ProfileCredentialsProvider.class.getName() + "|profileName");
+ assertEquals(provider.getClass(), AWSCredentialsProviderChain.class);
+ }
+
+ @Test
+ public void testProfileProviderWithTwoArgs() throws IOException {
+ File temp = File.createTempFile("test-profiles-file", ".tmp");
+ temp.deleteOnExit();
+ AWSCredentialsProvider provider = decoder.decodeValue(ProfileCredentialsProvider.class.getName() +
+ "|" + temp.getAbsolutePath() + "|profileName");
+ assertEquals(provider.getClass(), AWSCredentialsProviderChain.class);
+ }
+
+ /**
+ * This credentials provider will always succeed
+ */
+ public static class AlwaysSucceedCredentialsProvider implements AWSCredentialsProvider {
+
+ @Override
+ public AWSCredentials getCredentials() {
+ return null;
+ }
+
+ @Override
+ public void refresh() {
+ }
+
+ }
+
+ /**
+ * This credentials provider will always fail
+ */
+ public static class AlwaysFailCredentialsProvider implements AWSCredentialsProvider {
+
+ @Override
+ public AWSCredentials getCredentials() {
+ throw new IllegalArgumentException();
+ }
+
+ @Override
+ public void refresh() {
+ }
+
+ }
+}
diff --git a/src/test/java/com/amazonaws/services/kinesis/clientlibrary/lib/worker/KinesisClientLibConfigurationTest.java b/src/test/java/com/amazonaws/services/kinesis/clientlibrary/lib/worker/KinesisClientLibConfigurationTest.java
index 588c6d79..9da391af 100644
--- a/src/test/java/com/amazonaws/services/kinesis/clientlibrary/lib/worker/KinesisClientLibConfigurationTest.java
+++ b/src/test/java/com/amazonaws/services/kinesis/clientlibrary/lib/worker/KinesisClientLibConfigurationTest.java
@@ -56,6 +56,7 @@ public class KinesisClientLibConfigurationTest {
// Test constructor with all valid arguments.
config =
new KinesisClientLibConfiguration(TEST_STRING,
+ TEST_STRING,
TEST_STRING,
TEST_STRING,
null,
@@ -93,6 +94,7 @@ public class KinesisClientLibConfigurationTest {
try {
config =
new KinesisClientLibConfiguration(TEST_STRING,
+ TEST_STRING,
TEST_STRING,
TEST_STRING,
null,
@@ -126,6 +128,7 @@ public class KinesisClientLibConfigurationTest {
try {
config =
new KinesisClientLibConfiguration(TEST_STRING,
+ TEST_STRING,
TEST_STRING,
TEST_STRING,
null,
@@ -203,7 +206,7 @@ public class KinesisClientLibConfigurationTest {
AmazonDynamoDBClient dclient = Mockito.mock(AmazonDynamoDBClient.class);
AmazonCloudWatchClient cclient = Mockito.mock(AmazonCloudWatchClient.class);
Region region = RegionUtils.getRegion("us-west-2");
-
+
AWSCredentialsProvider credentialsProvider = Mockito.mock(AWSCredentialsProvider.class);
KinesisClientLibConfiguration kclConfig =
new KinesisClientLibConfiguration("Test", "Test", credentialsProvider, "0")
@@ -256,7 +259,7 @@ public class KinesisClientLibConfigurationTest {
Mockito.verify(kclConfig, Mockito.times(9)).getRegionName();
Mockito.verify(kclConfig, Mockito.times(4)).getKinesisEndpoint();
-
+
kclConfig = Mockito.spy(
new KinesisClientLibConfiguration("Test", "Test", credentialsProvider, "0")
.withKinesisEndpoint("https://kinesis.eu-west-1.amazonaws.com"));
@@ -288,6 +291,7 @@ public class KinesisClientLibConfigurationTest {
Mockito.mock(AWSCredentialsProvider.class);
try {
new KinesisClientLibConfiguration(TEST_STRING,
+ TEST_STRING,
TEST_STRING,
TEST_STRING,
null,