Skip to content

Commit e7389ca

Browse files
authored
feat: redesign presigning API (#854)
1 parent 749626b commit e7389ca

File tree

12 files changed

+145
-221
lines changed

12 files changed

+145
-221
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"id": "5066f1c0-75a2-4eac-beb8-a48a1fbc8f18",
3+
"type": "feature",
4+
"description": "**Breaking**: Refresh presigning APIs to simplify usage and add new capabilities. See [this discussion post](https://github.com/awslabs/aws-sdk-kotlin/discussions/925) for more information.",
5+
"issues": [
6+
"awslabs/smithy-kotlin#755"
7+
]
8+
}

codegen/smithy-kotlin-codegen-testutils/src/main/kotlin/software/amazon/smithy/kotlin/codegen/test/CodegenTestUtils.kt

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
*/
55
package software.amazon.smithy.kotlin.codegen.test
66

7+
import software.amazon.smithy.aws.traits.protocols.AwsJson1_0Trait
8+
import software.amazon.smithy.aws.traits.protocols.AwsJson1_1Trait
9+
import software.amazon.smithy.aws.traits.protocols.AwsQueryTrait
10+
import software.amazon.smithy.aws.traits.protocols.Ec2QueryTrait
711
import software.amazon.smithy.aws.traits.protocols.RestJson1Trait
12+
import software.amazon.smithy.aws.traits.protocols.RestXmlTrait
813
import software.amazon.smithy.build.MockManifest
914
import software.amazon.smithy.codegen.core.Symbol
1015
import software.amazon.smithy.codegen.core.SymbolProvider
@@ -19,6 +24,7 @@ import software.amazon.smithy.model.knowledge.HttpBinding
1924
import software.amazon.smithy.model.knowledge.HttpBindingIndex
2025
import software.amazon.smithy.model.shapes.*
2126
import software.amazon.smithy.model.traits.TimestampFormatTrait
27+
import software.amazon.smithy.model.traits.Trait
2228
import software.amazon.smithy.utils.StringUtils
2329

2430
// This file houses test classes and functions relating to the code generator (protocols, serializers, etc)
@@ -130,13 +136,29 @@ class TestProtocolClientGenerator(
130136
httpBindingResolver: HttpBindingResolver,
131137
) : HttpProtocolClientGenerator(ctx, features, httpBindingResolver)
132138

