diff --git a/.changes/next-release/bugfix-AWSSDKforJavav2-ca1c44c.json b/.changes/next-release/bugfix-AWSSDKforJavav2-ca1c44c.json new file mode 100644 index 000000000000..10d7d5125e37 --- /dev/null +++ b/.changes/next-release/bugfix-AWSSDKforJavav2-ca1c44c.json @@ -0,0 +1,6 @@ +{ + "type": "bugfix", + "category": "AWS SDK for Java v2", + "contributor": "kstich", + "description": "Fix Smithy RPC v2 CBOR URI resolution allowing custom URIs." +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7258cd01cfe2..f09e8c72405f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,7 +11,7 @@ __Jump To:__ * [Additional Resources](#additional-resources) ## Bug Reports -Bug reports are accepted through the [this][bug-report] page. +Bug reports are accepted through [this][bug-report] page. The following labels are used to track bug related issues: [Bug][label-bug], [Documentation Issue][label-doc-issue]. @@ -38,7 +38,7 @@ please ensure that your bug report has the following: * A short, descriptive title. Ideally, other community members should be able to get a good idea of the issue just from reading the title. -* A succint, detailed description of the problem you're experiencing. This +* A succinct, detailed description of the problem you're experiencing. This should include: * Expected behavior of the SDK and the actual behavior exhibited. * Any details of your application environment that may be relevant. At @@ -51,7 +51,7 @@ please ensure that your bug report has the following: stacktraces. ## Feature Requests -Feature requests are submitted through the [this][feature-request] page. +Feature requests are submitted through [this][feature-request] page. As with Bug Reports, please do a search of the open requests first before submitting a new one to avoid duplicates. If you find an existing one, give it @@ -71,7 +71,7 @@ Open an [issue][issues] with the following: * A short, descriptive title. Ideally, other community members should be able to get a good idea of the feature just from reading the title. -* A detailed description of the the proposed feature. Include justification for +* A detailed description of the proposed feature. Include justification for why it should be added to the SDK, and possibly example code to illustrate how it should work. * [Markdown][markdown] formatting as appropriate to make the request easier to @@ -136,11 +136,11 @@ interfaces](https://github.com/reactive-streams/reactive-streams-jvm), the change must also contain verification tests using the [Reactive Streams Technology Compatibility Kit](https://github.com/reactive-streams/reactive-streams-jvm/tree/master/tck) -to ensure specificiation compliance. +to ensure specification compliance. ### Getting Your Pull Request Merged All Pull Requests must be approved by at least one member of the SDK team -before it can be merged in. The members only have limited bandwitdth to review +before it can be merged in. The members only have limited bandwidth to review Pull Requests so it's not unusual for a Pull Request to go unreviewed for a few days, especially if it's a large or complex one. If, after a week, your Pull Request has not had any engagement from the SDK team, feel free to ping a diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/SmithyRpcV2CborProtocolProcessor.java b/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/SmithyRpcV2CborProtocolProcessor.java index d4921a6d4822..7db556fa63ed 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/SmithyRpcV2CborProtocolProcessor.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/SmithyRpcV2CborProtocolProcessor.java @@ -20,13 +20,11 @@ import software.amazon.awssdk.codegen.model.service.Http; import software.amazon.awssdk.codegen.model.service.Operation; import software.amazon.awssdk.codegen.model.service.ServiceModel; -import software.amazon.awssdk.utils.StringUtils; /** * This processor only runs for services using the smithy-rpc-v2-cbor protocol. * - * Adds a request URI that conform to the Smithy RPCv2 protocol to each operation in the model, if there's no URI already - * defined. + * Sets a request URI that conforms to the Smithy RPC v2 protocol to each operation in the model. */ public class SmithyRpcV2CborProtocolProcessor implements CodegenCustomizationProcessor { @Override @@ -38,13 +36,11 @@ public void preprocess(ServiceModel serviceModel) { } private void setRequestUri(ServiceModel service, String name, Operation op) { - Http http = op.getHttp(); - String requestUri = http.getRequestUri(); - if (StringUtils.isNotBlank(requestUri) && !"/".equals(requestUri)) { - return; - } String uri = String.format("/service/%s/operation/%s", service.getMetadata().getTargetPrefix(), op.getName()); - op.getHttp().setRequestUri(uri); + if (op.getHttp() == null) { + op.setHttp(new Http().withMethod("POST").withResponseCode("200")); + } + op.getHttp().withRequestUri(uri); } @Override diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/model/service/Http.java b/codegen/src/main/java/software/amazon/awssdk/codegen/model/service/Http.java index 521d51373574..f540249e472f 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/model/service/Http.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/model/service/Http.java @@ -56,4 +56,9 @@ public String getResponseCode() { public void setResponseCode(String responseCode) { this.responseCode = responseCode; } + + public Http withResponseCode(String responseCode) { + this.responseCode = responseCode; + return this; + } } diff --git a/codegen/src/test/java/software/amazon/awssdk/codegen/customization/processors/SmithyRpcV2CborProtocolProcessorTest.java b/codegen/src/test/java/software/amazon/awssdk/codegen/customization/processors/SmithyRpcV2CborProtocolProcessorTest.java new file mode 100644 index 000000000000..ee932b3b874f --- /dev/null +++ b/codegen/src/test/java/software/amazon/awssdk/codegen/customization/processors/SmithyRpcV2CborProtocolProcessorTest.java @@ -0,0 +1,63 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (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/apache2.0 + * + * 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 software.amazon.awssdk.codegen.customization.processors; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import java.io.File; +import java.io.IOException; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.codegen.C2jModels; +import software.amazon.awssdk.codegen.IntermediateModelBuilder; +import software.amazon.awssdk.codegen.model.config.customization.CustomizationConfig; +import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel; +import software.amazon.awssdk.codegen.model.service.ServiceModel; +import software.amazon.awssdk.codegen.utils.ModelLoaderUtils; + +public class SmithyRpcV2CborProtocolProcessorTest { + + private static CustomizationConfig config; + private static ServiceModel serviceModel; + + @BeforeAll + public static void setUp() throws IOException { + File serviceModelFile = new File(SmithyRpcV2CborProtocolProcessorTest.class.getResource("rpcv2-service-2.json").getFile()); + serviceModel = ModelLoaderUtils.loadModel(ServiceModel.class, serviceModelFile); + File customizationConfigFile = new File(SmithyRpcV2CborProtocolProcessorTest.class.getResource("customization.config").getFile()); + serviceModel = ModelLoaderUtils.loadModel(ServiceModel.class, serviceModelFile); + config = ModelLoaderUtils.loadModel(CustomizationConfig.class, customizationConfigFile); + } + + @Test + public void specificRpcV2Uri_isSetInTheModel() { + assertThat(serviceModel.getOperation("Slash").getHttp().getRequestUri()).isEqualTo("/"); + assertThat(serviceModel.getOperation("Custom").getHttp().getRequestUri()).isEqualTo("/Foo"); + assertThat(serviceModel.getOperation("None").getHttp()).isNull(); + IntermediateModel intermediateModel = new IntermediateModelBuilder(C2jModels.builder() + .serviceModel(serviceModel) + .customizationConfig(config) + .build()) + .build(); + + assertThat(serviceModel.getOperation("Slash").getHttp().getRequestUri()) + .isEqualTo("/service/RpcV2Protocol/operation/Slash"); + assertThat(serviceModel.getOperation("Custom").getHttp().getRequestUri()) + .isEqualTo("/service/RpcV2Protocol/operation/Custom"); + assertThat(serviceModel.getOperation("None").getHttp().getRequestUri()) + .isEqualTo("/service/RpcV2Protocol/operation/None"); + } +} diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/customization/processors/rpcv2-service-2.json b/codegen/src/test/resources/software/amazon/awssdk/codegen/customization/processors/rpcv2-service-2.json new file mode 100644 index 000000000000..252c1d0e1a63 --- /dev/null +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/customization/processors/rpcv2-service-2.json @@ -0,0 +1,77 @@ +{ + "version":"2.0", + "metadata":{ + "apiVersion":"2023-03-10", + "auth":["aws.auth#sigv4"], + "endpointPrefix":"smithyrpcv2protocol", + "protocol":"smithy-rpc-v2-cbor", + "protocols":["smithy-rpc-v2-cbor"], + "serviceFullName":"RpcV2 Protocol Service", + "serviceId":"SmithyRpcV2Protocol", + "signatureVersion":"v4", + "signingName":"execute-api", + "targetPrefix":"RpcV2Protocol", + "uid":"smithy-rpcv2protocol-2023-03-10" + }, + "operations":{ + "Slash":{ + "name":"Slash", + "http":{ + "method":"POST", + "requestUri":"/" + }, + "input":{"shape":"AllTypesStructure"} + }, + "Custom":{ + "name":"Custom", + "http":{ + "method":"POST", + "requestUri":"/Foo" + }, + "output":{"shape":"AllTypesStructure"} + }, + "None":{ + "name":"None", + "output":{"shape":"AllTypesStructure"} + } + }, + "shapes": { + "AllTypesStructure": { + "type": "structure", + "members": { + "TimeStampMember": { + "shape": "Timestamp" + }, + "ListOfTimestamps": { + "shape": "ListOfTimestamps" + }, + "Timestamp": { + "shape": "Timestamp" + }, + "StructWithTimestamp": { + "shape": "StructWithTimestamp" + } + } + }, + "ListOfTimestamps": { + "type": "list", + "member": { + "shape": "Timestamp" + } + }, + "StructWithTimestamp": { + "type": "structure", + "members": { + "Timestamp": { + "shape": "Timestamp" + } + } + }, + "Timestamp": { + "type": "string" + }, + "String" : { + "type" : "string" + } + } +} diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/rpcv2/service-2.json b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/rpcv2/service-2.json index 0cc5eeb51db6..7120326e77ec 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/rpcv2/service-2.json +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/rpcv2/service-2.json @@ -16,35 +16,19 @@ "operations":{ "EmptyInputOutput":{ "name":"EmptyInputOutput", - "http":{ - "method":"POST", - "requestUri":"/" - }, "input":{"shape":"EmptyStructure"}, "output":{"shape":"EmptyStructure"} }, "Float16":{ "name":"Float16", - "http":{ - "method":"POST", - "requestUri":"/" - }, "output":{"shape":"Float16Output"} }, "FractionalSeconds":{ "name":"FractionalSeconds", - "http":{ - "method":"POST", - "requestUri":"/" - }, "output":{"shape":"FractionalSecondsOutput"} }, "GreetingWithErrors":{ "name":"GreetingWithErrors", - "http":{ - "method":"POST", - "requestUri":"/" - }, "output":{"shape":"GreetingWithErrorsOutput"}, "errors":[ {"shape":"ComplexError"}, @@ -53,18 +37,10 @@ "idempotent":true }, "NoInputOutput":{ - "name":"NoInputOutput", - "http":{ - "method":"POST", - "requestUri":"/" - } + "name":"NoInputOutput" }, "OperationWithDefaults":{ "name":"OperationWithDefaults", - "http":{ - "method":"POST", - "requestUri":"/" - }, "input":{"shape":"OperationWithDefaultsInput"}, "output":{"shape":"OperationWithDefaultsOutput"}, "errors":[ @@ -73,28 +49,16 @@ }, "OptionalInputOutput":{ "name":"OptionalInputOutput", - "http":{ - "method":"POST", - "requestUri":"/" - }, "input":{"shape":"SimpleStructure"}, "output":{"shape":"SimpleStructure"} }, "RecursiveShapes":{ "name":"RecursiveShapes", - "http":{ - "method":"POST", - "requestUri":"/" - }, "input":{"shape":"RecursiveShapesInputOutput"}, "output":{"shape":"RecursiveShapesInputOutput"} }, "RpcV2CborDenseMaps":{ "name":"RpcV2CborDenseMaps", - "http":{ - "method":"POST", - "requestUri":"/" - }, "input":{"shape":"RpcV2CborDenseMapsInputOutput"}, "output":{"shape":"RpcV2CborDenseMapsInputOutput"}, "errors":[ @@ -103,10 +67,6 @@ }, "RpcV2CborLists":{ "name":"RpcV2CborLists", - "http":{ - "method":"POST", - "requestUri":"/" - }, "input":{"shape":"RpcV2CborListInputOutput"}, "output":{"shape":"RpcV2CborListInputOutput"}, "errors":[ @@ -116,10 +76,6 @@ }, "RpcV2CborSparseMaps":{ "name":"RpcV2CborSparseMaps", - "http":{ - "method":"POST", - "requestUri":"/" - }, "input":{"shape":"RpcV2CborSparseMapsInputOutput"}, "output":{"shape":"RpcV2CborSparseMapsInputOutput"}, "errors":[ @@ -128,19 +84,11 @@ }, "SimpleScalarProperties":{ "name":"SimpleScalarProperties", - "http":{ - "method":"POST", - "requestUri":"/" - }, "input":{"shape":"SimpleScalarStructure"}, "output":{"shape":"SimpleScalarStructure"} }, "SparseNullsOperation":{ "name":"SparseNullsOperation", - "http":{ - "method":"POST", - "requestUri":"/" - }, "input":{"shape":"SparseNullsOperationInputOutput"}, "output":{"shape":"SparseNullsOperationInputOutput"} }