Skip to content

Commit 7d8d115

Browse files
committed
Merge branch 'main' of https://github.com/awslabs/aws-sdk-kotlin into jmespath-flatten
2 parents 1a2d989 + eb24838 commit 7d8d115

File tree

159 files changed

+179717
-21486
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

159 files changed

+179717
-21486
lines changed

CHANGELOG.md

Lines changed: 417 additions & 48 deletions
Large diffs are not rendered by default.

CONTRIBUTING.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ AWS service clients are generated from [Smithy](https://awslabs.github.io/smithy
1616
As such the code in `aws-sdk-kotlin` is a layer on top of generic Smithy based code generation tooling.
1717

1818

19-
2. Smithy Kotlin Codegen repo ([awslabs/smithy-kotlin](https://github.com/awslabs/smithy-kotlin))
19+
2. Smithy Kotlin Codegen repo ([smithy-lang/smithy-kotlin](https://github.com/smithy-lang/smithy-kotlin))
2020

2121
The `smithy-kotlin` repository contains the generic Smithy code generation tools for Kotlin.
2222

23-
If you want to contribute by diving into the codegen machinery and helping develop the SDK please refer to the [contributing guide](https://github.com/awslabs/smithy-kotlin/blob/main/CONTRIBUTING.md) in that repo.
23+
If you want to contribute by diving into the codegen machinery and helping develop the SDK please refer to the [contributing guide](https://github.com/smithy-lang/smithy-kotlin/blob/main/CONTRIBUTING.md) in that repo.
2424

2525

2626
## Reporting Bugs/Feature Requests
@@ -78,7 +78,7 @@ following fields:
7878
| `id` | `string` | yes | | A unique identifier for this entry. We recommend you generate a UUID for this field. |
7979
| `type` | `string` | yes | `bugfix`, `feature`, `documentation`, `misc` | The type of change being made. |
8080
| `description` | `string` | yes | | A description of the change being made.<ul><li>Prefix with `**Breaking**:` if the change is breaking</li><li>Use the imperative present tense (e.g., "change" not "changed" nor "changes")</li><li>Capitalize first letter</li><li>No dot (.) at the end unless there are multiple sentences</li></ul> |
81-
| `issues` | `string[]` | no | | A list of references to any related issues in the relevant repositories. A reference can be specified in several ways:<ul><li>The issue number, if local to this repository (eg. `#12345`)</li><li>A fully-qualified issue ID (eg.`awslabs/smithy-kotlin#12345`)</li><li>A fully-qualified URL (eg. `https://issuetracker.com/12345`)</li></ul> |
81+
| `issues` | `string[]` | no | | A list of references to any related issues in the relevant repositories. A reference can be specified in several ways:<ul><li>The issue number, if local to this repository (eg. `#12345`)</li><li>A fully-qualified issue ID (eg.`smithy-lang/smithy-kotlin#12345`)</li><li>A fully-qualified URL (eg. `https://issuetracker.com/12345`)</li></ul> |
8282
| `module` | `string` | no | | The area of the code affected by your changes. If unsure, leave this value unset. |
8383
| `requiresMinorVersionBump` | `boolean` | no | | Indicates the change will require a new minor version. This is usually the case after a breaking change. Defaults to false if flag is not included. |
8484

aws-runtime/aws-http/api/aws-http.api

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ public final class aws/sdk/kotlin/runtime/http/interceptors/AwsBusinessMetric :
145145
public static final field S3_EXPRESS_BUCKET Laws/sdk/kotlin/runtime/http/interceptors/AwsBusinessMetric;
146146
public static fun getEntries ()Lkotlin/enums/EnumEntries;
147147
public fun getIdentifier ()Ljava/lang/String;
148+
public fun toString ()Ljava/lang/String;
148149
public static fun valueOf (Ljava/lang/String;)Laws/sdk/kotlin/runtime/http/interceptors/AwsBusinessMetric;
149150
public static fun values ()[Laws/sdk/kotlin/runtime/http/interceptors/AwsBusinessMetric;
150151
}

aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/BusinessMetricsInterceptor.kt

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,19 @@ import aws.smithy.kotlin.runtime.client.ProtocolRequestInterceptorContext
1313
import aws.smithy.kotlin.runtime.http.interceptors.HttpInterceptor
1414
import aws.smithy.kotlin.runtime.http.request.HttpRequest
1515
import aws.smithy.kotlin.runtime.http.request.toBuilder
16+
import aws.smithy.kotlin.runtime.telemetry.logging.Logger
17+
import aws.smithy.kotlin.runtime.telemetry.logging.logger
18+
import kotlin.coroutines.coroutineContext
1619

1720
/**
1821
* Appends business metrics to the `User-Agent` header.
1922
*/
2023
public class BusinessMetricsInterceptor : HttpInterceptor {
2124
override suspend fun modifyBeforeTransmit(context: ProtocolRequestInterceptorContext<Any, HttpRequest>): HttpRequest {
25+
val logger = coroutineContext.logger<BusinessMetricsInterceptor>()
26+
2227
context.executionContext.getOrNull(BusinessMetrics)?.let { metrics ->
23-
val metricsString = formatMetrics(metrics)
28+
val metricsString = formatMetrics(metrics, logger)
2429
val currentUserAgentHeader = context.protocolRequest.headers[USER_AGENT]
2530
val modifiedRequest = context.protocolRequest.toBuilder()
2631

@@ -34,10 +39,22 @@ public class BusinessMetricsInterceptor : HttpInterceptor {
3439

3540
/**
3641
* Makes sure the metrics do not exceed the maximum size and truncates them if so.
42+
* Makes sure that metric identifiers are not > 2 chars in length. Skips them if so.
3743
*/
38-
private fun formatMetrics(metrics: MutableSet<BusinessMetric>): String {
39-
if (metrics.isEmpty()) return ""
40-
val metricsString = metrics.joinToString(",", "m/") { it.identifier }
44+
private fun formatMetrics(metrics: MutableSet<BusinessMetric>, logger: Logger): String {
45+
val allowedMetrics = metrics.filter {
46+
if (it.identifier.length > 2) {
47+
logger.warn {
48+
"Business metric '${it.identifier}' will be skipped due to length being > 2. " +
49+
"This is likely a bug. Please raise an issue at https://github.com/awslabs/aws-sdk-kotlin/issues/new/choose"
50+
}
51+
false
52+
} else {
53+
true
54+
}
55+
}
56+
if (allowedMetrics.isEmpty()) return ""
57+
val metricsString = allowedMetrics.joinToString(",", "m/") { it.identifier }
4158
val metricsByteArray = metricsString.encodeToByteArray()
4259

4360
if (metricsByteArray.size <= BUSINESS_METRICS_MAX_LENGTH) return metricsString
@@ -65,4 +82,7 @@ private fun formatMetrics(metrics: MutableSet<BusinessMetric>): String {
6582
public enum class AwsBusinessMetric(public override val identifier: String) : BusinessMetric {
6683
S3_EXPRESS_BUCKET("J"),
6784
DDB_MAPPER("d"),
85+
;
86+
87+
override fun toString(): String = identifier
6888
}

aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/middleware/UserAgent.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public class UserAgent(
4444

4545
// NOTE: Due to legacy issues with processing the user agent, the original content for
4646
// x-amz-user-agent and User-Agent is swapped here. See top note in the
47-
// sdk-user-agent-header SEP and https://github.com/awslabs/smithy-kotlin/issues/373
47+
// sdk-user-agent-header SEP and https://github.com/smithy-lang/smithy-kotlin/issues/373
4848
// for further details.
4949
req.subject.headers[USER_AGENT] = requestMetadata.xAmzUserAgent
5050
req.subject.headers[X_AMZ_USER_AGENT] = requestMetadata.userAgent

aws-runtime/aws-http/common/test/aws/sdk/kotlin/runtime/http/interceptors/BusinessMetricsInterceptorTest.kt

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,12 @@ import aws.smithy.kotlin.runtime.businessmetrics.BusinessMetric
1010
import aws.smithy.kotlin.runtime.businessmetrics.SmithyBusinessMetric
1111
import aws.smithy.kotlin.runtime.businessmetrics.emitBusinessMetric
1212
import aws.smithy.kotlin.runtime.client.ProtocolRequestInterceptorContext
13-
import aws.smithy.kotlin.runtime.collections.get
1413
import aws.smithy.kotlin.runtime.http.*
1514
import aws.smithy.kotlin.runtime.http.request.HttpRequest
1615
import aws.smithy.kotlin.runtime.net.url.Url
1716
import aws.smithy.kotlin.runtime.operation.ExecutionContext
1817
import kotlinx.coroutines.test.runTest
19-
import kotlin.test.Test
20-
import kotlin.test.assertFailsWith
21-
import kotlin.test.assertFalse
22-
import kotlin.test.assertTrue
18+
import kotlin.test.*
2319

2420
class BusinessMetricsInterceptorTest {
2521
@Test
@@ -32,6 +28,23 @@ class BusinessMetricsInterceptorTest {
3228
assertFalse(userAgentHeader.endsWith("m/"))
3329
}
3430

31+
@Test
32+
fun noValidBusinessMetrics() = runTest {
33+
val executionContext = ExecutionContext()
34+
35+
val invalidBusinessMetric = object : BusinessMetric {
36+
override val identifier: String = "All work and no play makes Jack a dull boy".repeat(1000)
37+
}
38+
39+
executionContext.emitBusinessMetric(invalidBusinessMetric)
40+
41+
val interceptor = BusinessMetricsInterceptor()
42+
val request = interceptor.modifyBeforeTransmit(interceptorContext(executionContext))
43+
val userAgentHeader = request.headers[USER_AGENT]!!
44+
45+
assertFalse(userAgentHeader.endsWith("m/"))
46+
}
47+
3548
@Test
3649
fun businessMetrics() = runTest {
3750
val executionContext = ExecutionContext()
@@ -66,49 +79,57 @@ class BusinessMetricsInterceptorTest {
6679
}
6780

6881
@Test
69-
fun truncateBusinessMetrics() = runTest {
82+
fun businessMetricsMaxLength() = runTest {
7083
val executionContext = ExecutionContext()
7184
executionContext.attributes[aws.smithy.kotlin.runtime.businessmetrics.BusinessMetrics] = mutableSetOf()
7285

73-
for (i in 0..1024) {
86+
for (i in 0..BUSINESS_METRICS_MAX_LENGTH) {
7487
executionContext.emitBusinessMetric(
7588
object : BusinessMetric {
7689
override val identifier: String = i.toString()
7790
},
7891
)
7992
}
8093

81-
val rawMetrics = executionContext[aws.smithy.kotlin.runtime.businessmetrics.BusinessMetrics]
82-
val rawMetricsString = rawMetrics.joinToString(",", "m/")
83-
val rawMetricsByteArray = rawMetricsString.encodeToByteArray()
84-
85-
assertTrue(rawMetricsByteArray.size >= BUSINESS_METRICS_MAX_LENGTH)
86-
8794
val interceptor = BusinessMetricsInterceptor()
8895
val request = interceptor.modifyBeforeTransmit(interceptorContext(executionContext))
8996
val userAgentHeader = request.headers[USER_AGENT]!!
90-
val truncatedMetrics = "m/" + userAgentHeader.substringAfter("m/")
97+
val metrics = "m/" + userAgentHeader.substringAfter("m/")
9198

92-
assertTrue(truncatedMetrics.encodeToByteArray().size <= BUSINESS_METRICS_MAX_LENGTH)
93-
assertFalse(truncatedMetrics.endsWith(","))
99+
assertTrue(metrics.encodeToByteArray().size <= BUSINESS_METRICS_MAX_LENGTH)
100+
assertFalse(metrics.endsWith(","))
94101
}
95102

96103
@Test
97-
fun malformedBusinessMetrics() = runTest {
104+
fun invalidBusinessMetric() = runTest {
98105
val executionContext = ExecutionContext()
99-
val reallyLongMetric = "All work and no play makes Jack a dull boy".repeat(1000)
100106

101-
executionContext.attributes.emitBusinessMetric(
102-
object : BusinessMetric {
103-
override val identifier: String = reallyLongMetric
104-
},
105-
)
107+
val validMetric = AwsBusinessMetric.S3_EXPRESS_BUCKET
108+
val invalidMetric = object : BusinessMetric {
109+
override val identifier: String = "All work and no play makes Jack a dull boy".repeat(1000)
110+
}
111+
112+
executionContext.attributes.emitBusinessMetric(validMetric)
113+
executionContext.attributes.emitBusinessMetric(invalidMetric)
106114

107115
val interceptor = BusinessMetricsInterceptor()
116+
val request = interceptor.modifyBeforeTransmit(interceptorContext(executionContext))
117+
val userAgentHeader = request.headers[USER_AGENT]!!
108118

109-
assertFailsWith<IllegalStateException>("Business metrics are incorrectly formatted:") {
110-
interceptor.modifyBeforeTransmit(interceptorContext(executionContext))
111-
}
119+
assertTrue(
120+
userAgentHeader.contains(validMetric.identifier),
121+
)
122+
assertFalse(
123+
userAgentHeader.contains(invalidMetric.identifier),
124+
)
125+
}
126+
127+
@Test
128+
fun businessMetricToString() {
129+
val businessMetricToString = AwsBusinessMetric.S3_EXPRESS_BUCKET.toString()
130+
val businessMetricIdentifier = AwsBusinessMetric.S3_EXPRESS_BUCKET.identifier
131+
132+
assertEquals(businessMetricIdentifier, businessMetricToString)
112133
}
113134
}
114135

bom/build.gradle.kts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ fun createBomConstraintsAndVersionCatalog() {
5454
}
5555
}
5656

57+
// Add the BOM itself to the version catalog
58+
catalogExt.versionCatalog {
59+
library("bom", "aws.sdk.kotlin:bom:$version")
60+
}
61+
5762
val ignoredSmithyKotlin = setOf(
5863
"smithy.kotlin.codegen",
5964
"smithy.kotlin.http.test",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package aws.sdk.kotlin.codegen.smoketests
2+
3+
import software.amazon.smithy.kotlin.codegen.KotlinSettings
4+
import software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration
5+
import software.amazon.smithy.kotlin.codegen.integration.SectionWriterBinding
6+
import software.amazon.smithy.kotlin.codegen.rendering.smoketests.SmokeTestSectionIds.SmokeTestsFile
7+
import software.amazon.smithy.model.Model
8+
9+
/**
10+
* SDK ID's of services that are deny listed from smoke test code generation.
11+
*/
12+
val smokeTestDenyList = setOf(
13+
"S3Tables",
14+
)
15+
16+
/**
17+
* Will wipe the smoke test runner file for services that are deny listed.
18+
* Some services model smoke tests incorrectly and the code generated file will not compile.
19+
*/
20+
class SmokeTestsDenyListIntegration : KotlinIntegration {
21+
override fun enabledForService(model: Model, settings: KotlinSettings): Boolean =
22+
settings.sdkId in smokeTestDenyList
23+
24+
override val sectionWriters: List<SectionWriterBinding>
25+
get() = listOf(
26+
SectionWriterBinding(
27+
SmokeTestsFile,
28+
) { writer, _ ->
29+
writer.write("// Smoke tests for service are deny listed")
30+
},
31+
)
32+
}

codegen/aws-sdk-codegen/src/main/resources/META-INF/services/software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ aws.sdk.kotlin.codegen.customization.s3.express.S3ExpressIntegration
4343
aws.sdk.kotlin.codegen.customization.s3.S3ExpiresIntegration
4444
aws.sdk.kotlin.codegen.BusinessMetricsIntegration
4545
aws.sdk.kotlin.codegen.smoketests.AwsSmokeTestsRunnerGeneratorIntegration
46+
aws.sdk.kotlin.codegen.smoketests.SmokeTestsDenyListIntegration
4647
aws.sdk.kotlin.codegen.smoketests.testing.SmokeTestSuccessHttpEngineIntegration
4748
aws.sdk.kotlin.codegen.smoketests.testing.SmokeTestFailHttpEngineIntegration
4849
aws.sdk.kotlin.codegen.customization.AwsQueryModeCustomization

0 commit comments

Comments
 (0)