diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/AddOperations.java b/codegen/src/main/java/software/amazon/awssdk/codegen/AddOperations.java index 33cc1001902c..3405af686886 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/AddOperations.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/AddOperations.java @@ -155,6 +155,7 @@ public Map constructOperations() { operationModel.setOperationName(operationName); operationModel.setDeprecated(op.isDeprecated()); + operationModel.setDeprecatedMessage(op.getDeprecatedMessage()); operationModel.setDocumentation(op.getDocumentation()); operationModel.setIsAuthenticated(isAuthenticated(op)); operationModel.setAuthType(op.getAuthtype()); diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/model/intermediate/OperationModel.java b/codegen/src/main/java/software/amazon/awssdk/codegen/model/intermediate/OperationModel.java index eb0532056712..38a3b986c6ac 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/model/intermediate/OperationModel.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/model/intermediate/OperationModel.java @@ -32,6 +32,8 @@ public class OperationModel extends DocumentationModel { private boolean deprecated; + private String deprecatedMessage; + private VariableModel input; private ReturnTypeModel returnType; @@ -84,6 +86,14 @@ public void setDeprecated(boolean deprecated) { this.deprecated = deprecated; } + public String getDeprecatedMessage() { + return deprecatedMessage; + } + + public void setDeprecatedMessage(String deprecatedMessage) { + this.deprecatedMessage = deprecatedMessage; + } + public String getDocs(IntermediateModel model, ClientType clientType) { return OperationDocs.getDocs(model, this, clientType); diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/model/service/Operation.java b/codegen/src/main/java/software/amazon/awssdk/codegen/model/service/Operation.java index d60eb076d2fb..8b752afbca44 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/model/service/Operation.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/model/service/Operation.java @@ -24,6 +24,8 @@ public class Operation { private boolean deprecated; + private String deprecatedMessage; + private Http http; private Input input; @@ -67,6 +69,14 @@ public void setDeprecated(boolean deprecated) { this.deprecated = deprecated; } + public String getDeprecatedMessage() { + return deprecatedMessage; + } + + public void setDeprecatedMessage(String deprecatedMessage) { + this.deprecatedMessage = deprecatedMessage; + } + public Http getHttp() { return http; } diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientInterface.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientInterface.java index 5af632e20ed3..9ea7ec4297fa 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientInterface.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientInterface.java @@ -46,6 +46,7 @@ import software.amazon.awssdk.codegen.poet.PoetExtensions; import software.amazon.awssdk.codegen.poet.PoetUtils; import software.amazon.awssdk.codegen.poet.eventstream.EventStreamUtils; +import software.amazon.awssdk.codegen.poet.model.DeprecationUtils; import software.amazon.awssdk.codegen.utils.PaginatorUtils; import software.amazon.awssdk.core.SdkClient; import software.amazon.awssdk.core.async.AsyncRequestBody; @@ -179,7 +180,9 @@ private Stream operationsAndSimpleMethods(OperationModel operationMo methods.addAll(traditionalMethods(operationModel)); methods.addAll(overloadMethods(operationModel)); methods.addAll(paginatedMethods(operationModel)); - return methods.stream(); + return methods.stream() + // Add Deprecated annotation if needed to all overloads + .map(m -> DeprecationUtils.checkDeprecated(operationModel, m)); } private List paginatedMethods(OperationModel opModel) { @@ -406,7 +409,7 @@ private MethodSpec.Builder methodSignatureWithReturnType(OperationModel opModel) */ private MethodSpec.Builder interfaceMethodSignature(OperationModel opModel) { return methodSignatureWithReturnType(opModel) - .addModifiers(Modifier.PUBLIC, Modifier.DEFAULT); + .addModifiers(Modifier.PUBLIC, Modifier.DEFAULT); } /** diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/ClientClassUtils.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/ClientClassUtils.java index 2743aafbcbdb..f8fc455deb1b 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/ClientClassUtils.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/ClientClassUtils.java @@ -64,6 +64,7 @@ static MethodSpec consumerBuilderVariant(MethodSpec spec, String javadoc) { MethodSpec.Builder result = MethodSpec.methodBuilder(spec.name) .returns(spec.returnType) .addExceptions(spec.exceptions) + .addAnnotations(spec.annotations) .addJavadoc(javadoc) .addModifiers(Modifier.PUBLIC, Modifier.DEFAULT) .addTypeVariables(spec.typeVariables) diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientInterface.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientInterface.java index 1fe0d9227ee0..add504f3e6d7 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientInterface.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientInterface.java @@ -48,6 +48,7 @@ import software.amazon.awssdk.codegen.poet.ClassSpec; import software.amazon.awssdk.codegen.poet.PoetExtensions; import software.amazon.awssdk.codegen.poet.PoetUtils; +import software.amazon.awssdk.codegen.poet.model.DeprecationUtils; import software.amazon.awssdk.codegen.utils.PaginatorUtils; import software.amazon.awssdk.core.ResponseBytes; import software.amazon.awssdk.core.ResponseInputStream; @@ -176,7 +177,10 @@ private List operationMethodSpec(OperationModel opModel) { methods.addAll(streamingSimpleMethods(opModel)); methods.addAll(paginatedMethods(opModel)); - return methods; + return methods.stream() + // Add Deprecated annotation if needed to all overloads + .map(m -> DeprecationUtils.checkDeprecated(opModel, m)) + .collect(toList()); } private MethodSpec simpleMethod(OperationModel opModel) { diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/DeprecationUtils.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/DeprecationUtils.java index aee1c7177011..8d3e6ec8fc9c 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/DeprecationUtils.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/DeprecationUtils.java @@ -22,6 +22,7 @@ import com.squareup.javapoet.MethodSpec; import java.util.List; import software.amazon.awssdk.codegen.model.intermediate.MemberModel; +import software.amazon.awssdk.codegen.model.intermediate.OperationModel; import software.amazon.awssdk.utils.StringUtils; public final class DeprecationUtils { @@ -49,6 +50,24 @@ public static MethodSpec checkDeprecated(MemberModel member, MethodSpec method) return builder.build(); } + /** + * If a given operation is modeled as deprecated, add the {@link Deprecated} annotation to the method and, if the method + * already has existing Javadoc, append a section with the {@code @deprecated} tag. + */ + public static MethodSpec checkDeprecated(OperationModel operation, MethodSpec method) { + if (!operation.isDeprecated() || method.annotations.contains(DEPRECATED)) { + return method; + } + MethodSpec.Builder builder = method.toBuilder().addAnnotation(DEPRECATED); + if (!method.javadoc.isEmpty()) { + builder.addJavadoc(LF + "@deprecated"); + if (StringUtils.isNotBlank(operation.getDeprecatedMessage())) { + builder.addJavadoc(" $L", operation.getDeprecatedMessage()); + } + } + return builder.build(); + } + public static List checkDeprecated(MemberModel member, List methods) { return methods.stream().map(methodSpec -> checkDeprecated(member, methodSpec)).collect(toList()); } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/rest-json/service-2.json b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/rest-json/service-2.json index 3b4cb21eb7ed..5565b37f6d61 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/rest-json/service-2.json +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/rest-json/service-2.json @@ -39,6 +39,8 @@ "shape": "InvalidInputException" } ], + "deprecated": true, + "deprecatedMessage": "This API is deprecated, use something else", "documentation": "

Performs a post operation to the query service and has no output

" }, "GetWithoutRequiredMembers": { diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-interface.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-interface.java index d6415e45bb92..a360a92bbd02 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-interface.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-interface.java @@ -95,7 +95,10 @@ static JsonAsyncClientBuilder builder() { * @sample JsonAsyncClient.APostOperation * @see AWS * API Documentation + * + * @deprecated This API is deprecated, use something else */ + @Deprecated default CompletableFuture aPostOperation(APostOperationRequest aPostOperationRequest) { throw new UnsupportedOperationException(); } @@ -128,7 +131,10 @@ default CompletableFuture aPostOperation(APostOperationR * @sample JsonAsyncClient.APostOperation * @see AWS * API Documentation + * + * @deprecated This API is deprecated, use something else */ + @Deprecated default CompletableFuture aPostOperation(Consumer aPostOperationRequest) { return aPostOperation(APostOperationRequest.builder().applyMutation(aPostOperationRequest).build()); } @@ -1449,4 +1455,4 @@ default CompletableFuture streamingOutputOpera default JsonUtilities utilities() { throw new UnsupportedOperationException(); } -} +} \ No newline at end of file diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-client-interface.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-client-interface.java index 5ef3672183ac..399fcf2e238a 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-client-interface.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-client-interface.java @@ -88,7 +88,10 @@ static JsonClientBuilder builder() { * @sample JsonClient.APostOperation * @see AWS * API Documentation + * + * @deprecated This API is deprecated, use something else */ + @Deprecated default APostOperationResponse aPostOperation(APostOperationRequest aPostOperationRequest) throws InvalidInputException, AwsServiceException, SdkClientException, JsonException { throw new UnsupportedOperationException(); @@ -119,7 +122,10 @@ default APostOperationResponse aPostOperation(APostOperationRequest aPostOperati * @sample JsonClient.APostOperation * @see AWS * API Documentation + * + * @deprecated This API is deprecated, use something else */ + @Deprecated default APostOperationResponse aPostOperation(Consumer aPostOperationRequest) throws InvalidInputException, AwsServiceException, SdkClientException, JsonException { return aPostOperation(APostOperationRequest.builder().applyMutation(aPostOperationRequest).build()); @@ -1377,4 +1383,4 @@ static ServiceMetadata serviceMetadata() { default JsonUtilities utilities() { throw new UnsupportedOperationException(); } -} +} \ No newline at end of file