Skip to content

Commit 7f4e0ff

Browse files
authored
feat: add JVM property region provider (#295)
1 parent b5df102 commit 7f4e0ff

File tree

9 files changed

+126
-30
lines changed

9 files changed

+126
-30
lines changed

aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/CredentialsProvider.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,3 @@ public interface CredentialsProvider {
1515
*/
1616
public suspend fun getCredentials(): Credentials
1717
}
18-
19-
// TODO - add proxies for all the credentials providers in aws-crt-kotlin

aws-runtime/auth/common/src/aws/sdk/kotlin/runtime/auth/EnvironmentCredentialsProvider.kt

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package aws.sdk.kotlin.runtime.auth
77

8+
import aws.sdk.kotlin.runtime.AwsSdkSetting
89
import aws.sdk.kotlin.runtime.ConfigurationException
910
import aws.smithy.kotlin.runtime.util.Platform
1011

@@ -13,20 +14,14 @@ import aws.smithy.kotlin.runtime.util.Platform
1314
*/
1415
public class EnvironmentCredentialsProvider
1516
public constructor(private val getEnv: (String) -> String?) : CredentialsProvider {
16-
public companion object {
17-
internal const val ACCESS_KEY_ID: String = "AWS_ACCESS_KEY_ID"
18-
internal const val SECRET_ACCESS_KEY: String = "AWS_SECRET_ACCESS_KEY"
19-
internal const val SESSION_TOKEN: String = "AWS_SESSION_TOKEN"
20-
}
21-
2217
public constructor() : this(Platform::getenv)
2318

2419
private fun requireEnv(variable: String): String =
2520
getEnv(variable) ?: throw ConfigurationException("Unable to get value from environment variable $variable")
2621

2722
override suspend fun getCredentials(): Credentials = Credentials(
28-
accessKeyId = requireEnv(ACCESS_KEY_ID),
29-
secretAccessKey = requireEnv(SECRET_ACCESS_KEY),
30-
sessionToken = getEnv(SESSION_TOKEN),
23+
accessKeyId = requireEnv(AwsSdkSetting.AwsAccessKeyId.environmentVariable),
24+
secretAccessKey = requireEnv(AwsSdkSetting.AwsSecretAccessKey.environmentVariable),
25+
sessionToken = getEnv(AwsSdkSetting.AwsSessionToken.environmentVariable),
3126
)
3227
}

aws-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/EnvironmentCredentialsProviderTest.kt

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package aws.sdk.kotlin.runtime.auth
77

8+
import aws.sdk.kotlin.runtime.AwsSdkSetting
89
import aws.sdk.kotlin.runtime.ConfigurationException
910
import aws.sdk.kotlin.runtime.testing.runSuspendTest
1011
import kotlin.test.Test
@@ -17,33 +18,33 @@ class EnvironmentCredentialsProviderTest {
1718
@Test
1819
fun `it should read from environment variables (incl session token)`() = runSuspendTest {
1920
val provider = provider(
20-
EnvironmentCredentialsProvider.ACCESS_KEY_ID to "abc",
21-
EnvironmentCredentialsProvider.SECRET_ACCESS_KEY to "def",
22-
EnvironmentCredentialsProvider.SESSION_TOKEN to "ghi",
21+
AwsSdkSetting.AwsAccessKeyId.environmentVariable to "abc",
22+
AwsSdkSetting.AwsSecretAccessKey.environmentVariable to "def",
23+
AwsSdkSetting.AwsSessionToken.environmentVariable to "ghi",
2324
)
2425
assertEquals(provider.getCredentials(), Credentials("abc", "def", "ghi"))
2526
}
2627

2728
@Test
2829
fun `it should read from environment variables (excl session token)`() = runSuspendTest {
2930
val provider = provider(
30-
EnvironmentCredentialsProvider.ACCESS_KEY_ID to "abc",
31-
EnvironmentCredentialsProvider.SECRET_ACCESS_KEY to "def",
31+
AwsSdkSetting.AwsAccessKeyId.environmentVariable to "abc",
32+
AwsSdkSetting.AwsSecretAccessKey.environmentVariable to "def",
3233
)
3334
assertEquals(provider.getCredentials(), Credentials("abc", "def", null))
3435
}
3536

3637
@Test
37-
fun `it should throw an exception on missing access key`() = runSuspendTest {
38+
fun `it should throw an exception on missing access key`(): Unit = runSuspendTest {
3839
assertFailsWith<ConfigurationException> {
39-
provider(EnvironmentCredentialsProvider.SECRET_ACCESS_KEY to "def").getCredentials()
40+
provider(AwsSdkSetting.AwsSecretAccessKey.environmentVariable to "def").getCredentials()
4041
}
4142
}
4243

4344
@Test
44-
fun `it should throw an exception on missing secret key`() = runSuspendTest {
45+
fun `it should throw an exception on missing secret key`(): Unit = runSuspendTest {
4546
assertFailsWith<ConfigurationException> {
46-
provider(EnvironmentCredentialsProvider.ACCESS_KEY_ID to "abc").getCredentials()
47+
provider(AwsSdkSetting.AwsAccessKeyId.environmentVariable to "abc").getCredentials()
4748
}
4849
}
4950
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
6+
package aws.sdk.kotlin.runtime
7+
8+
// NOTE: The JVM property names MUST match the ones defined in the Java SDK for any setting added.
9+
// see: https://github.com/aws/aws-sdk-java-v2/blob/master/core/sdk-core/src/main/java/software/amazon/awssdk/core/SdkSystemSetting.java
10+
11+
/**
12+
* Settings to configure SDK runtime behavior
13+
*/
14+
@InternalSdkApi
15+
public sealed class AwsSdkSetting<T> (
16+
/**
17+
* The name of the corresponding environment variable that configures the setting
18+
*/
19+
public val environmentVariable: String,
20+
21+
/**
22+
* The name of the corresponding JVM system property that configures the setting
23+
*/
24+
public val jvmProperty: String,
25+
26+
/**
27+
* The default value (if one exists)
28+
*/
29+
public val defaultValue: T? = null
30+
) {
31+
/**
32+
* Configure the AWS access key ID.
33+
*
34+
* This value will not be ignored if the [AwsSecretAccessKey] is not specified.
35+
*/
36+
public object AwsAccessKeyId : AwsSdkSetting<String>("AWS_ACCESS_KEY_ID", "aws.accessKeyId")
37+
38+
/**
39+
* Configure the AWS secret access key.
40+
*
41+
* This value will not be ignored if the [AwsAccessKeyId] is not specified.
42+
*/
43+
public object AwsSecretAccessKey : AwsSdkSetting<String>("AWS_SECRET_ACCESS_KEY", "aws.secretAccessKey")
44+
45+
/**
46+
* Configure the AWS session token.
47+
*/
48+
public object AwsSessionToken : AwsSdkSetting<String>("AWS_SESSION_TOKEN", "aws.sessionToken")
49+
50+
/**
51+
* Configure the default region.
52+
*/
53+
public object AwsRegion : AwsSdkSetting<String>("AWS_REGION", "aws.region")
54+
}

aws-runtime/regions/common/src/aws/sdk/kotlin/runtime/regions/providers/DefaultAwsRegionProviderChain.kt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,11 @@
55

66
package aws.sdk.kotlin.runtime.regions.providers
77

8-
// FIXME - this probably needs to be expect/actual to customize the chain per/target platform (and definitely needs per/platform tests)
9-
108
/**
119
* [AwsRegionProvider] that looks for region in this order:
1210
* 1. Check `aws.region` system property (JVM only)
13-
* 2. Check the `AWS_REGION` and `AWS_DEFAULT_REGION` environment variable(s) (JVM, Node, Native)
11+
* 2. Check the `AWS_REGION` environment variable (JVM, Node, Native)
1412
* 3. Check the AWS config files/profile for region information
1513
* 4. If running on EC2, check the EC2 metadata service for region
1614
*/
17-
public class DefaultAwsRegionProviderChain : AwsRegionProviderChain {
18-
public constructor() : super(EnvironmentRegionProvider())
19-
}
15+
public expect class DefaultAwsRegionProviderChain public constructor() : AwsRegionProvider

aws-runtime/regions/common/src/aws/sdk/kotlin/runtime/regions/providers/EnvironmentRegionProvider.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55

66
package aws.sdk.kotlin.runtime.regions.providers
77

8+
import aws.sdk.kotlin.runtime.AwsSdkSetting
89
import aws.smithy.kotlin.runtime.util.Platform
910

10-
private const val AWS_ENVIRON_REGION = "AWS_REGION"
11-
1211
/**
1312
* Provide a mapping from key to value
1413
*/
@@ -17,13 +16,13 @@ public fun interface Environment {
1716
}
1817

1918
/**
20-
* [AwsRegionProvider] that checks `AWS_REGION` and `AWS_DEFAULT` region environment variables
19+
* [AwsRegionProvider] that checks `AWS_REGION` region environment variable
2120
* @param environ the environment mapping to lookup keys in (defaults to the system environment)
2221
*/
2322
public class EnvironmentRegionProvider(
2423
private val environ: Environment
2524
) : AwsRegionProvider {
2625
public constructor() : this(Platform::getenv)
2726

28-
override suspend fun getRegion(): String? = environ.get(AWS_ENVIRON_REGION)
27+
override suspend fun getRegion(): String? = environ.get(AwsSdkSetting.AwsRegion.environmentVariable)
2928
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
6+
package aws.sdk.kotlin.runtime.regions.providers
7+
8+
public actual class DefaultAwsRegionProviderChain public actual constructor() :
9+
AwsRegionProvider,
10+
AwsRegionProviderChain(
11+
JvmSystemPropRegionProvider(),
12+
EnvironmentRegionProvider()
13+
)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
6+
package aws.sdk.kotlin.runtime.regions.providers
7+
8+
import aws.sdk.kotlin.runtime.AwsSdkSetting
9+
10+
/**
11+
* [AwsRegionProvider] that checks `aws.region` system property
12+
*/
13+
internal class JvmSystemPropRegionProvider : AwsRegionProvider {
14+
override suspend fun getRegion(): String? = System.getProperty(AwsSdkSetting.AwsRegion.jvmProperty, null)
15+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
6+
package aws.sdk.kotlin.runtime.regions.providers
7+
8+
import aws.sdk.kotlin.runtime.AwsSdkSetting
9+
import aws.sdk.kotlin.runtime.testing.runSuspendTest
10+
import org.junit.jupiter.api.Test
11+
import kotlin.test.assertEquals
12+
import kotlin.test.assertNull
13+
14+
class JvmSystemPropRegionProviderTest {
15+
16+
@Test
17+
fun testGetRegion() = runSuspendTest {
18+
val provider = JvmSystemPropRegionProvider()
19+
20+
assertNull(provider.getRegion())
21+
22+
System.setProperty(AwsSdkSetting.AwsRegion.jvmProperty, "us-east-1")
23+
assertEquals("us-east-1", provider.getRegion())
24+
}
25+
}

0 commit comments

Comments
 (0)