diff --git a/.changes/a9deee4f-8f15-472c-906f-492066275178.json b/.changes/a9deee4f-8f15-472c-906f-492066275178.json new file mode 100644 index 00000000000..9ee06c3053b --- /dev/null +++ b/.changes/a9deee4f-8f15-472c-906f-492066275178.json @@ -0,0 +1,8 @@ +{ + "id": "a9deee4f-8f15-472c-906f-492066275178", + "type": "bugfix", + "description": "Remove Route53 InvalidChangeBatch error response customization", + "issues": [ + "https://github.com/awslabs/aws-sdk-kotlin/issues/1433" + ] +} \ No newline at end of file diff --git a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/route53/ChangeResourceRecordSetsUnmarshallingIntegration.kt b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/route53/ChangeResourceRecordSetsUnmarshallingIntegration.kt deleted file mode 100644 index b2fccd7a54b..00000000000 --- a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/route53/ChangeResourceRecordSetsUnmarshallingIntegration.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.sdk.kotlin.codegen.customization.route53 - -import aws.sdk.kotlin.codegen.sdkId -import software.amazon.smithy.kotlin.codegen.KotlinSettings -import software.amazon.smithy.kotlin.codegen.aws.protocols.core.AwsHttpBindingProtocolGenerator -import software.amazon.smithy.kotlin.codegen.core.getContextValue -import software.amazon.smithy.kotlin.codegen.core.withBlock -import software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration -import software.amazon.smithy.kotlin.codegen.integration.SectionWriterBinding -import software.amazon.smithy.kotlin.codegen.model.expectShape -import software.amazon.smithy.model.Model -import software.amazon.smithy.model.shapes.ServiceShape -import software.amazon.smithy.model.shapes.ShapeId - -class ChangeResourceRecordSetsUnmarshallingIntegration : KotlinIntegration { - private val targetErrorShapeId = ShapeId.from("com.amazonaws.route53#InvalidChangeBatch") - - override val sectionWriters: List = listOf( - SectionWriterBinding(AwsHttpBindingProtocolGenerator.Sections.ProtocolErrorDeserialization) { writer, prevValue -> - val op = writer.getContextValue(AwsHttpBindingProtocolGenerator.Sections.RenderThrowOperationError.Operation) - - if (op.errors.any { it == targetErrorShapeId }) { - writer.withBlock("payload?.let {", "}") { - withBlock("aws.sdk.kotlin.services.route53.internal.parseRestXmlInvalidChangeBatchResponse(payload)?.let {", "}") { - write("setAseErrorMetadata(it.exception, wrappedResponse, it.errorDetails)") - write("throw it.exception") - } - } - writer.write("") - } else { - writer.write(prevValue) - } - }, - ) - - override fun enabledForService(model: Model, settings: KotlinSettings) = - model.expectShape(settings.service).sdkId.equals("route 53", ignoreCase = true) -} diff --git a/codegen/aws-sdk-codegen/src/main/resources/META-INF/services/software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration b/codegen/aws-sdk-codegen/src/main/resources/META-INF/services/software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration index fba8df4f45e..3ef264034df 100644 --- a/codegen/aws-sdk-codegen/src/main/resources/META-INF/services/software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration +++ b/codegen/aws-sdk-codegen/src/main/resources/META-INF/services/software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration @@ -33,7 +33,6 @@ aws.sdk.kotlin.codegen.customization.glacier.GlacierBodyChecksum aws.sdk.kotlin.codegen.customization.polly.PollyPresigner aws.sdk.kotlin.codegen.customization.machinelearning.MachineLearningEndpointCustomization aws.sdk.kotlin.codegen.customization.route53.TrimResourcePrefix -aws.sdk.kotlin.codegen.customization.route53.ChangeResourceRecordSetsUnmarshallingIntegration aws.sdk.kotlin.codegen.customization.ec2.EC2MakePrimitivesOptional aws.sdk.kotlin.codegen.customization.RemoveDefaults aws.sdk.kotlin.codegen.customization.s3.UnsupportedSigningAlgorithmIntegration diff --git a/codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/route53/ChangeResourceRecordSetsUnmarshallingIntegrationTest.kt b/codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/route53/ChangeResourceRecordSetsUnmarshallingIntegrationTest.kt deleted file mode 100644 index b46961e0695..00000000000 --- a/codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/route53/ChangeResourceRecordSetsUnmarshallingIntegrationTest.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.sdk.kotlin.codegen.customization.route53 - -import org.junit.jupiter.api.Test -import software.amazon.smithy.kotlin.codegen.test.defaultSettings -import software.amazon.smithy.kotlin.codegen.test.prependNamespaceAndService -import software.amazon.smithy.kotlin.codegen.test.toSmithyModel -import software.amazon.smithy.model.Model -import kotlin.test.assertFalse -import kotlin.test.assertTrue - -class ChangeResourceRecordSetsUnmarshallingIntegrationTest { - @Test - fun nonRoute53ModelIntegration() { - val model = sampleModel("not route 53") - val isEnabledForModel = ChangeResourceRecordSetsUnmarshallingIntegration().enabledForService(model, model.defaultSettings()) - assertFalse(isEnabledForModel) - } - - @Test - fun route53ModelIntegration() { - val model = sampleModel("route 53") - val isEnabledForModel = ChangeResourceRecordSetsUnmarshallingIntegration().enabledForService(model, model.defaultSettings()) - assertTrue(isEnabledForModel) - } -} - -private fun sampleModel(serviceName: String): Model = - """ - @http(method: "PUT", uri: "/foo") - operation Foo { } - - @http(method: "POST", uri: "/bar") - operation Bar { } - """ - .prependNamespaceAndService(operations = listOf("Foo", "Bar"), serviceName = serviceName) - .toSmithyModel() diff --git a/services/route53/common/src/aws/sdk/kotlin/services/route53/internal/ChangeResourceRecordSetsUnmarshalling.kt b/services/route53/common/src/aws/sdk/kotlin/services/route53/internal/ChangeResourceRecordSetsUnmarshalling.kt deleted file mode 100644 index e61e2a62021..00000000000 --- a/services/route53/common/src/aws/sdk/kotlin/services/route53/internal/ChangeResourceRecordSetsUnmarshalling.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.sdk.kotlin.services.route53.internal - -import aws.sdk.kotlin.services.route53.model.InvalidChangeBatch -import aws.smithy.kotlin.runtime.awsprotocol.ErrorDetails -import aws.smithy.kotlin.runtime.serde.xml.* - -internal fun parseRestXmlInvalidChangeBatchResponse(payload: ByteArray): InvalidChangeBatchErrorResponse? = - deserializeInvalidChangeBatchError(InvalidChangeBatch.Builder(), payload) - -internal fun deserializeInvalidChangeBatchError(builder: InvalidChangeBatch.Builder, payload: ByteArray): InvalidChangeBatchErrorResponse? { - val root = xmlTagReader(payload) - var requestId: String? = null - - loop@while (true) { - val curr = root.nextTag() ?: break@loop - when (curr.tagName) { - "Message", "message" -> builder.message = curr.data() - "Messages", "messages" -> builder.messages = deserializeMessages(curr) - "RequestId" -> requestId = curr.data() - } - curr.drop() - } - - return InvalidChangeBatchErrorResponse(ErrorDetails("InvalidChangeBatch", builder.message, requestId), builder.build()) -} - -private fun deserializeMessages(root: XmlTagReader): List { - val result = mutableListOf() - loop@while (true) { - val curr = root.nextTag() ?: break@loop - when (curr.tagName) { - "Message" -> { - val el = curr.tryData().getOrNull() ?: continue@loop - result.add(el) - } - } - } - - return result -} - -internal data class InvalidChangeBatchErrorResponse( - val errorDetails: ErrorDetails, - val exception: InvalidChangeBatch, -) diff --git a/services/route53/common/test/aws/sdk/kotlin/services/route53/internal/ChangeResourceRecordSetsUnmarshallingTest.kt b/services/route53/common/test/aws/sdk/kotlin/services/route53/internal/ChangeResourceRecordSetsUnmarshallingTest.kt deleted file mode 100644 index 3b4ecff446d..00000000000 --- a/services/route53/common/test/aws/sdk/kotlin/services/route53/internal/ChangeResourceRecordSetsUnmarshallingTest.kt +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.sdk.kotlin.services.route53.internal - -import aws.sdk.kotlin.services.route53.model.InvalidChangeBatch -import aws.sdk.kotlin.services.route53.serde.ChangeResourceRecordSetsOperationDeserializer -import aws.smithy.kotlin.runtime.http.Headers -import aws.smithy.kotlin.runtime.http.HttpBody -import aws.smithy.kotlin.runtime.http.HttpCall -import aws.smithy.kotlin.runtime.http.HttpStatusCode -import aws.smithy.kotlin.runtime.http.request.HttpRequestBuilder -import aws.smithy.kotlin.runtime.http.response.HttpResponse -import aws.smithy.kotlin.runtime.operation.ExecutionContext -import kotlinx.coroutines.runBlocking -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith - -class ChangeResourceRecordSetsUnmarshallingTest { - @Test - fun invalidChangeBatchMessage() { - val bodyText = """ - - - - InvalidChangeBatch message - - b25f48e8-84fd-11e6-80d9-574e0c4664cb - - """.trimIndent() - - val response = HttpResponse( - HttpStatusCode.BadRequest, - Headers.Empty, - HttpBody.fromBytes(bodyText.encodeToByteArray()), - ) - - val call = HttpCall(HttpRequestBuilder().build(), response) - - val exception = assertFailsWith { - runBlocking { - ChangeResourceRecordSetsOperationDeserializer().deserialize(ExecutionContext(), call, bodyText.encodeToByteArray()) - } - } - assertEquals(listOf("InvalidChangeBatch message"), exception.messages) - } - - @Test - fun invalidChangeBatchMessage2() { - val bodyText = """ - - - - InvalidChangeBatch message 1 - InvalidChangeBatch message 2 - - b25f48e8-84fd-11e6-80d9-574e0c4664cb - - """.trimIndent() - - val response: HttpResponse = HttpResponse( - HttpStatusCode.BadRequest, - Headers.Empty, - HttpBody.fromBytes(bodyText.encodeToByteArray()), - ) - - val call = HttpCall(HttpRequestBuilder().build(), response) - - val exception = assertFailsWith { - runBlocking { - ChangeResourceRecordSetsOperationDeserializer().deserialize(ExecutionContext(), call, bodyText.encodeToByteArray()) - } - } - assertEquals(listOf("InvalidChangeBatch message 1", "InvalidChangeBatch message 2"), exception.messages) - } - - @Test - fun invalidChangeBatchMessage3() { - val bodyText = """ - - - - InvalidChangeBatch message 1 - InvalidChangeBatch message 2 - - InvalidChangeBatch message 3 - b25f48e8-84fd-11e6-80d9-574e0c4664cb - - """.trimIndent() - - val response: HttpResponse = HttpResponse( - HttpStatusCode.BadRequest, - Headers.Empty, - HttpBody.fromBytes(bodyText.encodeToByteArray()), - ) - - val call = HttpCall(HttpRequestBuilder().build(), response) - - val exception = assertFailsWith { - runBlocking { - ChangeResourceRecordSetsOperationDeserializer().deserialize(ExecutionContext(), call, bodyText.encodeToByteArray()) - } - } - assertEquals(listOf("InvalidChangeBatch message 1", "InvalidChangeBatch message 2"), exception.messages) - assertEquals("InvalidChangeBatch message 3", exception.message) - } -} diff --git a/services/route53/e2eTest/src/InvalidChangeBatchTest.kt b/services/route53/e2eTest/src/InvalidChangeBatchTest.kt new file mode 100644 index 00000000000..cf5e50a1fa7 --- /dev/null +++ b/services/route53/e2eTest/src/InvalidChangeBatchTest.kt @@ -0,0 +1,74 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package aws.sdk.kotlin.services.route53 + +import aws.sdk.kotlin.services.route53.model.* +import aws.smithy.kotlin.runtime.util.Uuid +import kotlinx.coroutines.test.runTest +import kotlin.test.Test +import kotlin.test.assertFailsWith +import kotlin.test.assertNotNull + +// https://github.com/awslabs/aws-sdk-kotlin/issues/1433 +class InvalidChangeBatchTest { + @Test + fun testMessageIsPopulated() = runTest { + Route53Client { + region = "us-east-1" + }.use { client -> + val createHostedZoneResp = client.createHostedZone { + this.callerReference = Uuid.random().toString() + this.name = "this-is-a-test-hosted-zone-for-aws-sdk-kotlin.com" + } + + val hostedZoneId = checkNotNull(createHostedZoneResp.hostedZone?.id) { "Hosted zone is unexpectedly null" } + + try { + val exception = assertFailsWith { + client.changeResourceRecordSets { + this.hostedZoneId = hostedZoneId + this.changeBatch = ChangeBatch { + this.changes = listOf( + Change { + this.action = ChangeAction.Delete + this.resourceRecordSet = ResourceRecordSet { + this.name = "test.blerg.com" + this.type = RrType.Cname + this.ttl = 300 + this.resourceRecords = listOf( + ResourceRecord { + value = "test.blerg.com" + }, + ) + } + }, + Change { + this.action = ChangeAction.Create + this.resourceRecordSet = ResourceRecordSet { + this.name = "test.blerg.com" + this.type = RrType.Cname + this.ttl = 300 + this.resourceRecords = listOf( + ResourceRecord { + value = "test.blerg.com" + }, + ) + } + }, + ) + this.comment = "testing..." + } + } + } + + assertNotNull(exception.message) + } finally { + client.deleteHostedZone { + id = hostedZoneId + } + } + } + } +}