139+
private val allProtocols = setOf(
140+
AwsJson1_0Trait.ID,
141+
AwsJson1_1Trait.ID,
142+
AwsQueryTrait.ID,
143+
Ec2QueryTrait.ID,
144+
RestJson1Trait.ID,
145+
RestXmlTrait.ID,
146+
)
147+
133148
/** An HttpBindingProtocolGenerator for testing (nothing is rendered for serializing/deserializing payload bodies) */
134-
class MockHttpProtocolGenerator : HttpBindingProtocolGenerator() {
149+
class MockHttpProtocolGenerator(model: Model) : HttpBindingProtocolGenerator() {
135150
override val defaultTimestampFormat: TimestampFormatTrait.Format = TimestampFormatTrait.Format.EPOCH_SECONDS
136151
override fun getProtocolHttpBindingResolver(model: Model, serviceShape: ServiceShape): HttpBindingResolver =
137152
HttpTraitResolver(model, serviceShape, ProtocolContentTypes.consistent("application/json"))
138153

139-
override val protocol: ShapeId = RestJson1Trait.ID
154+
override val protocol: ShapeId = model
155+
.serviceShapes
156+
.single()
157+
.allTraits
158+
.values
159+
.map(Trait::toShapeId)
160+
.singleOrNull(allProtocols::contains)
161+
?: RestJson1Trait.ID
140162

141163
override fun generateProtocolUnitTests(ctx: ProtocolGenerator.GenerationContext) {}
142164

codegen/smithy-kotlin-codegen-testutils/src/main/kotlin/software/amazon/smithy/kotlin/codegen/test/ModelTestUtils.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ fun Model.newTestContext(
116116
serviceName: String = TestModelDefault.SERVICE_NAME,
117117
packageName: String = TestModelDefault.NAMESPACE,
118118
settings: KotlinSettings = this.defaultSettings(serviceName, packageName),
119-
generator: ProtocolGenerator = MockHttpProtocolGenerator(),
119+
generator: ProtocolGenerator = MockHttpProtocolGenerator(this),
120120
integrations: List<KotlinIntegration> = listOf(),
121121
): TestContext {
122122
val manifest = MockManifest()

codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,12 @@ object RuntimeTypes {
189189
val EndpointProvider = symbol("EndpointProvider")
190190
val Endpoint = symbol("Endpoint")
191191
val EndpointProviderException = symbol("EndpointProviderException")
192+
val SigningContext = symbol("SigningContext")
193+
val SigningContextAttributeKey = symbol("SigningContextAttributeKey")
194+
195+
@get:JvmName("getSigningContextExtMethod")
196+
val signingContext = symbol("signingContext")
197+
192198
object Functions : RuntimeTypePackage(KotlinDependency.SMITHY_CLIENT, "endpoints.functions") {
193199
val substring = symbol("substring")
194200
val isValidHostLabel = symbol("isValidHostLabel")
@@ -272,13 +278,10 @@ object RuntimeTypes {
272278
val AwsSignedBodyHeader = symbol("AwsSignedBodyHeader")
273279
val AwsSigner = symbol("AwsSigner")
274280
val AwsSigningAttributes = symbol("AwsSigningAttributes")
281+
val AwsSigningConfig = symbol("AwsSigningConfig")
275282
val HashSpecification = symbol("HashSpecification")
276-
val createPresignedRequest = symbol("createPresignedRequest")
277-
val PresignedRequestConfig = symbol("PresignedRequestConfig")
278-
val PresigningLocation = symbol("PresigningLocation")
279-
val ServicePresignConfig = symbol("ServicePresignConfig")
280-
val SigningEndpointProvider = symbol("SigningEndpointProvider")
281-
val SigningContextualizedEndpoint = symbol("SigningContextualizedEndpoint")
283+
val mergeInto = symbol("mergeInto")
284+
val presignRequest = symbol("presignRequest")
282285
}
283286

284287
object AwsSigningStandard : RuntimeTypePackage(KotlinDependency.AWS_SIGNING_DEFAULT) {

codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/ServiceClientGeneratorTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ class ServiceClientGeneratorTest {
203203
val writer = KotlinWriter(TestModelDefault.NAMESPACE)
204204
val service = model.getShape(ShapeId.from(TestModelDefault.SERVICE_SHAPE_ID)).get().asServiceShape().get()
205205
val settings = KotlinSettings(service.id, KotlinSettings.PackageSettings(TestModelDefault.NAMESPACE, TestModelDefault.MODEL_VERSION), sdkId = service.id.name)
206-
val protocolGenerator = if (withProtocolGenerator) MockHttpProtocolGenerator() else null
206+
val protocolGenerator = if (withProtocolGenerator) MockHttpProtocolGenerator(model) else null
207207
val renderingCtx = RenderingContext(writer, service, model, provider, settings, protocolGenerator)
208208
val generator = ServiceClientGenerator(renderingCtx)
209209

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ kotlin.native.ignoreDisabledTargets=true
66
kotlin.mpp.enableCompatibilityMetadataVariant=true
77

88
# SDK
9-
sdkVersion=0.20.1-SNAPSHOT
9+
sdkVersion=0.21.0-SNAPSHOT
1010

1111
# kotlin
1212
kotlinVersion=1.8.10
@@ -44,4 +44,4 @@ kotlinLoggingVersion=3.0.0
4444
slf4jVersion=2.0.6
4545

4646
# crt
47-
crtKotlinVersion=0.6.8
47+
crtKotlinVersion=0.6.8

runtime/auth/aws-signing-common/api/aws-signing-common.api

Lines changed: 3 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ public final class aws/smithy/kotlin/runtime/auth/awssigning/AwsSigningAttribute
4040
public final fun getSigningService ()Laws/smithy/kotlin/runtime/util/AttributeKey;
4141
}
4242

43+
public final class aws/smithy/kotlin/runtime/auth/awssigning/AwsSigningAttributesKt {
44+
}
45+
4346
public final class aws/smithy/kotlin/runtime/auth/awssigning/AwsSigningConfig {
4447
public static final field Companion Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigningConfig$Companion;
4548
public fun <init> (Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigningConfig$Builder;)V
@@ -154,77 +157,9 @@ public final class aws/smithy/kotlin/runtime/auth/awssigning/HashSpecification$U
154157
public static final field INSTANCE Laws/smithy/kotlin/runtime/auth/awssigning/HashSpecification$UnsignedPayload;
155158
}
156159

157-
public final class aws/smithy/kotlin/runtime/auth/awssigning/PresignedRequestConfig {
158-
public synthetic fun <init> (Laws/smithy/kotlin/runtime/http/HttpMethod;Ljava/lang/String;Laws/smithy/kotlin/runtime/net/QueryParameters;JZLaws/smithy/kotlin/runtime/auth/awssigning/PresigningLocation;Laws/smithy/kotlin/runtime/http/Headers;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
159-
public synthetic fun <init> (Laws/smithy/kotlin/runtime/http/HttpMethod;Ljava/lang/String;Laws/smithy/kotlin/runtime/net/QueryParameters;JZLaws/smithy/kotlin/runtime/auth/awssigning/PresigningLocation;Laws/smithy/kotlin/runtime/http/Headers;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
160-
public final fun component1 ()Laws/smithy/kotlin/runtime/http/HttpMethod;
161-
public final fun component2 ()Ljava/lang/String;
162-
public final fun component3 ()Laws/smithy/kotlin/runtime/net/QueryParameters;
163-
public final fun component4-UwyO8pc ()J
164-
public final fun component5 ()Z
165-
public final fun component6 ()Laws/smithy/kotlin/runtime/auth/awssigning/PresigningLocation;
166-
public final fun component7 ()Laws/smithy/kotlin/runtime/http/Headers;
167-
public final fun copy-45ZY6uE (Laws/smithy/kotlin/runtime/http/HttpMethod;Ljava/lang/String;Laws/smithy/kotlin/runtime/net/QueryParameters;JZLaws/smithy/kotlin/runtime/auth/awssigning/PresigningLocation;Laws/smithy/kotlin/runtime/http/Headers;)Laws/smithy/kotlin/runtime/auth/awssigning/PresignedRequestConfig;
168-
public static synthetic fun copy-45ZY6uE$default (Laws/smithy/kotlin/runtime/auth/awssigning/PresignedRequestConfig;Laws/smithy/kotlin/runtime/http/HttpMethod;Ljava/lang/String;Laws/smithy/kotlin/runtime/net/QueryParameters;JZLaws/smithy/kotlin/runtime/auth/awssigning/PresigningLocation;Laws/smithy/kotlin/runtime/http/Headers;ILjava/lang/Object;)Laws/smithy/kotlin/runtime/auth/awssigning/PresignedRequestConfig;
169-
public fun equals (Ljava/lang/Object;)Z
170-
public final fun getAdditionalHeaders ()Laws/smithy/kotlin/runtime/http/Headers;
171-
public final fun getExpiresAfter-UwyO8pc ()J
172-
public final fun getMethod ()Laws/smithy/kotlin/runtime/http/HttpMethod;
173-
public final fun getPath ()Ljava/lang/String;
174-
public final fun getPresigningLocation ()Laws/smithy/kotlin/runtime/auth/awssigning/PresigningLocation;
175-
public final fun getQueryString ()Laws/smithy/kotlin/runtime/net/QueryParameters;
176-
public final fun getSignBody ()Z
177-
public fun hashCode ()I
178-
public fun toString ()Ljava/lang/String;
179-
}
180-
181160
public final class aws/smithy/kotlin/runtime/auth/awssigning/PresignerKt {
182161
}
183162

184-
public final class aws/smithy/kotlin/runtime/auth/awssigning/PresigningLocation : java/lang/Enum {
185-
public static final field HEADER Laws/smithy/kotlin/runtime/auth/awssigning/PresigningLocation;
186-
public static final field QUERY_STRING Laws/smithy/kotlin/runtime/auth/awssigning/PresigningLocation;
187-
public static fun valueOf (Ljava/lang/String;)Laws/smithy/kotlin/runtime/auth/awssigning/PresigningLocation;
188-
public static fun values ()[Laws/smithy/kotlin/runtime/auth/awssigning/PresigningLocation;
189-
}
190-
191-
public abstract interface class aws/smithy/kotlin/runtime/auth/awssigning/ServicePresignConfig {
192-
public abstract fun getCredentialsProvider ()Laws/smithy/kotlin/runtime/auth/awscredentials/CredentialsProvider;
193-
public abstract fun getEndpointProvider ()Lkotlin/jvm/functions/Function2;
194-
public abstract fun getNormalizeUriPath ()Z
195-
public abstract fun getRegion ()Ljava/lang/String;
196-
public abstract fun getServiceId ()Ljava/lang/String;
197-
public abstract fun getSigner ()Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigner;
198-
public abstract fun getSigningName ()Ljava/lang/String;
199-
public abstract fun getUseDoubleUriEncode ()Z
200-
}
201-
202-
public final class aws/smithy/kotlin/runtime/auth/awssigning/SigningContext {
203-
public fun <init> (Ljava/lang/String;Ljava/lang/String;)V
204-
public final fun component1 ()Ljava/lang/String;
205-
public final fun component2 ()Ljava/lang/String;
206-
public final fun copy (Ljava/lang/String;Ljava/lang/String;)Laws/smithy/kotlin/runtime/auth/awssigning/SigningContext;
207-
public static synthetic fun copy$default (Laws/smithy/kotlin/runtime/auth/awssigning/SigningContext;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Laws/smithy/kotlin/runtime/auth/awssigning/SigningContext;
208-
public fun equals (Ljava/lang/Object;)Z
209-
public final fun getRegion ()Ljava/lang/String;
210-
public final fun getService ()Ljava/lang/String;
211-
public fun hashCode ()I
212-
public fun toString ()Ljava/lang/String;
213-
}
214-
215-
public final class aws/smithy/kotlin/runtime/auth/awssigning/SigningContextualizedEndpoint {
216-
public fun <init> (Laws/smithy/kotlin/runtime/client/endpoints/Endpoint;Laws/smithy/kotlin/runtime/auth/awssigning/SigningContext;)V
217-
public final fun component1 ()Laws/smithy/kotlin/runtime/client/endpoints/Endpoint;
218-
public final fun component2 ()Laws/smithy/kotlin/runtime/auth/awssigning/SigningContext;
219-
public final fun copy (Laws/smithy/kotlin/runtime/client/endpoints/Endpoint;Laws/smithy/kotlin/runtime/auth/awssigning/SigningContext;)Laws/smithy/kotlin/runtime/auth/awssigning/SigningContextualizedEndpoint;
220-
public static synthetic fun copy$default (Laws/smithy/kotlin/runtime/auth/awssigning/SigningContextualizedEndpoint;Laws/smithy/kotlin/runtime/client/endpoints/Endpoint;Laws/smithy/kotlin/runtime/auth/awssigning/SigningContext;ILjava/lang/Object;)Laws/smithy/kotlin/runtime/auth/awssigning/SigningContextualizedEndpoint;
221-
public fun equals (Ljava/lang/Object;)Z
222-
public final fun getContext ()Laws/smithy/kotlin/runtime/auth/awssigning/SigningContext;
223-
public final fun getEndpoint ()Laws/smithy/kotlin/runtime/client/endpoints/Endpoint;
224-
public fun hashCode ()I
225-
public fun toString ()Ljava/lang/String;
226-
}
227-
228163
public final class aws/smithy/kotlin/runtime/auth/awssigning/internal/AwsChunkedUtilJVMKt {
229164
}
230165

runtime/auth/aws-signing-common/common/src/aws/smithy/kotlin/runtime/auth/awssigning/AwsSigningAttributes.kt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
*/
55
package aws.smithy.kotlin.runtime.auth.awssigning
66

7+
import aws.smithy.kotlin.runtime.InternalApi
78
import aws.smithy.kotlin.runtime.auth.awscredentials.CredentialsProvider
9+
import aws.smithy.kotlin.runtime.client.endpoints.SigningContext
10+
import aws.smithy.kotlin.runtime.operation.ExecutionContext
811
import aws.smithy.kotlin.runtime.time.Instant
912
import aws.smithy.kotlin.runtime.util.AttributeKey
1013
import kotlinx.coroutines.CompletableDeferred
@@ -64,3 +67,17 @@ public object AwsSigningAttributes {
6467
*/
6568
public val RequestSignature: AttributeKey<CompletableDeferred<ByteArray>> = AttributeKey("aws.smithy.kotlin#RequestSignature")
6669
}
70+
71+
/**
72+
* Merges this signing context into the given [ExecutionContext].
73+
* @param context The execution context into which to merge the values from this signing context.
74+
*/
75+
@InternalApi
76+
public fun SigningContext.SigV4.mergeInto(context: ExecutionContext) {
77+
context.setUnlessBlank(AwsSigningAttributes.SigningService, signingName)
78+
context.setUnlessBlank(AwsSigningAttributes.SigningRegion, signingRegion)
79+
}
80+
81+
private fun ExecutionContext.setUnlessBlank(key: AttributeKey<String>, value: String?) {
82+
if (!value.isNullOrBlank()) set(key, value)
83+
}

0 commit comments

Comments
 (0)