diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/AddMetadata.java b/codegen/src/main/java/software/amazon/awssdk/codegen/AddMetadata.java index 3dbb1f02aa8c..435a2b99fc35 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/AddMetadata.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/AddMetadata.java @@ -58,6 +58,7 @@ public static Metadata constructMetadata(ServiceModel serviceModel, .withRequestTransformPackageName(namingStrategy.getRequestTransformPackageName(serviceName)) .withPaginatorsPackageName(namingStrategy.getPaginatorsPackageName(serviceName)) .withWaitersPackageName(namingStrategy.getWaitersPackageName(serviceName)) + .withBatchmanagerPackageName(namingStrategy.getBatchManagerPackageName(serviceName)) .withServiceAbbreviation(serviceMetadata.getServiceAbbreviation()) .withServiceFullName(serviceMetadata.getServiceFullName()) .withServiceName(serviceName) diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/emitters/GeneratorPathProvider.java b/codegen/src/main/java/software/amazon/awssdk/codegen/emitters/GeneratorPathProvider.java index 3f6ef72d037f..cac81c4ac6cc 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/emitters/GeneratorPathProvider.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/emitters/GeneratorPathProvider.java @@ -68,4 +68,12 @@ public String getWaitersDirectory() { public String getWaitersInternalDirectory() { return sourceDirectory + "/" + Utils.packageToDirectory(model.getMetadata().getFullWaitersInternalPackageName()); } + + public String getBatchManagerDirectory() { + return sourceDirectory + "/" + Utils.packageToDirectory(model.getMetadata().getFullBatchManagerPackageName()); + } + + public String getBatchManagerInternalDirectory() { + return sourceDirectory + "/" + Utils.packageToDirectory(model.getMetadata().getFullBatchManagerInternalPackageName()); + } } diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/emitters/tasks/AwsGeneratorTasks.java b/codegen/src/main/java/software/amazon/awssdk/codegen/emitters/tasks/AwsGeneratorTasks.java index 9866806d8c8f..6513c6dd3d19 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/emitters/tasks/AwsGeneratorTasks.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/emitters/tasks/AwsGeneratorTasks.java @@ -26,6 +26,7 @@ public AwsGeneratorTasks(GeneratorTaskParams params) { new AsyncClientGeneratorTasks(params), new PaginatorsGeneratorTasks(params), new EventStreamGeneratorTasks(params), - new WaitersGeneratorTasks(params)); + new WaitersGeneratorTasks(params), + new BatchManagerGeneratorTasks(params)); } } diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/emitters/tasks/BatchManagerGeneratorTasks.java b/codegen/src/main/java/software/amazon/awssdk/codegen/emitters/tasks/BatchManagerGeneratorTasks.java new file mode 100644 index 000000000000..926958428d38 --- /dev/null +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/emitters/tasks/BatchManagerGeneratorTasks.java @@ -0,0 +1,55 @@ +/* + * 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.emitters.tasks; + +import java.util.ArrayList; +import java.util.List; +import software.amazon.awssdk.annotations.SdkInternalApi; +import software.amazon.awssdk.codegen.emitters.GeneratorTask; +import software.amazon.awssdk.codegen.emitters.GeneratorTaskParams; +import software.amazon.awssdk.codegen.emitters.PoetGeneratorTask; +import software.amazon.awssdk.codegen.poet.batchmanager.BatchFunctionsClassSpec; + +@SdkInternalApi +public class BatchManagerGeneratorTasks extends BaseGeneratorTasks { + private final GeneratorTaskParams generatorTaskParams; + + public BatchManagerGeneratorTasks(GeneratorTaskParams dependencies) { + super(dependencies); + this.generatorTaskParams = dependencies; + } + + @Override + protected boolean hasTasks() { + return model.getCustomizationConfig().getBatchManagerMethods() != null; + } + + @Override + protected List createTasks() { + List generatorTasks = new ArrayList<>(); + generatorTasks.add(createBatchFunctions()); + return generatorTasks; + } + + private GeneratorTask createBatchFunctions() { + return new PoetGeneratorTask(batchManagerInternalClassDir(), model.getFileHeader(), + new BatchFunctionsClassSpec(model)); + } + + private String batchManagerInternalClassDir() { + return generatorTaskParams.getPathProvider().getBatchManagerInternalDirectory(); + } +} diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/internal/Constant.java b/codegen/src/main/java/software/amazon/awssdk/codegen/internal/Constant.java index 2a57bb3b51b4..d55eb44cd3e9 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/internal/Constant.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/internal/Constant.java @@ -72,6 +72,8 @@ public final class Constant { public static final String PACKAGE_NAME_CUSTOM_AUTH_PATTERN = "%s.auth"; + public static final String PACKAGE_NAME_BATCHMANAGER_PATTERN = "%s.batchmanager"; + public static final String AUTH_POLICY_ENUM_CLASS_DIR = "software/amazon/awssdk/auth/policy/actions"; public static final String REQUEST_CLASS_SUFFIX = "Request"; diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/BatchManager.java b/codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/BatchManager.java new file mode 100644 index 000000000000..080110170d84 --- /dev/null +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/BatchManager.java @@ -0,0 +1,165 @@ +/* + * 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.model.config.customization; + +/** + * Config to define a batchable method. The key is a method that has a batch counterpart + * + * ex. For SQS, we can use a key of: sendMessage, meanwhile the batchFunctionsTypes will store the types + * SendMessageRequest, SendMessageResponse, and SendMessageBatchResponse. + */ +public class BatchManager { + + /** + * The batch equivalent of the request method. This is required. + * + * Ex. if the request method is sendMessage, batchMethod is sendMessageBatch + */ + private String batchMethod; + + /** Type of a single entry that is contained within a batch request. This is required. */ + private String batchRequestEntry; + + /** + * Type of a successful batch response entry. If a successful and failed batch response entry are the same, + * successfulBatchEntry indicates the type of that entry. This is required. + * + * Ex. SendMessageBatchResultEntry for SQS, PutRecordsResultEntry for kinesis + */ + private String successBatchEntry; + + /** Type of a failed batch response entry. This is optional (depending on service). */ + private String errorBatchEntry; + + /** + * Name of the method used to extract the successful responses from a batch response. If the method to extract successful + * and failed entries are the same, successEntriesMethod indicates the name of that method. This is required. + * + * Ex. successful for SQS, records for kinesis, responses for dynamodb etc. + */ + private String successEntriesMethod; + + /** Name of the method used to extract failed responses from a batch responses. This is optional (depending on service). */ + private String errorEntriesMethod; + + /** + * Name of the method used to get/set the destination for a request. This is required. + * + * Ex. queueUrl for SQS, streamName for Kinesis + */ + private String batchKey; + + /** + * Name of the method used to extract the status code from a failed batch entry. + * + * Ex. code for SQS, errorCode for Kinesis. + */ + private String errorCodeMethod; + + /** + * Name of the method used to extract the status code from a failed batch entry. + * + * Ex. code for SQS, errorCode for Kinesis. + */ + private String errorMessageMethod; + + /** + * Name of the method used to set or extract the request identifier used to identify entries within a batch request. + * + * Ex. id for SQS + */ + private String batchRequestIdentifier; + + public String getBatchMethod() { + return batchMethod; + } + + public void setBatchMethod(String batchMethod) { + this.batchMethod = batchMethod; + } + + public String getBatchRequestEntry() { + return batchRequestEntry; + } + + public void setBatchRequestEntry(String batchRequestEntry) { + this.batchRequestEntry = batchRequestEntry; + } + + public String getSuccessBatchEntry() { + return successBatchEntry; + } + + public void setSuccessBatchEntry(String successBatchEntry) { + this.successBatchEntry = successBatchEntry; + } + + public String getErrorBatchEntry() { + return errorBatchEntry; + } + + public void setErrorBatchEntry(String errorBatchEntry) { + this.errorBatchEntry = errorBatchEntry; + } + + public String getSuccessEntriesMethod() { + return successEntriesMethod; + } + + public void setSuccessEntriesMethod(String successEntriesMethod) { + this.successEntriesMethod = successEntriesMethod; + } + + public String getErrorEntriesMethod() { + return errorEntriesMethod; + } + + public void setErrorEntriesMethod(String errorEntriesMethod) { + this.errorEntriesMethod = errorEntriesMethod; + } + + public String getBatchKey() { + return batchKey; + } + + public void setBatchKey(String batchKey) { + this.batchKey = batchKey; + } + + public String getErrorCodeMethod() { + return errorCodeMethod; + } + + public void setErrorCodeMethod(String errorCodeMethod) { + this.errorCodeMethod = errorCodeMethod; + } + + public String getErrorMessageMethod() { + return errorMessageMethod; + } + + public void setErrorMessageMethod(String errorMessageMethod) { + this.errorMessageMethod = errorMessageMethod; + } + + public String getBatchRequestIdentifier() { + return batchRequestIdentifier; + } + + public void setBatchRequestIdentifier(String requestIdentifier) { + this.batchRequestIdentifier = requestIdentifier; + } +} diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/BatchManagerMethod.java b/codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/BatchManagerMethod.java deleted file mode 100644 index bb46bf1f3ffb..000000000000 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/BatchManagerMethod.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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.model.config.customization; - -/** - * Config required to generate a batchManager method that returns an instance of a BatchManager in addition to any required - * executors or scheduledExecutors. - */ -public class BatchManagerMethod { - - public static final String METHOD_NAME = "batchManager"; - - /** Fqcn of the return type of the operation for the sync client */ - private String returnType; - - /** Fqcn of the return type of the operation for the async client */ - private String asyncReturnType; - - public String getReturnType() { - return returnType; - } - - public void setReturnType(String returnType) { - this.returnType = returnType; - } - - public String getAsyncReturnType() { - return asyncReturnType; - } - - public void setAsyncReturnType(String asyncReturnType) { - this.asyncReturnType = asyncReturnType; - } -} diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/CustomizationConfig.java b/codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/CustomizationConfig.java index 6f54c5a31876..c50d4719243e 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/CustomizationConfig.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/CustomizationConfig.java @@ -189,7 +189,7 @@ public class CustomizationConfig { private String userAgent; - private BatchManagerMethod batchManagerMethod; + private Map batchManagerMethods; private CustomizationConfig() { } @@ -488,11 +488,11 @@ public CustomizationConfig withUserAgent(String userAgent) { return this; } - public BatchManagerMethod getBatchManagerMethod() { - return batchManagerMethod; + public Map getBatchManagerMethods() { + return batchManagerMethods; } - public void setBatchManagerMethod(BatchManagerMethod batchManagerMethod) { - this.batchManagerMethod = batchManagerMethod; + public void setBatchManager(Map batchManagerMethods) { + this.batchManagerMethods = batchManagerMethods; } } diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/model/intermediate/Metadata.java b/codegen/src/main/java/software/amazon/awssdk/codegen/model/intermediate/Metadata.java index eb3a83d9fb20..06afe93e091c 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/model/intermediate/Metadata.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/model/intermediate/Metadata.java @@ -69,6 +69,8 @@ public class Metadata { private String waitersPackageName; + private String batchManagerPackageName; + private String serviceAbbreviation; private String serviceFullName; @@ -683,4 +685,25 @@ public String getFullWaitersPackageName() { public String getFullWaitersInternalPackageName() { return joinPackageNames(getFullWaitersPackageName(), "internal"); } + + public String getBatchManagerPackageName() { + return batchManagerPackageName; + } + + public void setBatchManagerPackageName(String batchManagerPackageName) { + this.batchManagerPackageName = batchManagerPackageName; + } + + public Metadata withBatchmanagerPackageName(String batchmanagerPackageName) { + setBatchManagerPackageName(batchmanagerPackageName); + return this; + } + + public String getFullBatchManagerPackageName() { + return joinPackageNames(rootPackageName, getBatchManagerPackageName()); + } + + public String getFullBatchManagerInternalPackageName() { + return joinPackageNames(getFullBatchManagerPackageName(), "internal"); + } } diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/naming/DefaultNamingStrategy.java b/codegen/src/main/java/software/amazon/awssdk/codegen/naming/DefaultNamingStrategy.java index 0a996a7fbdf2..034e54a47ba1 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/naming/DefaultNamingStrategy.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/naming/DefaultNamingStrategy.java @@ -181,6 +181,11 @@ public String getSmokeTestPackageName(String serviceName) { Constant.PACKAGE_NAME_SMOKE_TEST_PATTERN); } + @Override + public String getBatchManagerPackageName(String serviceName) { + return getCustomizedPackageName(concatServiceNameIfShareModel(serviceName), Constant.PACKAGE_NAME_BATCHMANAGER_PATTERN); + } + /** * If the service is sharing models with other services, we need to concatenate its customized package name * if provided or service name with the shared service name. diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/naming/NamingStrategy.java b/codegen/src/main/java/software/amazon/awssdk/codegen/naming/NamingStrategy.java index d59a34df29b6..8dff92882728 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/naming/NamingStrategy.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/naming/NamingStrategy.java @@ -63,6 +63,11 @@ public interface NamingStrategy { */ String getSmokeTestPackageName(String serviceName); + /** + * Retrieve the batchmanager package name that should be used based on the service name. + */ + String getBatchManagerPackageName(String serviceName); + /** * @param errorShapeName Name of error shape to derive exception class name from. * @return Appropriate name to use for a Java exception class name diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/PoetExtensions.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/PoetExtensions.java index d372649415d5..77ed3bc8702c 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/PoetExtensions.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/PoetExtensions.java @@ -95,6 +95,21 @@ public ClassName getAsyncWaiterClass() { "AsyncWaiter"); } + public ClassName getBatchFunctionsClass() { + return ClassName.get(model.getMetadata().getFullBatchManagerInternalPackageName(), model.getMetadata().getServiceName() + + "BatchFunctions"); + } + + public ClassName getBatchManagerSyncReturnType() { + return ClassName.get(model.getMetadata().getFullBatchManagerPackageName(), model.getMetadata().getServiceName() + + "BatchManager"); + } + + public ClassName getBatchManagerAsyncReturnType() { + return ClassName.get(model.getMetadata().getFullBatchManagerPackageName(), model.getMetadata().getServiceName() + + "AsyncBatchManager"); + } + /** * @param operationName Name of the operation * @return A Poet {@link ClassName} for the response type of a async paginated operation in the base service package. diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/batchmanager/BatchFunctionsClassSpec.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/batchmanager/BatchFunctionsClassSpec.java new file mode 100644 index 000000000000..dc51abbbfc71 --- /dev/null +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/batchmanager/BatchFunctionsClassSpec.java @@ -0,0 +1,426 @@ +/* + * 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.poet.batchmanager; + +import static javax.lang.model.element.Modifier.FINAL; +import static javax.lang.model.element.Modifier.PRIVATE; +import static javax.lang.model.element.Modifier.PUBLIC; +import static javax.lang.model.element.Modifier.STATIC; +import static software.amazon.awssdk.codegen.poet.batchmanager.BatchTypesUtils.getBatchRequestEntryType; +import static software.amazon.awssdk.codegen.poet.batchmanager.BatchTypesUtils.getBatchRequestMethod; +import static software.amazon.awssdk.codegen.poet.batchmanager.BatchTypesUtils.getBatchRequestType; +import static software.amazon.awssdk.codegen.poet.batchmanager.BatchTypesUtils.getBatchResponseType; +import static software.amazon.awssdk.codegen.poet.batchmanager.BatchTypesUtils.getErrorBatchEntry; +import static software.amazon.awssdk.codegen.poet.batchmanager.BatchTypesUtils.getErrorEntriesMethod; +import static software.amazon.awssdk.codegen.poet.batchmanager.BatchTypesUtils.getRequestType; +import static software.amazon.awssdk.codegen.poet.batchmanager.BatchTypesUtils.getResponseType; +import static software.amazon.awssdk.codegen.poet.batchmanager.BatchTypesUtils.getSuccessBatchEntry; +import static software.amazon.awssdk.codegen.poet.batchmanager.BatchTypesUtils.getType; + +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.CodeBlock; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterizedTypeName; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.TypeSpec; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import software.amazon.awssdk.annotations.SdkInternalApi; +import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration; +import software.amazon.awssdk.awscore.exception.AwsErrorDetails; +import software.amazon.awssdk.codegen.model.config.customization.BatchManager; +import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel; +import software.amazon.awssdk.codegen.model.intermediate.MemberModel; +import software.amazon.awssdk.codegen.model.intermediate.ShapeModel; +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.core.batchmanager.BatchAndSend; +import software.amazon.awssdk.core.batchmanager.BatchKeyMapper; +import software.amazon.awssdk.core.batchmanager.BatchResponseMapper; +import software.amazon.awssdk.core.batchmanager.IdentifiableMessage; +import software.amazon.awssdk.utils.Either; +import software.amazon.awssdk.utils.Logger; + +public class BatchFunctionsClassSpec implements ClassSpec { + + private static final Logger log = Logger.loggerFor(BatchFunctionsClassSpec.class); + + private final IntermediateModel model; + private final Map batchFunctions; + private final String modelPackage; + private final PoetExtensions poetExtensions; + private final ClassName className; + private final ClassName clientName; + private final ClassName asyncClientName; + + public BatchFunctionsClassSpec(IntermediateModel model) { + this.model = model; + this.batchFunctions = model.getCustomizationConfig().getBatchManagerMethods(); + this.modelPackage = model.getMetadata().getFullModelPackageName(); + this.poetExtensions = new PoetExtensions(model); + this.className = poetExtensions.getBatchFunctionsClass(); + this.clientName = poetExtensions.getClientClass(model.getMetadata().getSyncInterface()); + this.asyncClientName = poetExtensions.getClientClass(model.getMetadata().getAsyncInterface()); + } + + @Override + public TypeSpec poetSpec() { + TypeSpec.Builder classBuilder = PoetUtils.createClassBuilder(className) + .addAnnotation(SdkInternalApi.class) + .addModifiers(PUBLIC, FINAL) + .addMethod(constructor()) + .addMethods(batchFunctions()); + + return classBuilder.build(); + } + + @Override + public ClassName className() { + return className; + } + + private MethodSpec constructor() { + return MethodSpec.constructorBuilder().addModifiers(PRIVATE).build(); + } + + private List batchFunctions() { + return batchFunctions.entrySet() + .stream() + .flatMap(this::safeBatchFunctions) + .collect(Collectors.toList()); + } + + private Stream safeBatchFunctions(Map.Entry batchFunctions) throws RuntimeException { + try { + return batchFunctions(batchFunctions); + } catch (IllegalArgumentException e) { + throw new RuntimeException(e); + } + } + + private Stream batchFunctions(Map.Entry batchFunctions) throws IllegalArgumentException { + List methods = new ArrayList<>(); + methods.addAll(batchingFunction(batchFunctions)); + methods.addAll(responseMapper(batchFunctions)); + methods.add(batchKeyMapper(batchFunctions)); + return methods.stream(); + } + + private List batchingFunction(Map.Entry batchFunctions) { + List methods = new ArrayList<>(); + methods.add(batchingFunctionSync(batchFunctions)); + methods.add(batchingFunctionAsync(batchFunctions)); + methods.add(batchingFunctionHelper(batchFunctions)); + methods.add(addCreateBatchEntryMethod(batchFunctions)); + return methods; + } + + private MethodSpec batchingFunctionSync(Map.Entry batchFunctions) { + String methodName = batchFunctions.getKey() + "BatchFunction"; + MethodSpec.Builder builder = methodSignatureWithReturnType(methodName, batchingFunctionReturn(batchFunctions)) + .addModifiers(PUBLIC, STATIC) + .addParameter(clientName, "client") + .addParameter(ClassName.get(Executor.class), "executor"); + addBatchFunctionStatementSync(builder, batchFunctions); + + return builder.build(); + } + + private MethodSpec batchingFunctionAsync(Map.Entry batchFunctions) { + String methodName = batchFunctions.getKey() + "BatchAsyncFunction"; + MethodSpec.Builder builder = methodSignatureWithReturnType(methodName, batchingFunctionReturn(batchFunctions)) + .addModifiers(PUBLIC, STATIC) + .addParameter(asyncClientName, "client"); + addBatchFunctionStatementAsync(builder, batchFunctions); + + return builder.build(); + } + + private MethodSpec batchingFunctionHelper(Map.Entry batchFunctions) { + ClassName returnType = getBatchRequestType(batchFunctions, modelPackage); + ClassName batchRequestEntryType = getBatchRequestEntryType(batchFunctions, modelPackage); + ClassName batchRequestType = getBatchRequestType(batchFunctions, modelPackage); + ParameterizedTypeName identifiedRequest = ParameterizedTypeName.get(ClassName.get(IdentifiableMessage.class), + getRequestType(batchFunctions, modelPackage)); + ParameterizedTypeName requestsParam = ParameterizedTypeName.get(ClassName.get(List.class), identifiedRequest); + String methodName = "create" + returnType.simpleName(); + + MethodSpec.Builder builder = methodSignatureWithReturnType(methodName, returnType) + .addModifiers(PRIVATE, STATIC) + .addParameter(requestsParam, "identifiedRequests") + .addParameter(ClassName.get(String.class), "batchKey"); + + String batchKeyMethod = batchFunctions.getValue().getBatchKey(); + builder.addStatement("$T entries = identifiedRequests.stream()\n" + + ".map(identifiedRequest -> $N(identifiedRequest.id(),\n" + + "identifiedRequest.message()))\n" + + ".collect($T.toList())", + ParameterizedTypeName.get(ClassName.get(List.class), batchRequestEntryType), + addCreateBatchEntryMethod(batchFunctions), + ClassName.get(Collectors.class)) + .addCode("// Since requests are batched together according to a combination of their $L and " + + "overrideConfiguration, all requests must have the same overrideConfiguration so it is sufficient to " + + "retrieve it from the first request.\n", batchKeyMethod) + .addStatement("$T overrideConfiguration = identifiedRequests\n" + + ".get(0)\n" + + ".message()\n" + + ".overrideConfiguration()", + ParameterizedTypeName.get(ClassName.get(Optional.class), + ClassName.get(AwsRequestOverrideConfiguration.class))) + .addStatement("return overrideConfiguration.map(overrideConfig -> $T.builder()\n" + + ".$L(batchKey)\n" + + ".overrideConfiguration(overrideConfig)\n" + + ".entries(entries)\n" + + ".build())\n" + + ".orElse($T.builder()\n" + + ".$L(batchKey)\n" + + ".entries(entries)\n" + + ".build())", + batchRequestType, batchKeyMethod, + batchRequestType, batchKeyMethod); + + return builder.build(); + } + + private void addBatchFunctionStatementSync(MethodSpec.Builder builder, + Map.Entry batchFunctions) { + addBatchFunctionStatementCore(builder, batchFunctions); + builder.addStatement(" return $T.supplyAsync(() -> client.$L(batchRequest), executor);\n" + + "}", + ClassName.get(CompletableFuture.class), + getBatchRequestMethod(batchFunctions)); + } + + private void addBatchFunctionStatementAsync(MethodSpec.Builder builder, + Map.Entry batchFunctions) { + addBatchFunctionStatementCore(builder, batchFunctions); + builder.addStatement(" return client.$L(batchRequest);\n" + + "}", + getBatchRequestMethod(batchFunctions)); + } + + private void addBatchFunctionStatementCore(MethodSpec.Builder builder, + Map.Entry batchFunctions) { + builder.addStatement("return (identifiedRequests, batchKey) -> {\n" + + " $T batchRequest = $N(identifiedRequests, batchKey)", + getBatchRequestType(batchFunctions, modelPackage), + batchingFunctionHelper(batchFunctions)); + } + + private MethodSpec addCreateBatchEntryMethod(Map.Entry batchFunctions) { + ClassName batchRequestEntryType = getBatchRequestEntryType(batchFunctions, modelPackage); + ClassName requestType = getRequestType(batchFunctions, modelPackage); + String methodName = "create" + batchRequestEntryType.simpleName(); + String requestParam = "request"; + + MethodSpec.Builder builder = methodSignatureWithReturnType(methodName, batchRequestEntryType) + .addModifiers(PRIVATE, STATIC) + .addParameter(ClassName.get(String.class), "id") + .addParameter(getRequestType(batchFunctions, modelPackage), requestParam); + builder.addCode("return "); + builder.addCode(builderMapOneClassToAnother(batchFunctions, batchRequestEntryType, requestType, requestParam)); + builder.addCode(".build();"); + + return builder.build(); + } + + private ParameterizedTypeName batchingFunctionReturn(Map.Entry batchFunctions) { + ClassName requestClass = getRequestType(batchFunctions, modelPackage); + ClassName batchResponseClass = getBatchResponseType(batchFunctions, modelPackage); + + return ParameterizedTypeName.get(ClassName.get(BatchAndSend.class), + requestClass, batchResponseClass); + } + + private List responseMapper(Map.Entry batchFunctions) throws IllegalArgumentException { + List methods = new ArrayList<>(); + methods.add(responseMapperCore(batchFunctions)); + methods.add(createResponseFromEntry(batchFunctions)); + methods.add(createThrowableFromEntry(batchFunctions)); + return methods; + } + + private MethodSpec responseMapperCore(Map.Entry batchFunctions) throws IllegalArgumentException { + BatchManager batchManager = batchFunctions.getValue(); + String methodName = batchFunctions.getKey() + "ResponseMapper"; + ClassName responseClass = getResponseType(batchFunctions, modelPackage); + ClassName batchResponseClass = getBatchResponseType(batchFunctions, modelPackage); + ParameterizedTypeName returnType = ParameterizedTypeName.get(ClassName.get(BatchResponseMapper.class), + batchResponseClass, responseClass); + MethodSpec.Builder builder = methodSignatureWithReturnType(methodName, returnType) + .addModifiers(PUBLIC, STATIC); + + ParameterizedTypeName identifiedResponse = ParameterizedTypeName.get(ClassName.get(IdentifiableMessage.class), + responseClass); + ParameterizedTypeName identifiedThrowable = ParameterizedTypeName.get(ClassName.get(IdentifiableMessage.class), + ClassName.get(Throwable.class)); + ParameterizedTypeName either = ParameterizedTypeName.get(ClassName.get(Either.class), identifiedResponse, + identifiedThrowable); + ParameterizedTypeName mappedResponsesType = ParameterizedTypeName.get(ClassName.get(List.class), either); + builder.addStatement("return batchResponse -> {\n" + + " $T mappedResponses = new $T<>()", + mappedResponsesType, ClassName.get(ArrayList.class)) + .addStatement("batchResponse.$L()\n" + + " .forEach(batchResponseEntry -> {\n" + + " IdentifiableMessage<$T> response = $N(batchResponseEntry, batchResponse);\n" + + " mappedResponses.add(Either.left(response));\n" + + "})", + batchManager.getSuccessEntriesMethod(), responseClass, createResponseFromEntry(batchFunctions)); + + String errorEntriesMethod = getErrorEntriesMethod(batchFunctions); + String errorCodeMethod = batchManager.getErrorCodeMethod(); + if (errorEntriesMethod.equals(batchManager.getSuccessEntriesMethod())) { + throw new IllegalArgumentException("A batch operation must return a separate list for success and errors in the " + + "response"); + } else { + if (errorCodeMethod != null) { + builder.addStatement("batchResponse.$L()\n" + + ".forEach(batchResponseEntry -> {\n" + + " IdentifiableMessage response = $N(batchResponseEntry);\n" + + " mappedResponses.add(Either.right(response));\n" + + "})", + getErrorEntriesMethod(batchFunctions), + createThrowableFromEntry(batchFunctions)); + } + } + + builder.addStatement("return mappedResponses;\n" + + "}"); + + return builder.build(); + } + + private MethodSpec createResponseFromEntry(Map.Entry batchFunctions) { + String methodName = "create" + getResponseType(batchFunctions, modelPackage).simpleName(); + String responseParam = "successfulEntry"; + ClassName responseClass = getResponseType(batchFunctions, modelPackage); + ClassName responseEntryClass = getSuccessBatchEntry(batchFunctions, modelPackage); + ParameterizedTypeName returnType = ParameterizedTypeName.get(ClassName.get(IdentifiableMessage.class), responseClass); + MethodSpec.Builder builder = methodSignatureWithReturnType(methodName, returnType) + .addModifiers(PRIVATE, STATIC) + .addParameter(responseEntryClass, responseParam) + .addParameter(getBatchResponseType(batchFunctions, modelPackage), "batchResponse"); + + builder.addStatement("String key = successfulEntry.$L()", batchFunctions.getValue().getBatchRequestIdentifier()); + builder.addCode("$T.Builder builder = ", responseClass); + builder.addStatement(builderMapOneClassToAnother(batchFunctions, responseClass, responseEntryClass, responseParam)); + builder.beginControlFlow("if (batchResponse.responseMetadata() != null)") + .addStatement("builder.responseMetadata(batchResponse.responseMetadata())") + .endControlFlow(); + builder.beginControlFlow("if (batchResponse.sdkHttpResponse() != null)") + .addStatement("builder.sdkHttpResponse(batchResponse.sdkHttpResponse())") + .endControlFlow(); + builder.addStatement("$T response = builder.build()", responseClass); + builder.addStatement("return new $T(key, response)", + returnType); + + return builder.build(); + } + + private MethodSpec createThrowableFromEntry(Map.Entry batchFunctions) { + String methodName = batchFunctions.getKey() + "CreateThrowable"; + String responseParam = "failedEntry"; + BatchManager batchManager = batchFunctions.getValue(); + ClassName responseClass = ClassName.get(Throwable.class); + ClassName exceptionType = getType(model.getMetadata().getServiceName() + "Exception", modelPackage); + ParameterizedTypeName returnClass = ParameterizedTypeName.get(ClassName.get(IdentifiableMessage.class), responseClass); + MethodSpec.Builder builder = methodSignatureWithReturnType(methodName, returnClass) + .addModifiers(PRIVATE, STATIC) + .addParameter(getErrorBatchEntry(batchFunctions, modelPackage), responseParam); + + // TODO: Figure out a better way to return error entry's. Right now we are just returning the error code and message in + // an exception but ideally we would want to return all field's in the error entry. + builder.addStatement("String key = failedEntry.$L()", batchManager.getBatchRequestIdentifier()); + + builder.addCode("$T errorDetailsBuilder = $T.builder()", + ClassName.get(AwsErrorDetails.class), ClassName.get(AwsErrorDetails.class)); + if (batchManager.getErrorCodeMethod() != null) { + builder.addCode(".errorCode($L.$L())", responseParam, batchManager.getErrorCodeMethod()); + } + if (batchManager.getErrorMessageMethod() != null) { + builder.addCode(".errorMessage($L.$L())", responseParam, batchManager.getErrorMessageMethod()); + } + builder.addCode(".build();\n"); + + builder.addStatement("$T response = $T.builder().awsErrorDetails(errorDetailsBuilder).build()", + responseClass, exceptionType); + builder.addStatement("return new $T(key, response)", + returnClass); + + return builder.build(); + } + + private CodeBlock builderMapOneClassToAnother(Map.Entry batchFunctions, ClassName newType, + ClassName originalType, String originalParam) { + CodeBlock.Builder builder = CodeBlock.builder(); + + builder.add("$T.builder()", newType); + ShapeModel newShape = model.getShapes().get(newType.simpleName()); + ShapeModel originalShape = model.getShapes().get(originalType.simpleName()); + + if (newShape == null) { + throw new IllegalArgumentException("Bad input for type: " + newType.simpleName()); + } + if (originalShape == null) { + throw new IllegalArgumentException("Bad input for type: " + originalType.simpleName()); + } + + newShape.getMembers() + .forEach(memberModel -> { + MemberModel foundMember = originalShape.getMemberByName(memberModel.getName()); + String setterMethod = memberModel.getFluentSetterMethodName(); + if (setterMethod.equals(batchFunctions.getValue().getBatchRequestIdentifier())) { + builder.add(".$L(id)\n", setterMethod); + } else if (foundMember != null) { + String getterMethod = foundMember.getFluentGetterMethodName(); + builder.add(".$L($L.$L())\n", setterMethod, originalParam, getterMethod); + } else { + log.debug(() -> originalType.simpleName() + " doesn't have method: " + memberModel.getName()); + } + }); + + return builder.build(); + } + + private MethodSpec batchKeyMapper(Map.Entry batchFunctions) { + String methodName = batchFunctions.getKey() + "BatchKeyMapper"; + String batchKeyMethod = batchFunctions.getValue().getBatchKey(); + ClassName requestClass = getRequestType(batchFunctions, modelPackage); + ParameterizedTypeName returnType = ParameterizedTypeName.get(ClassName.get(BatchKeyMapper.class), requestClass); + + MethodSpec.Builder builder = methodSignatureWithReturnType(methodName, returnType) + .addModifiers(PUBLIC, STATIC); + builder.addStatement("return request -> request.overrideConfiguration()\n" + + ".map(overrideConfig -> request.$L() + overrideConfig.hashCode())\n" + + ".orElse(request.$L())", + batchKeyMethod, batchKeyMethod); + + return builder.build(); + } + + private MethodSpec.Builder methodSignatureWithReturnType(String methodName, TypeName returnType) { + return MethodSpec.methodBuilder(methodName) + .returns(returnType); + } + +} diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/batchmanager/BatchTypesUtils.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/batchmanager/BatchTypesUtils.java new file mode 100644 index 000000000000..88271387fdae --- /dev/null +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/batchmanager/BatchTypesUtils.java @@ -0,0 +1,86 @@ +/* + * 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.poet.batchmanager; + +import static software.amazon.awssdk.utils.internal.CodegenNamingUtils.uppercaseFirstChar; + +import com.squareup.javapoet.ClassName; +import java.util.Map; +import software.amazon.awssdk.codegen.model.config.customization.BatchManager; + +/** + * Conenvience methods to access the batch types and methods listed in the customization.config + * TODO: would it make more sense to instantiate this as a class like PoetExtensions instead of making this a static utils class? + */ +public final class BatchTypesUtils { + + private BatchTypesUtils() { + } + + public static ClassName getRequestType(Map.Entry batchFunctions, String modelPackage) { + String requestMethodName = uppercaseFirstChar(batchFunctions.getKey()) + "Request"; + return getType(requestMethodName, modelPackage); + } + + public static ClassName getResponseType(Map.Entry batchFunctions, String modelPackage) { + String requestMethodName = uppercaseFirstChar(batchFunctions.getKey()) + "Response"; + return getType(requestMethodName, modelPackage); + } + + public static String getBatchRequestMethod(Map.Entry batchFunctions) { + return batchFunctions.getValue().getBatchMethod(); + } + + public static ClassName getBatchRequestType(Map.Entry batchFunctions, String modelPackage) { + String requestMethodName = uppercaseFirstChar(getBatchRequestMethod(batchFunctions)) + "Request"; + return getType(requestMethodName, modelPackage); + } + + public static ClassName getBatchRequestEntryType(Map.Entry batchFunctions, String modelPackage) { + String requestMethodName = batchFunctions.getValue().getBatchRequestEntry(); + return getType(requestMethodName, modelPackage); + } + + public static ClassName getBatchResponseType(Map.Entry batchFunctions, String modelPackage) { + String requestMethodName = uppercaseFirstChar(batchFunctions.getValue().getBatchMethod()) + "Response"; + return getType(requestMethodName, modelPackage); + } + + public static ClassName getSuccessBatchEntry(Map.Entry batchFunctions, String modelPackage) { + return getType(batchFunctions.getValue().getSuccessBatchEntry(), modelPackage); + } + + public static ClassName getErrorBatchEntry(Map.Entry batchFunctions, String modelPackage) { + String errorBatchEntry = batchFunctions.getValue().getErrorBatchEntry(); + if (errorBatchEntry == null) { + return getSuccessBatchEntry(batchFunctions, modelPackage); + } + return getType(errorBatchEntry, modelPackage); + } + + public static String getErrorEntriesMethod(Map.Entry batchFunctions) { + String errorEntriesMethod = batchFunctions.getValue().getErrorEntriesMethod(); + if (errorEntriesMethod == null) { + return batchFunctions.getValue().getSuccessEntriesMethod(); + } + return errorEntriesMethod; + } + + public static ClassName getType(String type, String modelPackage) { + return ClassName.get(modelPackage, type); + } + +} diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java index 2b24a48aa4ee..c397e9a4dc28 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java @@ -148,8 +148,8 @@ public TypeSpec poetSpec() { addScheduledExecutorIfNeeded(classBuilder); } - if (model.getCustomizationConfig().getBatchManagerMethod() != null) { - classBuilder.addMethod(batchMangerMethod(model, false)); + if (model.getCustomizationConfig().getBatchManagerMethods() != null) { + classBuilder.addMethod(batchMangerMethod(poetExtensions, false)); addScheduledExecutorIfNeeded(classBuilder); } @@ -202,7 +202,7 @@ private MethodSpec constructor(Builder classBuilder) { builder.endControlFlow(); } - if (model.hasWaiters() || model.getCustomizationConfig().getBatchManagerMethod() != null) { + if (model.hasWaiters() || model.getCustomizationConfig().getBatchManagerMethods() != null) { builder.addStatement("this.executorService = clientConfiguration.option($T.SCHEDULED_EXECUTOR_SERVICE)", SdkClientOption.class); } 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 2a438fdec3b3..c0f064b8c5aa 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 @@ -39,7 +39,6 @@ import software.amazon.awssdk.codegen.docs.DocConfiguration; import software.amazon.awssdk.codegen.docs.SimpleMethodOverload; import software.amazon.awssdk.codegen.docs.WaiterDocs; -import software.amazon.awssdk.codegen.model.config.customization.BatchManagerMethod; import software.amazon.awssdk.codegen.model.config.customization.UtilitiesMethod; import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel; import software.amazon.awssdk.codegen.model.intermediate.OperationModel; @@ -109,7 +108,7 @@ public TypeSpec poetSpec() { result.addMethod(waiterMethod()); } - if (model.getCustomizationConfig().getBatchManagerMethod() != null) { + if (model.getCustomizationConfig().getBatchManagerMethods() != null) { result.addMethod(batchManagerMethod()); } @@ -474,9 +473,7 @@ private MethodSpec waiterMethod() { } private MethodSpec batchManagerMethod() { - BatchManagerMethod config = model.getCustomizationConfig().getBatchManagerMethod(); - ClassName returnType = PoetUtils.classNameFromFqcn(config.getAsyncReturnType()); - + ClassName returnType = poetExtensions.getBatchManagerAsyncReturnType(); return MethodSpec.methodBuilder("batchManager") .returns(returnType) .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 570a47c354b0..e1d04fb0706f 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 @@ -32,7 +32,6 @@ import software.amazon.awssdk.arns.Arn; import software.amazon.awssdk.auth.signer.EventStreamAws4Signer; import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration; -import software.amazon.awssdk.codegen.model.config.customization.BatchManagerMethod; import software.amazon.awssdk.codegen.model.config.customization.S3ArnableFieldConfig; import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel; import software.amazon.awssdk.codegen.model.intermediate.MemberModel; @@ -269,17 +268,16 @@ static Optional addS3ArnableFieldCode(OperationModel opModel, Interme return Optional.empty(); } - static MethodSpec batchMangerMethod(IntermediateModel model, boolean isSync) { + static MethodSpec batchMangerMethod(PoetExtensions poetExtensions, boolean isSync) { String scheduledExecutor = "executorService"; - BatchManagerMethod config = model.getCustomizationConfig().getBatchManagerMethod(); ClassName returnType; if (isSync) { - returnType = PoetUtils.classNameFromFqcn(config.getReturnType()); + returnType = poetExtensions.getBatchManagerSyncReturnType(); } else { - returnType = PoetUtils.classNameFromFqcn(config.getAsyncReturnType()); + returnType = poetExtensions.getBatchManagerAsyncReturnType(); } - return MethodSpec.methodBuilder(BatchManagerMethod.METHOD_NAME) + return MethodSpec.methodBuilder("batchManager") .addModifiers(Modifier.PUBLIC) .addAnnotation(Override.class) .returns(returnType) diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java index e8459b62792e..85e58fc88e5c 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java @@ -118,8 +118,8 @@ public TypeSpec poetSpec() { classBuilder.addMethod(utilitiesMethod()); } - if (model.getCustomizationConfig().getBatchManagerMethod() != null) { - classBuilder.addMethod(batchMangerMethod(model, true)); + if (model.getCustomizationConfig().getBatchManagerMethods() != null) { + classBuilder.addMethod(batchMangerMethod(poetExtensions, true)); classBuilder.addField(FieldSpec.builder(ClassName.get(ScheduledExecutorService.class), "executorService") .addModifiers(PRIVATE, FINAL) .build()); @@ -190,7 +190,7 @@ private MethodSpec constructor() { builder.endControlFlow(); } - if (model.getCustomizationConfig().getBatchManagerMethod() != null) { + if (model.getCustomizationConfig().getBatchManagerMethods() != null) { builder.addStatement("this.executorService = clientConfiguration.option($T.SCHEDULED_EXECUTOR_SERVICE)", SdkClientOption.class); } 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 81a6df05f24f..0a4b749907a1 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 @@ -42,7 +42,6 @@ import software.amazon.awssdk.codegen.docs.DocConfiguration; import software.amazon.awssdk.codegen.docs.SimpleMethodOverload; import software.amazon.awssdk.codegen.docs.WaiterDocs; -import software.amazon.awssdk.codegen.model.config.customization.BatchManagerMethod; import software.amazon.awssdk.codegen.model.config.customization.UtilitiesMethod; import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel; import software.amazon.awssdk.codegen.model.intermediate.OperationModel; @@ -111,7 +110,7 @@ public TypeSpec poetSpec() { result.addMethod(waiterMethod()); } - if (model.getCustomizationConfig().getBatchManagerMethod() != null) { + if (model.getCustomizationConfig().getBatchManagerMethods() != null) { result.addMethod(batchManagerMethod()); } @@ -505,9 +504,7 @@ private MethodSpec waiterMethod() { } private MethodSpec batchManagerMethod() { - BatchManagerMethod config = model.getCustomizationConfig().getBatchManagerMethod(); - ClassName returnType = PoetUtils.classNameFromFqcn(config.getReturnType()); - + ClassName returnType = poetExtensions.getBatchManagerSyncReturnType(); return MethodSpec.methodBuilder("batchManager") .returns(returnType) .addModifiers(Modifier.PUBLIC, Modifier.DEFAULT) diff --git a/codegen/src/test/java/software/amazon/awssdk/codegen/poet/client/PoetClientFunctionalTests.java b/codegen/src/test/java/software/amazon/awssdk/codegen/poet/client/PoetClientFunctionalTests.java index 957f1349ffde..733c3f44cd43 100644 --- a/codegen/src/test/java/software/amazon/awssdk/codegen/poet/client/PoetClientFunctionalTests.java +++ b/codegen/src/test/java/software/amazon/awssdk/codegen/poet/client/PoetClientFunctionalTests.java @@ -23,7 +23,7 @@ import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel; import software.amazon.awssdk.codegen.poet.ClassSpec; import software.amazon.awssdk.codegen.poet.ClientTestModels; -import software.amazon.awssdk.codegen.poet.waiters.WaiterInterfaceSpec; +import software.amazon.awssdk.codegen.poet.batchmanager.BatchFunctionsClassSpec; public class PoetClientFunctionalTests { @@ -143,4 +143,10 @@ public void asyncClientBatchManagerInterface() throws Exception { ClassSpec asyncClientBatchManagerInterface = new AsyncClientInterface(ClientTestModels.batchManagerModels()); assertThat(asyncClientBatchManagerInterface, generatesTo("test-batchmanager-async-interface.java")); } + + @Test + public void batchFunctionsClass() throws Exception { + ClassSpec batchFunctionsClassSpec = new BatchFunctionsClassSpec(ClientTestModels.batchManagerModels()); + assertThat(batchFunctionsClassSpec, generatesTo("test-batchmanager-batchfunctions.java")); + } } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/batchmanager/test-batchmanager-batchfunctions.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/batchmanager/test-batchmanager-batchfunctions.java new file mode 100644 index 000000000000..05f997a8b512 --- /dev/null +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/batchmanager/test-batchmanager-batchfunctions.java @@ -0,0 +1,204 @@ +package software.amazon.awssdk.services.batchmanagertest.batchmanager.internal; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.stream.Collectors; +import software.amazon.awssdk.annotations.Generated; +import software.amazon.awssdk.annotations.SdkInternalApi; +import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration; +import software.amazon.awssdk.awscore.exception.AwsErrorDetails; +import software.amazon.awssdk.core.batchmanager.BatchAndSend; +import software.amazon.awssdk.core.batchmanager.BatchKeyMapper; +import software.amazon.awssdk.core.batchmanager.BatchResponseMapper; +import software.amazon.awssdk.core.batchmanager.IdentifiableMessage; +import software.amazon.awssdk.services.batchmanagertest.BatchManagerTestAsyncClient; +import software.amazon.awssdk.services.batchmanagertest.BatchManagerTestClient; +import software.amazon.awssdk.services.batchmanagertest.model.BatchManagerTestException; +import software.amazon.awssdk.services.batchmanagertest.model.BatchResultErrorEntry; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestBatchRequest; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestBatchRequestEntry; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestBatchResponse; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestBatchResultEntry; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestRequest; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestResponse; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestBatchRequest; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestBatchRequestEntry; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestBatchResponse; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestBatchResultEntry; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestRequest; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestResponse; +import software.amazon.awssdk.utils.Either; + +@Generated("software.amazon.awssdk:codegen") +@SdkInternalApi +public final class BatchManagerTestBatchFunctions { + private BatchManagerTestBatchFunctions() { + } + + public static BatchAndSend sendRequestBatchFunction( + BatchManagerTestClient client, Executor executor) { + return (identifiedRequests, batchKey) -> { + SendRequestBatchRequest batchRequest = createSendRequestBatchRequest(identifiedRequests, batchKey); + return CompletableFuture.supplyAsync(() -> client.sendRequestBatch(batchRequest), executor); + }; + } + + public static BatchAndSend sendRequestBatchAsyncFunction( + BatchManagerTestAsyncClient client) { + return (identifiedRequests, batchKey) -> { + SendRequestBatchRequest batchRequest = createSendRequestBatchRequest(identifiedRequests, batchKey); + return client.sendRequestBatch(batchRequest); + }; + } + + private static SendRequestBatchRequest createSendRequestBatchRequest( + List> identifiedRequests, String batchKey) { + List entries = identifiedRequests + .stream() + .map(identifiedRequest -> createSendRequestBatchRequestEntry(identifiedRequest.id(), identifiedRequest.message())) + .collect(Collectors.toList()); + // Since requests are batched together according to a combination of their destination and + // overrideConfiguration, all requests must have the same overrideConfiguration so it is sufficient to retrieve + // it from the first request. + Optional overrideConfiguration = identifiedRequests.get(0).message() + .overrideConfiguration(); + return overrideConfiguration.map( + overrideConfig -> SendRequestBatchRequest.builder().destination(batchKey).overrideConfiguration(overrideConfig) + .entries(entries).build()).orElse( + SendRequestBatchRequest.builder().destination(batchKey).entries(entries).build()); + } + + private static SendRequestBatchRequestEntry createSendRequestBatchRequestEntry(String id, SendRequestRequest request) { + return SendRequestBatchRequestEntry.builder().id(id).messageBody(request.messageBody()).delaySeconds(request.delaySeconds()) + .messageDeduplicationId(request.messageDeduplicationId()).messageGroupId(request.messageGroupId()).build(); + } + + public static BatchResponseMapper sendRequestResponseMapper() { + return batchResponse -> { + List, IdentifiableMessage>> mappedResponses = new ArrayList<>(); + batchResponse.successful().forEach(batchResponseEntry -> { + IdentifiableMessage response = createSendRequestResponse(batchResponseEntry, batchResponse); + mappedResponses.add(Either.left(response)); + }); + batchResponse.failed().forEach(batchResponseEntry -> { + IdentifiableMessage response = sendRequestCreateThrowable(batchResponseEntry); + mappedResponses.add(Either.right(response)); + }); + return mappedResponses; + }; + } + + private static IdentifiableMessage createSendRequestResponse( + SendRequestBatchResultEntry successfulEntry, SendRequestBatchResponse batchResponse) { + String key = successfulEntry.id(); + SendRequestResponse.Builder builder = SendRequestResponse.builder().md5OfMessageBody(successfulEntry.md5OfMessageBody()) + .md5OfMessageAttributes(successfulEntry.md5OfMessageAttributes()) + .md5OfMessageSystemAttributes(successfulEntry.md5OfMessageSystemAttributes()) + .messageId(successfulEntry.messageId()).sequenceNumber(successfulEntry.sequenceNumber()); + if (batchResponse.responseMetadata() != null) { + builder.responseMetadata(batchResponse.responseMetadata()); + } + if (batchResponse.sdkHttpResponse() != null) { + builder.sdkHttpResponse(batchResponse.sdkHttpResponse()); + } + SendRequestResponse response = builder.build(); + return new IdentifiableMessage(key, response); + } + + private static IdentifiableMessage sendRequestCreateThrowable(BatchResultErrorEntry failedEntry) { + String key = failedEntry.id(); + AwsErrorDetails errorDetailsBuilder = AwsErrorDetails.builder().errorCode(failedEntry.errorCode()) + .errorMessage(failedEntry.errorMessage()).build(); + Throwable response = BatchManagerTestException.builder().awsErrorDetails(errorDetailsBuilder).build(); + return new IdentifiableMessage(key, response); + } + + public static BatchKeyMapper sendRequestBatchKeyMapper() { + return request -> request.overrideConfiguration() + .map(overrideConfig -> request.destination() + overrideConfig.hashCode()).orElse(request.destination()); + } + + public static BatchAndSend deleteRequestBatchFunction( + BatchManagerTestClient client, Executor executor) { + return (identifiedRequests, batchKey) -> { + DeleteRequestBatchRequest batchRequest = createDeleteRequestBatchRequest(identifiedRequests, batchKey); + return CompletableFuture.supplyAsync(() -> client.deleteRequestBatch(batchRequest), executor); + }; + } + + public static BatchAndSend deleteRequestBatchAsyncFunction( + BatchManagerTestAsyncClient client) { + return (identifiedRequests, batchKey) -> { + DeleteRequestBatchRequest batchRequest = createDeleteRequestBatchRequest(identifiedRequests, batchKey); + return client.deleteRequestBatch(batchRequest); + }; + } + + private static DeleteRequestBatchRequest createDeleteRequestBatchRequest( + List> identifiedRequests, String batchKey) { + List entries = identifiedRequests + .stream() + .map(identifiedRequest -> createDeleteRequestBatchRequestEntry(identifiedRequest.id(), + identifiedRequest.message())).collect(Collectors.toList()); + // Since requests are batched together according to a combination of their destination and + // overrideConfiguration, all requests must have the same overrideConfiguration so it is sufficient to retrieve + // it from the first request. + Optional overrideConfiguration = identifiedRequests.get(0).message() + .overrideConfiguration(); + return overrideConfiguration.map( + overrideConfig -> DeleteRequestBatchRequest.builder().destination(batchKey).overrideConfiguration(overrideConfig) + .entries(entries).build()).orElse( + DeleteRequestBatchRequest.builder().destination(batchKey).entries(entries).build()); + } + + private static DeleteRequestBatchRequestEntry createDeleteRequestBatchRequestEntry(String id, DeleteRequestRequest request) { + return DeleteRequestBatchRequestEntry.builder().id(id).receiptHandle(request.receiptHandle()).build(); + } + + public static BatchResponseMapper deleteRequestResponseMapper() { + return batchResponse -> { + List, IdentifiableMessage>> mappedResponses = new ArrayList<>(); + batchResponse.successful().forEach( + batchResponseEntry -> { + IdentifiableMessage response = createDeleteRequestResponse(batchResponseEntry, + batchResponse); + mappedResponses.add(Either.left(response)); + }); + batchResponse.failed().forEach(batchResponseEntry -> { + IdentifiableMessage response = deleteRequestCreateThrowable(batchResponseEntry); + mappedResponses.add(Either.right(response)); + }); + return mappedResponses; + }; + } + + private static IdentifiableMessage createDeleteRequestResponse( + DeleteRequestBatchResultEntry successfulEntry, DeleteRequestBatchResponse batchResponse) { + String key = successfulEntry.id(); + DeleteRequestResponse.Builder builder = DeleteRequestResponse.builder(); + if (batchResponse.responseMetadata() != null) { + builder.responseMetadata(batchResponse.responseMetadata()); + } + if (batchResponse.sdkHttpResponse() != null) { + builder.sdkHttpResponse(batchResponse.sdkHttpResponse()); + } + DeleteRequestResponse response = builder.build(); + return new IdentifiableMessage(key, response); + } + + private static IdentifiableMessage deleteRequestCreateThrowable(BatchResultErrorEntry failedEntry) { + String key = failedEntry.id(); + AwsErrorDetails errorDetailsBuilder = AwsErrorDetails.builder().errorCode(failedEntry.errorCode()) + .errorMessage(failedEntry.errorMessage()).build(); + Throwable response = BatchManagerTestException.builder().awsErrorDetails(errorDetailsBuilder).build(); + return new IdentifiableMessage(key, response); + } + + public static BatchKeyMapper deleteRequestBatchKeyMapper() { + return request -> request.overrideConfiguration() + .map(overrideConfig -> request.destination() + overrideConfig.hashCode()).orElse(request.destination()); + } +} diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/batchmanager/customization.config b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/batchmanager/customization.config index 1c74333135b4..eff96349dcfd 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/batchmanager/customization.config +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/batchmanager/customization.config @@ -1,6 +1,28 @@ { - "batchManagerMethod": { - "returnType": "software.amazon.awssdk.services.batchmanagertest.batchmanager.SyncBatchManagerTest", - "asyncReturnType": "software.amazon.awssdk.services.batchmanagertest.batchmanager.AsyncBatchManagerTest" + "batchManager": { + "sendRequest": { + "batchMethod": "sendRequestBatch", + "batchRequestEntry": "SendRequestBatchRequestEntry", + "successBatchEntry": "SendRequestBatchResultEntry", + "errorBatchEntry": "BatchResultErrorEntry", + "successEntriesMethod": "successful", + "errorEntriesMethod": "failed", + "batchKey": "destination", + "errorCodeMethod": "errorCode", + "errorMessageMethod": "errorMessage", + "batchRequestIdentifier": "id" + }, + "deleteRequest": { + "batchMethod": "deleteRequestBatch", + "batchRequestEntry": "DeleteRequestBatchRequestEntry", + "successBatchEntry": "DeleteRequestBatchResultEntry", + "errorBatchEntry": "BatchResultErrorEntry", + "successEntriesMethod": "successful", + "errorEntriesMethod": "failed", + "batchKey": "destination", + "errorCodeMethod": "errorCode", + "errorMessageMethod": "errorMessage", + "batchRequestIdentifier": "id" + } } } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/batchmanager/service-2.json b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/batchmanager/service-2.json index 35c73133b90f..62992c242bf8 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/batchmanager/service-2.json +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/batchmanager/service-2.json @@ -2,19 +2,328 @@ "version":"2.0", "metadata":{ "apiVersion":"2016-03-11", - "endpointPrefix":"batchmanager", + "endpointPrefix":"batchmanagertest", "jsonVersion":"1.1", "protocol":"rest-json", - "serviceAbbreviation":"BatchManager", - "serviceFullName":"BatchManager", - "serviceId":"BatchManager", + "serviceAbbreviation":"BatchManagerTest", + "serviceFullName":"BatchManagerTest", + "serviceId":"BatchManagerTest", "signatureVersion":"v4", - "uid":"batchmanager-2016-03-11" + "uid":"batchmanagertest-2016-03-11" }, "operations":{ + "SendRequest":{ + "name":"SendMessage", + "http":{ + "method":"POST", + "requestUri":"/" + }, + "input":{"shape":"SendRequestRequest"}, + "output":{ + "shape":"SendRequestResult", + "resultWrapper":"SendRequestResult" + } + }, + "SendRequestBatch":{ + "name":"SendRequestBatch", + "http":{ + "method":"POST", + "requestUri":"/" + }, + "input":{"shape":"SendRequestBatchRequest"}, + "output":{ + "shape":"SendRequestBatchResult", + "resultWrapper":"SendRequestBatchResult" + } + }, + "DeleteRequest":{ + "name":"DeleteRequest", + "http":{ + "method":"POST", + "requestUri":"/" + }, + "input":{"shape":"DeleteRequestRequest"} + }, + "DeleteRequestBatch":{ + "name":"DeleteRequestBatch", + "http":{ + "method":"POST", + "requestUri":"/" + }, + "input":{"shape":"DeleteRequestBatchRequest"}, + "output":{ + "shape":"DeleteRequestBatchResult", + "resultWrapper":"DeleteRequestBatchResult" + } + } }, "shapes": { - "String":{"type":"string"} + "String": { + "type": "string" + }, + "Integer": { + "type": "integer" + }, + "Boolean": { + "type": "boolean" + }, + "SendRequestRequest": { + "type": "structure", + "required": [ + "QueueUrl", + "MessageBody" + ], + "members": { + "QueueUrl": { + "shape": "String" + }, + "MessageBody": { + "shape": "String" + }, + "DelaySeconds": { + "shape": "Integer" + }, + "MessageDeduplicationId": { + "shape": "String" + }, + "MessageGroupId": { + "shape": "String" + } + } + }, + "SendRequestBatchRequest":{ + "type":"structure", + "required":[ + "QueueUrl", + "Entries" + ], + "members":{ + "QueueUrl":{ + "shape":"String" + }, + "Entries":{ + "shape":"SendRequestBatchRequestEntryList" + } + } + }, + "SendRequestBatchRequestEntry": { + "type": "structure", + "required": [ + "Id", + "MessageBody" + ], + "members": { + "Id": { + "shape": "String" + }, + "MessageBody": { + "shape": "String" + }, + "DelaySeconds": { + "shape": "Integer" + }, + "MessageDeduplicationId": { + "shape": "String" + }, + "MessageGroupId": { + "shape": "String" + } + } + }, + "SendRequestBatchRequestEntryList":{ + "type":"list", + "member":{ + "shape":"SendRequestBatchRequestEntry", + "locationName":"SendRequestBatchRequestEntry" + }, + "flattened":true + }, + "DeleteRequestRequest": { + "type": "structure", + "required": [ + "QueueUrl", + "ReceiptHandle" + ], + "members": { + "QueueUrl": { + "shape": "String" + }, + "ReceiptHandle": { + "shape": "String" + } + } + }, + "DeleteRequestBatchRequest":{ + "type":"structure", + "required":[ + "QueueUrl", + "Entries" + ], + "members":{ + "QueueUrl":{ + "shape":"String" + }, + "Entries":{ + "shape":"DeleteRequestBatchRequestEntryList" + } + } + }, + "DeleteRequestBatchRequestEntry": { + "type": "structure", + "required": [ + "Id", + "ReceiptHandle" + ], + "members": { + "Id": { + "shape": "String" + }, + "ReceiptHandle": { + "shape": "String" + } + } + }, + "DeleteRequestBatchRequestEntryList":{ + "type":"list", + "member":{ + "shape":"DeleteRequestBatchRequestEntry", + "locationName":"DeleteRequestBatchRequestEntry" + }, + "flattened":true + }, + "SendRequestResult":{ + "type":"structure", + "members":{ + "MD5OfMessageBody":{ + "shape":"String" + }, + "MD5OfMessageAttributes":{ + "shape":"String" + }, + "MD5OfMessageSystemAttributes":{ + "shape":"String" + }, + "MessageId":{ + "shape":"String" + }, + "SequenceNumber":{ + "shape":"String" + } + } + }, + "SendRequestBatchResult":{ + "type":"structure", + "required":[ + "Successful", + "Failed" + ], + "members":{ + "Successful":{ + "shape":"SendRequestBatchResultEntryList" + }, + "Failed":{ + "shape":"BatchResultErrorEntryList" + } + } + }, + "SendRequestBatchResultEntry":{ + "type":"structure", + "required":[ + "Id", + "MessageId", + "MD5OfMessageBody" + ], + "members":{ + "Id":{ + "shape":"String" + }, + "MessageId":{ + "shape":"String" + }, + "MD5OfMessageBody":{ + "shape":"String" + }, + "MD5OfMessageAttributes":{ + "shape":"String" + }, + "MD5OfMessageSystemAttributes":{ + "shape":"String" + }, + "SequenceNumber":{ + "shape":"String" + } + } + }, + "SendRequestBatchResultEntryList":{ + "type":"list", + "member":{ + "shape":"SendRequestBatchResultEntry", + "locationName":"SendRequestBatchResultEntry" + }, + "flattened":true + }, + "DeleteRequestBatchResult":{ + "type":"structure", + "required":[ + "Successful", + "Failed" + ], + "members":{ + "Successful":{ + "shape":"DeleteRequestBatchResultEntryList" + }, + "Failed":{ + "shape":"BatchResultErrorEntryList" + } + } + }, + "DeleteRequestBatchResultEntry":{ + "type":"structure", + "required":["Id"], + "members":{ + "Id":{ + "shape":"String" + } + } + }, + "DeleteRequestBatchResultEntryList":{ + "type":"list", + "member":{ + "shape":"DeleteRequestBatchResultEntry", + "locationName":"DeleteRequestBatchResultEntry" + }, + "flattened":true + }, + "BatchResultErrorEntry":{ + "type":"structure", + "required":[ + "Id", + "SenderFault", + "Code" + ], + "members":{ + "Id":{ + "shape":"String" + }, + "SenderFault":{ + "shape":"Boolean" + }, + "Code":{ + "shape":"String" + }, + "Message":{ + "shape":"String" + } + } + }, + "BatchResultErrorEntryList":{ + "type":"list", + "member":{ + "shape":"BatchResultErrorEntry", + "locationName":"BatchResultErrorEntry" + }, + "flattened":true + } }, "documentation": "A service that implements the batchManager() method" } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-batchmanager-async-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-batchmanager-async-class.java index 1c6745b8efbd..376f2a99a0c3 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-batchmanager-async-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-batchmanager-async-class.java @@ -1,38 +1,57 @@ -package software.amazon.awssdk.services.batchmanager; +package software.amazon.awssdk.services.batchmanagertest; import static software.amazon.awssdk.utils.FunctionalUtils.runAndLogError; import java.util.Collections; import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ScheduledExecutorService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.annotations.Generated; import software.amazon.awssdk.annotations.SdkInternalApi; +import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration; import software.amazon.awssdk.awscore.client.handler.AwsAsyncClientHandler; import software.amazon.awssdk.awscore.exception.AwsServiceException; import software.amazon.awssdk.core.RequestOverrideConfiguration; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; import software.amazon.awssdk.core.client.handler.AsyncClientHandler; +import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.http.HttpResponseHandler; +import software.amazon.awssdk.core.metrics.CoreMetric; +import software.amazon.awssdk.metrics.MetricCollector; import software.amazon.awssdk.metrics.MetricPublisher; +import software.amazon.awssdk.metrics.NoOpMetricCollector; import software.amazon.awssdk.protocols.json.AwsJsonProtocol; import software.amazon.awssdk.protocols.json.AwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.BaseAwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.JsonOperationMetadata; -import software.amazon.awssdk.services.batchmanager.model.BatchManagerException; -import software.amazon.awssdk.services.batchmanagertest.batchmanager.AsyncBatchManagerTest; +import software.amazon.awssdk.services.batchmanagertest.batchmanager.BatchManagerTestAsyncBatchManager; +import software.amazon.awssdk.services.batchmanagertest.model.BatchManagerTestException; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestBatchRequest; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestBatchResponse; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestRequest; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestResponse; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestBatchRequest; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestBatchResponse; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestRequest; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestResponse; +import software.amazon.awssdk.services.batchmanagertest.transform.DeleteRequestBatchRequestMarshaller; +import software.amazon.awssdk.services.batchmanagertest.transform.DeleteRequestRequestMarshaller; +import software.amazon.awssdk.services.batchmanagertest.transform.SendRequestBatchRequestMarshaller; +import software.amazon.awssdk.services.batchmanagertest.transform.SendRequestRequestMarshaller; +import software.amazon.awssdk.utils.CompletableFutureUtils; /** - * Internal implementation of {@link BatchManagerAsyncClient}. + * Internal implementation of {@link BatchManagerTestAsyncClient}. * - * @see BatchManagerAsyncClient#builder() + * @see BatchManagerTestAsyncClient#builder() */ @Generated("software.amazon.awssdk:codegen") @SdkInternalApi -final class DefaultBatchManagerAsyncClient implements BatchManagerAsyncClient { - private static final Logger log = LoggerFactory.getLogger(DefaultBatchManagerAsyncClient.class); +final class DefaultBatchManagerTestAsyncClient implements BatchManagerTestAsyncClient { + private static final Logger log = LoggerFactory.getLogger(DefaultBatchManagerTestAsyncClient.class); private final AsyncClientHandler clientHandler; @@ -42,7 +61,7 @@ final class DefaultBatchManagerAsyncClient implements BatchManagerAsyncClient { private final ScheduledExecutorService executorService; - protected DefaultBatchManagerAsyncClient(SdkClientConfiguration clientConfiguration) { + protected DefaultBatchManagerTestAsyncClient(SdkClientConfiguration clientConfiguration) { this.clientHandler = new AwsAsyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.protocolFactory = init(AwsJsonProtocolFactory.builder()).build(); @@ -54,14 +73,235 @@ public final String serviceName() { return SERVICE_NAME; } + /** + * Invokes the DeleteRequest operation asynchronously. + * + * @param deleteRequestRequest + * @return A Java Future containing the result of the DeleteRequest operation returned by the service.
+ * The CompletableFuture returned by this method can be completed exceptionally with the following + * exceptions. + *
    + *
  • SdkException Base class for all exceptions that can be thrown by the SDK (both service and client). + * Can be used for catch all scenarios.
  • + *
  • SdkClientException If any client side error occurs such as an IO related failure, failure to get + * credentials, etc.
  • + *
  • BatchManagerTestException Base class for all service exceptions. Unknown exceptions will be thrown as + * an instance of this type.
  • + *
+ * @sample BatchManagerTestAsyncClient.DeleteRequest + * @see AWS API Documentation + */ + @Override + public CompletableFuture deleteRequest(DeleteRequestRequest deleteRequestRequest) { + List metricPublishers = resolveMetricPublishers(clientConfiguration, deleteRequestRequest + .overrideConfiguration().orElse(null)); + MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector + .create("ApiCall"); + try { + apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "BatchManagerTest"); + apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "DeleteRequest"); + JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) + .isPayloadJson(true).build(); + + HttpResponseHandler responseHandler = protocolFactory.createResponseHandler(operationMetadata, + DeleteRequestResponse::builder); + + HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, + operationMetadata); + + CompletableFuture executeFuture = clientHandler + .execute(new ClientExecutionParams() + .withOperationName("DeleteRequest") + .withMarshaller(new DeleteRequestRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withMetricCollector(apiCallMetricCollector).withInput(deleteRequestRequest)); + AwsRequestOverrideConfiguration requestOverrideConfig = deleteRequestRequest.overrideConfiguration().orElse(null); + CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { + metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); + }); + executeFuture = CompletableFutureUtils.forwardExceptionTo(whenCompleted, executeFuture); + return executeFuture; + } catch (Throwable t) { + metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); + return CompletableFutureUtils.failedFuture(t); + } + } + + /** + * Invokes the DeleteRequestBatch operation asynchronously. + * + * @param deleteRequestBatchRequest + * @return A Java Future containing the result of the DeleteRequestBatch operation returned by the service.
+ * The CompletableFuture returned by this method can be completed exceptionally with the following + * exceptions. + *
    + *
  • SdkException Base class for all exceptions that can be thrown by the SDK (both service and client). + * Can be used for catch all scenarios.
  • + *
  • SdkClientException If any client side error occurs such as an IO related failure, failure to get + * credentials, etc.
  • + *
  • BatchManagerTestException Base class for all service exceptions. Unknown exceptions will be thrown as + * an instance of this type.
  • + *
+ * @sample BatchManagerTestAsyncClient.DeleteRequestBatch + * @see AWS API Documentation + */ + @Override + public CompletableFuture deleteRequestBatch(DeleteRequestBatchRequest deleteRequestBatchRequest) { + List metricPublishers = resolveMetricPublishers(clientConfiguration, deleteRequestBatchRequest + .overrideConfiguration().orElse(null)); + MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector + .create("ApiCall"); + try { + apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "BatchManagerTest"); + apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "DeleteRequestBatch"); + JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) + .isPayloadJson(true).build(); + + HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( + operationMetadata, DeleteRequestBatchResponse::builder); + + HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, + operationMetadata); + + CompletableFuture executeFuture = clientHandler + .execute(new ClientExecutionParams() + .withOperationName("DeleteRequestBatch") + .withMarshaller(new DeleteRequestBatchRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withMetricCollector(apiCallMetricCollector).withInput(deleteRequestBatchRequest)); + AwsRequestOverrideConfiguration requestOverrideConfig = deleteRequestBatchRequest.overrideConfiguration() + .orElse(null); + CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { + metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); + }); + executeFuture = CompletableFutureUtils.forwardExceptionTo(whenCompleted, executeFuture); + return executeFuture; + } catch (Throwable t) { + metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); + return CompletableFutureUtils.failedFuture(t); + } + } + + /** + * Invokes the SendRequest operation asynchronously. + * + * @param sendRequestRequest + * @return A Java Future containing the result of the SendRequest operation returned by the service.
+ * The CompletableFuture returned by this method can be completed exceptionally with the following + * exceptions. + *
    + *
  • SdkException Base class for all exceptions that can be thrown by the SDK (both service and client). + * Can be used for catch all scenarios.
  • + *
  • SdkClientException If any client side error occurs such as an IO related failure, failure to get + * credentials, etc.
  • + *
  • BatchManagerTestException Base class for all service exceptions. Unknown exceptions will be thrown as + * an instance of this type.
  • + *
+ * @sample BatchManagerTestAsyncClient.SendRequest + * @see AWS + * API Documentation + */ + @Override + public CompletableFuture sendRequest(SendRequestRequest sendRequestRequest) { + List metricPublishers = resolveMetricPublishers(clientConfiguration, sendRequestRequest + .overrideConfiguration().orElse(null)); + MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector + .create("ApiCall"); + try { + apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "BatchManagerTest"); + apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "SendRequest"); + JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) + .isPayloadJson(true).build(); + + HttpResponseHandler responseHandler = protocolFactory.createResponseHandler(operationMetadata, + SendRequestResponse::builder); + + HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, + operationMetadata); + + CompletableFuture executeFuture = clientHandler + .execute(new ClientExecutionParams() + .withOperationName("SendRequest").withMarshaller(new SendRequestRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withMetricCollector(apiCallMetricCollector).withInput(sendRequestRequest)); + AwsRequestOverrideConfiguration requestOverrideConfig = sendRequestRequest.overrideConfiguration().orElse(null); + CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { + metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); + }); + executeFuture = CompletableFutureUtils.forwardExceptionTo(whenCompleted, executeFuture); + return executeFuture; + } catch (Throwable t) { + metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); + return CompletableFutureUtils.failedFuture(t); + } + } + + /** + * Invokes the SendRequestBatch operation asynchronously. + * + * @param sendRequestBatchRequest + * @return A Java Future containing the result of the SendRequestBatch operation returned by the service.
+ * The CompletableFuture returned by this method can be completed exceptionally with the following + * exceptions. + *
    + *
  • SdkException Base class for all exceptions that can be thrown by the SDK (both service and client). + * Can be used for catch all scenarios.
  • + *
  • SdkClientException If any client side error occurs such as an IO related failure, failure to get + * credentials, etc.
  • + *
  • BatchManagerTestException Base class for all service exceptions. Unknown exceptions will be thrown as + * an instance of this type.
  • + *
+ * @sample BatchManagerTestAsyncClient.SendRequestBatch + * @see AWS API Documentation + */ + @Override + public CompletableFuture sendRequestBatch(SendRequestBatchRequest sendRequestBatchRequest) { + List metricPublishers = resolveMetricPublishers(clientConfiguration, sendRequestBatchRequest + .overrideConfiguration().orElse(null)); + MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector + .create("ApiCall"); + try { + apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "BatchManagerTest"); + apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "SendRequestBatch"); + JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) + .isPayloadJson(true).build(); + + HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( + operationMetadata, SendRequestBatchResponse::builder); + + HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, + operationMetadata); + + CompletableFuture executeFuture = clientHandler + .execute(new ClientExecutionParams() + .withOperationName("SendRequestBatch") + .withMarshaller(new SendRequestBatchRequestMarshaller(protocolFactory)) + .withResponseHandler(responseHandler).withErrorResponseHandler(errorResponseHandler) + .withMetricCollector(apiCallMetricCollector).withInput(sendRequestBatchRequest)); + AwsRequestOverrideConfiguration requestOverrideConfig = sendRequestBatchRequest.overrideConfiguration().orElse(null); + CompletableFuture whenCompleted = executeFuture.whenComplete((r, e) -> { + metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); + }); + executeFuture = CompletableFutureUtils.forwardExceptionTo(whenCompleted, executeFuture); + return executeFuture; + } catch (Throwable t) { + metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); + return CompletableFutureUtils.failedFuture(t); + } + } + @Override public void close() { clientHandler.close(); } private > T init(T builder) { - return builder.clientConfiguration(clientConfiguration).defaultServiceExceptionSupplier(BatchManagerException::builder) - .protocol(AwsJsonProtocol.REST_JSON).protocolVersion("1.1"); + return builder.clientConfiguration(clientConfiguration) + .defaultServiceExceptionSupplier(BatchManagerTestException::builder).protocol(AwsJsonProtocol.REST_JSON) + .protocolVersion("1.1"); } private static List resolveMetricPublishers(SdkClientConfiguration clientConfiguration, @@ -85,7 +325,7 @@ private HttpResponseHandler createErrorResponseHandler(Base } @Override - public AsyncBatchManagerTest batchManager() { - return AsyncBatchManagerTest.builder().client(this).scheduledExecutor(executorService).build(); + public BatchManagerTestAsyncBatchManager batchManager() { + return BatchManagerTestAsyncBatchManager.builder().client(this).scheduledExecutor(executorService).build(); } } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-batchmanager-async-interface.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-batchmanager-async-interface.java index 63a807011b7b..ee726ba316df 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-batchmanager-async-interface.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-batchmanager-async-interface.java @@ -1,13 +1,23 @@ -package software.amazon.awssdk.services.batchmanager; +package software.amazon.awssdk.services.batchmanagertest; +import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; import software.amazon.awssdk.annotations.Generated; import software.amazon.awssdk.annotations.SdkPublicApi; import software.amazon.awssdk.annotations.ThreadSafe; import software.amazon.awssdk.core.SdkClient; -import software.amazon.awssdk.services.batchmanagertest.batchmanager.AsyncBatchManagerTest; +import software.amazon.awssdk.services.batchmanagertest.batchmanager.BatchManagerTestAsyncBatchManager; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestBatchRequest; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestBatchResponse; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestRequest; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestResponse; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestBatchRequest; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestBatchResponse; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestRequest; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestResponse; /** - * Service client for accessing BatchManager asynchronously. This can be created using the static {@link #builder()} + * Service client for accessing BatchManagerTest asynchronously. This can be created using the static {@link #builder()} * method. * * A service that implements the batchManager() method @@ -15,35 +25,243 @@ @Generated("software.amazon.awssdk:codegen") @SdkPublicApi @ThreadSafe -public interface BatchManagerAsyncClient extends SdkClient { - String SERVICE_NAME = "batchmanager"; +public interface BatchManagerTestAsyncClient extends SdkClient { + String SERVICE_NAME = "batchmanagertest"; /** * Value for looking up the service's metadata from the * {@link software.amazon.awssdk.regions.ServiceMetadataProvider}. */ - String SERVICE_METADATA_ID = "batchmanager"; + String SERVICE_METADATA_ID = "batchmanagertest"; /** - * Create a {@link BatchManagerAsyncClient} with the region loaded from the + * Create a {@link BatchManagerTestAsyncClient} with the region loaded from the * {@link software.amazon.awssdk.regions.providers.DefaultAwsRegionProviderChain} and credentials loaded from the * {@link software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider}. */ - static BatchManagerAsyncClient create() { + static BatchManagerTestAsyncClient create() { return builder().build(); } /** - * Create a builder that can be used to configure and create a {@link BatchManagerAsyncClient}. + * Create a builder that can be used to configure and create a {@link BatchManagerTestAsyncClient}. */ - static BatchManagerAsyncClientBuilder builder() { - return new DefaultBatchManagerAsyncClientBuilder(); + static BatchManagerTestAsyncClientBuilder builder() { + return new DefaultBatchManagerTestAsyncClientBuilder(); } /** - * Creates an instance of {@link AsyncBatchManagerTest} object with the configuration set on this client. + * Invokes the DeleteRequest operation asynchronously. + * + * @param deleteRequestRequest + * @return A Java Future containing the result of the DeleteRequest operation returned by the service.
+ * The CompletableFuture returned by this method can be completed exceptionally with the following + * exceptions. + *
    + *
  • SdkException Base class for all exceptions that can be thrown by the SDK (both service and client). + * Can be used for catch all scenarios.
  • + *
  • SdkClientException If any client side error occurs such as an IO related failure, failure to get + * credentials, etc.
  • + *
  • BatchManagerTestException Base class for all service exceptions. Unknown exceptions will be thrown as + * an instance of this type.
  • + *
+ * @sample BatchManagerTestAsyncClient.DeleteRequest + * @see AWS API Documentation */ - default AsyncBatchManagerTest batchManager() { + default CompletableFuture deleteRequest(DeleteRequestRequest deleteRequestRequest) { + throw new UnsupportedOperationException(); + } + + /** + * Invokes the DeleteRequest operation asynchronously.
+ *

+ * This is a convenience which creates an instance of the {@link DeleteRequestRequest.Builder} avoiding the need to + * create one manually via {@link DeleteRequestRequest#builder()} + *

+ * + * @param deleteRequestRequest + * A {@link Consumer} that will call methods on {@link DeleteRequestRequest.Builder} to create a request. + * @return A Java Future containing the result of the DeleteRequest operation returned by the service.
+ * The CompletableFuture returned by this method can be completed exceptionally with the following + * exceptions. + *
    + *
  • SdkException Base class for all exceptions that can be thrown by the SDK (both service and client). + * Can be used for catch all scenarios.
  • + *
  • SdkClientException If any client side error occurs such as an IO related failure, failure to get + * credentials, etc.
  • + *
  • BatchManagerTestException Base class for all service exceptions. Unknown exceptions will be thrown as + * an instance of this type.
  • + *
+ * @sample BatchManagerTestAsyncClient.DeleteRequest + * @see AWS API Documentation + */ + default CompletableFuture deleteRequest(Consumer deleteRequestRequest) { + return deleteRequest(DeleteRequestRequest.builder().applyMutation(deleteRequestRequest).build()); + } + + /** + * Invokes the DeleteRequestBatch operation asynchronously. + * + * @param deleteRequestBatchRequest + * @return A Java Future containing the result of the DeleteRequestBatch operation returned by the service.
+ * The CompletableFuture returned by this method can be completed exceptionally with the following + * exceptions. + *
    + *
  • SdkException Base class for all exceptions that can be thrown by the SDK (both service and client). + * Can be used for catch all scenarios.
  • + *
  • SdkClientException If any client side error occurs such as an IO related failure, failure to get + * credentials, etc.
  • + *
  • BatchManagerTestException Base class for all service exceptions. Unknown exceptions will be thrown as + * an instance of this type.
  • + *
+ * @sample BatchManagerTestAsyncClient.DeleteRequestBatch + * @see AWS API Documentation + */ + default CompletableFuture deleteRequestBatch(DeleteRequestBatchRequest deleteRequestBatchRequest) { + throw new UnsupportedOperationException(); + } + + /** + * Invokes the DeleteRequestBatch operation asynchronously.
+ *

+ * This is a convenience which creates an instance of the {@link DeleteRequestBatchRequest.Builder} avoiding the + * need to create one manually via {@link DeleteRequestBatchRequest#builder()} + *

+ * + * @param deleteRequestBatchRequest + * A {@link Consumer} that will call methods on {@link DeleteRequestBatchRequest.Builder} to create a + * request. + * @return A Java Future containing the result of the DeleteRequestBatch operation returned by the service.
+ * The CompletableFuture returned by this method can be completed exceptionally with the following + * exceptions. + *
    + *
  • SdkException Base class for all exceptions that can be thrown by the SDK (both service and client). + * Can be used for catch all scenarios.
  • + *
  • SdkClientException If any client side error occurs such as an IO related failure, failure to get + * credentials, etc.
  • + *
  • BatchManagerTestException Base class for all service exceptions. Unknown exceptions will be thrown as + * an instance of this type.
  • + *
+ * @sample BatchManagerTestAsyncClient.DeleteRequestBatch + * @see AWS API Documentation + */ + default CompletableFuture deleteRequestBatch( + Consumer deleteRequestBatchRequest) { + return deleteRequestBatch(DeleteRequestBatchRequest.builder().applyMutation(deleteRequestBatchRequest).build()); + } + + /** + * Invokes the SendRequest operation asynchronously. + * + * @param sendRequestRequest + * @return A Java Future containing the result of the SendRequest operation returned by the service.
+ * The CompletableFuture returned by this method can be completed exceptionally with the following + * exceptions. + *
    + *
  • SdkException Base class for all exceptions that can be thrown by the SDK (both service and client). + * Can be used for catch all scenarios.
  • + *
  • SdkClientException If any client side error occurs such as an IO related failure, failure to get + * credentials, etc.
  • + *
  • BatchManagerTestException Base class for all service exceptions. Unknown exceptions will be thrown as + * an instance of this type.
  • + *
+ * @sample BatchManagerTestAsyncClient.SendRequest + * @see AWS + * API Documentation + */ + default CompletableFuture sendRequest(SendRequestRequest sendRequestRequest) { + throw new UnsupportedOperationException(); + } + + /** + * Invokes the SendRequest operation asynchronously.
+ *

+ * This is a convenience which creates an instance of the {@link SendRequestRequest.Builder} avoiding the need to + * create one manually via {@link SendRequestRequest#builder()} + *

+ * + * @param sendRequestRequest + * A {@link Consumer} that will call methods on {@link SendRequestRequest.Builder} to create a request. + * @return A Java Future containing the result of the SendRequest operation returned by the service.
+ * The CompletableFuture returned by this method can be completed exceptionally with the following + * exceptions. + *
    + *
  • SdkException Base class for all exceptions that can be thrown by the SDK (both service and client). + * Can be used for catch all scenarios.
  • + *
  • SdkClientException If any client side error occurs such as an IO related failure, failure to get + * credentials, etc.
  • + *
  • BatchManagerTestException Base class for all service exceptions. Unknown exceptions will be thrown as + * an instance of this type.
  • + *
+ * @sample BatchManagerTestAsyncClient.SendRequest + * @see AWS + * API Documentation + */ + default CompletableFuture sendRequest(Consumer sendRequestRequest) { + return sendRequest(SendRequestRequest.builder().applyMutation(sendRequestRequest).build()); + } + + /** + * Invokes the SendRequestBatch operation asynchronously. + * + * @param sendRequestBatchRequest + * @return A Java Future containing the result of the SendRequestBatch operation returned by the service.
+ * The CompletableFuture returned by this method can be completed exceptionally with the following + * exceptions. + *
    + *
  • SdkException Base class for all exceptions that can be thrown by the SDK (both service and client). + * Can be used for catch all scenarios.
  • + *
  • SdkClientException If any client side error occurs such as an IO related failure, failure to get + * credentials, etc.
  • + *
  • BatchManagerTestException Base class for all service exceptions. Unknown exceptions will be thrown as + * an instance of this type.
  • + *
+ * @sample BatchManagerTestAsyncClient.SendRequestBatch + * @see AWS API Documentation + */ + default CompletableFuture sendRequestBatch(SendRequestBatchRequest sendRequestBatchRequest) { + throw new UnsupportedOperationException(); + } + + /** + * Invokes the SendRequestBatch operation asynchronously.
+ *

+ * This is a convenience which creates an instance of the {@link SendRequestBatchRequest.Builder} avoiding the need + * to create one manually via {@link SendRequestBatchRequest#builder()} + *

+ * + * @param sendRequestBatchRequest + * A {@link Consumer} that will call methods on {@link SendRequestBatchRequest.Builder} to create a request. + * @return A Java Future containing the result of the SendRequestBatch operation returned by the service.
+ * The CompletableFuture returned by this method can be completed exceptionally with the following + * exceptions. + *
    + *
  • SdkException Base class for all exceptions that can be thrown by the SDK (both service and client). + * Can be used for catch all scenarios.
  • + *
  • SdkClientException If any client side error occurs such as an IO related failure, failure to get + * credentials, etc.
  • + *
  • BatchManagerTestException Base class for all service exceptions. Unknown exceptions will be thrown as + * an instance of this type.
  • + *
+ * @sample BatchManagerTestAsyncClient.SendRequestBatch + * @see AWS API Documentation + */ + default CompletableFuture sendRequestBatch( + Consumer sendRequestBatchRequest) { + return sendRequestBatch(SendRequestBatchRequest.builder().applyMutation(sendRequestBatchRequest).build()); + } + + /** + * Creates an instance of {@link BatchManagerTestAsyncBatchManager} object with the configuration set on this + * client. + */ + default BatchManagerTestAsyncBatchManager batchManager() { throw new UnsupportedOperationException(); } } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-batchmanager-sync-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-batchmanager-sync-class.java index 3508b951a912..49d410cc9856 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-batchmanager-sync-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-batchmanager-sync-class.java @@ -1,4 +1,4 @@ -package software.amazon.awssdk.services.batchmanager; +package software.amazon.awssdk.services.batchmanagertest; import java.util.Collections; import java.util.List; @@ -10,26 +10,43 @@ import software.amazon.awssdk.core.RequestOverrideConfiguration; import software.amazon.awssdk.core.client.config.SdkClientConfiguration; import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.client.handler.SyncClientHandler; +import software.amazon.awssdk.core.exception.SdkClientException; import software.amazon.awssdk.core.http.HttpResponseHandler; +import software.amazon.awssdk.core.metrics.CoreMetric; +import software.amazon.awssdk.metrics.MetricCollector; import software.amazon.awssdk.metrics.MetricPublisher; +import software.amazon.awssdk.metrics.NoOpMetricCollector; import software.amazon.awssdk.protocols.json.AwsJsonProtocol; import software.amazon.awssdk.protocols.json.AwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.BaseAwsJsonProtocolFactory; import software.amazon.awssdk.protocols.json.JsonOperationMetadata; -import software.amazon.awssdk.services.batchmanager.model.BatchManagerException; -import software.amazon.awssdk.services.batchmanagertest.batchmanager.SyncBatchManagerTest; +import software.amazon.awssdk.services.batchmanagertest.batchmanager.BatchManagerTestBatchManager; +import software.amazon.awssdk.services.batchmanagertest.model.BatchManagerTestException; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestBatchRequest; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestBatchResponse; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestRequest; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestResponse; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestBatchRequest; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestBatchResponse; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestRequest; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestResponse; +import software.amazon.awssdk.services.batchmanagertest.transform.DeleteRequestBatchRequestMarshaller; +import software.amazon.awssdk.services.batchmanagertest.transform.DeleteRequestRequestMarshaller; +import software.amazon.awssdk.services.batchmanagertest.transform.SendRequestBatchRequestMarshaller; +import software.amazon.awssdk.services.batchmanagertest.transform.SendRequestRequestMarshaller; import software.amazon.awssdk.utils.Logger; /** - * Internal implementation of {@link BatchManagerClient}. + * Internal implementation of {@link BatchManagerTestClient}. * - * @see BatchManagerClient#builder() + * @see BatchManagerTestClient#builder() */ @Generated("software.amazon.awssdk:codegen") @SdkInternalApi -final class DefaultBatchManagerClient implements BatchManagerClient { - private static final Logger log = Logger.loggerFor(DefaultBatchManagerClient.class); +final class DefaultBatchManagerTestClient implements BatchManagerTestClient { + private static final Logger log = Logger.loggerFor(DefaultBatchManagerTestClient.class); private final SyncClientHandler clientHandler; @@ -39,7 +56,7 @@ final class DefaultBatchManagerClient implements BatchManagerClient { private final ScheduledExecutorService executorService; - protected DefaultBatchManagerClient(SdkClientConfiguration clientConfiguration) { + protected DefaultBatchManagerTestClient(SdkClientConfiguration clientConfiguration) { this.clientHandler = new AwsSyncClientHandler(clientConfiguration); this.clientConfiguration = clientConfiguration; this.protocolFactory = init(AwsJsonProtocolFactory.builder()).build(); @@ -51,6 +68,186 @@ public final String serviceName() { return SERVICE_NAME; } + /** + * Invokes the DeleteRequest operation. + * + * @param deleteRequestRequest + * @return Result of the DeleteRequest operation returned by the service. + * @throws SdkException + * Base class for all exceptions that can be thrown by the SDK (both service and client). Can be used for + * catch all scenarios. + * @throws SdkClientException + * If any client side error occurs such as an IO related failure, failure to get credentials, etc. + * @throws BatchManagerTestException + * Base class for all service exceptions. Unknown exceptions will be thrown as an instance of this type. + * @sample BatchManagerTestClient.DeleteRequest + * @see AWS API Documentation + */ + @Override + public DeleteRequestResponse deleteRequest(DeleteRequestRequest deleteRequestRequest) throws AwsServiceException, + SdkClientException, BatchManagerTestException { + JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) + .isPayloadJson(true).build(); + + HttpResponseHandler responseHandler = protocolFactory.createResponseHandler(operationMetadata, + DeleteRequestResponse::builder); + + HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, + operationMetadata); + List metricPublishers = resolveMetricPublishers(clientConfiguration, deleteRequestRequest + .overrideConfiguration().orElse(null)); + MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector + .create("ApiCall"); + try { + apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "BatchManagerTest"); + apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "DeleteRequest"); + + return clientHandler.execute(new ClientExecutionParams() + .withOperationName("DeleteRequest").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withInput(deleteRequestRequest) + .withMetricCollector(apiCallMetricCollector) + .withMarshaller(new DeleteRequestRequestMarshaller(protocolFactory))); + } finally { + metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); + } + } + + /** + * Invokes the DeleteRequestBatch operation. + * + * @param deleteRequestBatchRequest + * @return Result of the DeleteRequestBatch operation returned by the service. + * @throws SdkException + * Base class for all exceptions that can be thrown by the SDK (both service and client). Can be used for + * catch all scenarios. + * @throws SdkClientException + * If any client side error occurs such as an IO related failure, failure to get credentials, etc. + * @throws BatchManagerTestException + * Base class for all service exceptions. Unknown exceptions will be thrown as an instance of this type. + * @sample BatchManagerTestClient.DeleteRequestBatch + * @see AWS API Documentation + */ + @Override + public DeleteRequestBatchResponse deleteRequestBatch(DeleteRequestBatchRequest deleteRequestBatchRequest) + throws AwsServiceException, SdkClientException, BatchManagerTestException { + JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) + .isPayloadJson(true).build(); + + HttpResponseHandler responseHandler = protocolFactory.createResponseHandler( + operationMetadata, DeleteRequestBatchResponse::builder); + + HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, + operationMetadata); + List metricPublishers = resolveMetricPublishers(clientConfiguration, deleteRequestBatchRequest + .overrideConfiguration().orElse(null)); + MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector + .create("ApiCall"); + try { + apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "BatchManagerTest"); + apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "DeleteRequestBatch"); + + return clientHandler.execute(new ClientExecutionParams() + .withOperationName("DeleteRequestBatch").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withInput(deleteRequestBatchRequest) + .withMetricCollector(apiCallMetricCollector) + .withMarshaller(new DeleteRequestBatchRequestMarshaller(protocolFactory))); + } finally { + metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); + } + } + + /** + * Invokes the SendRequest operation. + * + * @param sendRequestRequest + * @return Result of the SendRequest operation returned by the service. + * @throws SdkException + * Base class for all exceptions that can be thrown by the SDK (both service and client). Can be used for + * catch all scenarios. + * @throws SdkClientException + * If any client side error occurs such as an IO related failure, failure to get credentials, etc. + * @throws BatchManagerTestException + * Base class for all service exceptions. Unknown exceptions will be thrown as an instance of this type. + * @sample BatchManagerTestClient.SendRequest + * @see AWS + * API Documentation + */ + @Override + public SendRequestResponse sendRequest(SendRequestRequest sendRequestRequest) throws AwsServiceException, SdkClientException, + BatchManagerTestException { + JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) + .isPayloadJson(true).build(); + + HttpResponseHandler responseHandler = protocolFactory.createResponseHandler(operationMetadata, + SendRequestResponse::builder); + + HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, + operationMetadata); + List metricPublishers = resolveMetricPublishers(clientConfiguration, sendRequestRequest + .overrideConfiguration().orElse(null)); + MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector + .create("ApiCall"); + try { + apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "BatchManagerTest"); + apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "SendRequest"); + + return clientHandler.execute(new ClientExecutionParams() + .withOperationName("SendRequest").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withInput(sendRequestRequest) + .withMetricCollector(apiCallMetricCollector) + .withMarshaller(new SendRequestRequestMarshaller(protocolFactory))); + } finally { + metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); + } + } + + /** + * Invokes the SendRequestBatch operation. + * + * @param sendRequestBatchRequest + * @return Result of the SendRequestBatch operation returned by the service. + * @throws SdkException + * Base class for all exceptions that can be thrown by the SDK (both service and client). Can be used for + * catch all scenarios. + * @throws SdkClientException + * If any client side error occurs such as an IO related failure, failure to get credentials, etc. + * @throws BatchManagerTestException + * Base class for all service exceptions. Unknown exceptions will be thrown as an instance of this type. + * @sample BatchManagerTestClient.SendRequestBatch + * @see AWS API Documentation + */ + @Override + public SendRequestBatchResponse sendRequestBatch(SendRequestBatchRequest sendRequestBatchRequest) throws AwsServiceException, + SdkClientException, BatchManagerTestException { + JsonOperationMetadata operationMetadata = JsonOperationMetadata.builder().hasStreamingSuccessResponse(false) + .isPayloadJson(true).build(); + + HttpResponseHandler responseHandler = protocolFactory.createResponseHandler(operationMetadata, + SendRequestBatchResponse::builder); + + HttpResponseHandler errorResponseHandler = createErrorResponseHandler(protocolFactory, + operationMetadata); + List metricPublishers = resolveMetricPublishers(clientConfiguration, sendRequestBatchRequest + .overrideConfiguration().orElse(null)); + MetricCollector apiCallMetricCollector = metricPublishers.isEmpty() ? NoOpMetricCollector.create() : MetricCollector + .create("ApiCall"); + try { + apiCallMetricCollector.reportMetric(CoreMetric.SERVICE_ID, "BatchManagerTest"); + apiCallMetricCollector.reportMetric(CoreMetric.OPERATION_NAME, "SendRequestBatch"); + + return clientHandler.execute(new ClientExecutionParams() + .withOperationName("SendRequestBatch").withResponseHandler(responseHandler) + .withErrorResponseHandler(errorResponseHandler).withInput(sendRequestBatchRequest) + .withMetricCollector(apiCallMetricCollector) + .withMarshaller(new SendRequestBatchRequestMarshaller(protocolFactory))); + } finally { + metricPublishers.forEach(p -> p.publish(apiCallMetricCollector.collect())); + } + } + private static List resolveMetricPublishers(SdkClientConfiguration clientConfiguration, RequestOverrideConfiguration requestOverrideConfiguration) { List publishers = null; @@ -72,8 +269,9 @@ private HttpResponseHandler createErrorResponseHandler(Base } private > T init(T builder) { - return builder.clientConfiguration(clientConfiguration).defaultServiceExceptionSupplier(BatchManagerException::builder) - .protocol(AwsJsonProtocol.REST_JSON).protocolVersion("1.1"); + return builder.clientConfiguration(clientConfiguration) + .defaultServiceExceptionSupplier(BatchManagerTestException::builder).protocol(AwsJsonProtocol.REST_JSON) + .protocolVersion("1.1"); } @Override @@ -82,7 +280,7 @@ public void close() { } @Override - public SyncBatchManagerTest batchManager() { - return SyncBatchManagerTest.builder().client(this).scheduledExecutor(executorService).build(); + public BatchManagerTestBatchManager batchManager() { + return BatchManagerTestBatchManager.builder().client(this).scheduledExecutor(executorService).build(); } } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-batchmanager-sync-interface.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-batchmanager-sync-interface.java index 74ff3fd95f04..d6498da232f9 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-batchmanager-sync-interface.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-batchmanager-sync-interface.java @@ -1,43 +1,244 @@ -package software.amazon.awssdk.services.batchmanager; +package software.amazon.awssdk.services.batchmanagertest; +import java.util.function.Consumer; import software.amazon.awssdk.annotations.Generated; import software.amazon.awssdk.annotations.SdkPublicApi; import software.amazon.awssdk.annotations.ThreadSafe; +import software.amazon.awssdk.awscore.exception.AwsServiceException; import software.amazon.awssdk.core.SdkClient; +import software.amazon.awssdk.core.exception.SdkClientException; import software.amazon.awssdk.regions.ServiceMetadata; -import software.amazon.awssdk.services.batchmanagertest.batchmanager.SyncBatchManagerTest; +import software.amazon.awssdk.services.batchmanagertest.batchmanager.BatchManagerTestBatchManager; +import software.amazon.awssdk.services.batchmanagertest.model.BatchManagerTestException; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestBatchRequest; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestBatchResponse; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestRequest; +import software.amazon.awssdk.services.batchmanagertest.model.DeleteRequestResponse; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestBatchRequest; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestBatchResponse; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestRequest; +import software.amazon.awssdk.services.batchmanagertest.model.SendRequestResponse; /** - * Service client for accessing BatchManager. This can be created using the static {@link #builder()} method. + * Service client for accessing BatchManagerTest. This can be created using the static {@link #builder()} method. * * A service that implements the batchManager() method */ @Generated("software.amazon.awssdk:codegen") @SdkPublicApi @ThreadSafe -public interface BatchManagerClient extends SdkClient { - String SERVICE_NAME = "batchmanager"; +public interface BatchManagerTestClient extends SdkClient { + String SERVICE_NAME = "batchmanagertest"; /** * Value for looking up the service's metadata from the * {@link software.amazon.awssdk.regions.ServiceMetadataProvider}. */ - String SERVICE_METADATA_ID = "batchmanager"; + String SERVICE_METADATA_ID = "batchmanagertest"; /** - * Create a {@link BatchManagerClient} with the region loaded from the + * Create a {@link BatchManagerTestClient} with the region loaded from the * {@link software.amazon.awssdk.regions.providers.DefaultAwsRegionProviderChain} and credentials loaded from the * {@link software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider}. */ - static BatchManagerClient create() { + static BatchManagerTestClient create() { return builder().build(); } /** - * Create a builder that can be used to configure and create a {@link BatchManagerClient}. + * Create a builder that can be used to configure and create a {@link BatchManagerTestClient}. */ - static BatchManagerClientBuilder builder() { - return new DefaultBatchManagerClientBuilder(); + static BatchManagerTestClientBuilder builder() { + return new DefaultBatchManagerTestClientBuilder(); + } + + /** + * Invokes the DeleteRequest operation. + * + * @param deleteRequestRequest + * @return Result of the DeleteRequest operation returned by the service. + * @throws SdkException + * Base class for all exceptions that can be thrown by the SDK (both service and client). Can be used for + * catch all scenarios. + * @throws SdkClientException + * If any client side error occurs such as an IO related failure, failure to get credentials, etc. + * @throws BatchManagerTestException + * Base class for all service exceptions. Unknown exceptions will be thrown as an instance of this type. + * @sample BatchManagerTestClient.DeleteRequest + * @see AWS API Documentation + */ + default DeleteRequestResponse deleteRequest(DeleteRequestRequest deleteRequestRequest) throws AwsServiceException, + SdkClientException, BatchManagerTestException { + throw new UnsupportedOperationException(); + } + + /** + * Invokes the DeleteRequest operation.
+ *

+ * This is a convenience which creates an instance of the {@link DeleteRequestRequest.Builder} avoiding the need to + * create one manually via {@link DeleteRequestRequest#builder()} + *

+ * + * @param deleteRequestRequest + * A {@link Consumer} that will call methods on {@link DeleteRequestRequest.Builder} to create a request. + * @return Result of the DeleteRequest operation returned by the service. + * @throws SdkException + * Base class for all exceptions that can be thrown by the SDK (both service and client). Can be used for + * catch all scenarios. + * @throws SdkClientException + * If any client side error occurs such as an IO related failure, failure to get credentials, etc. + * @throws BatchManagerTestException + * Base class for all service exceptions. Unknown exceptions will be thrown as an instance of this type. + * @sample BatchManagerTestClient.DeleteRequest + * @see AWS API Documentation + */ + default DeleteRequestResponse deleteRequest(Consumer deleteRequestRequest) + throws AwsServiceException, SdkClientException, BatchManagerTestException { + return deleteRequest(DeleteRequestRequest.builder().applyMutation(deleteRequestRequest).build()); + } + + /** + * Invokes the DeleteRequestBatch operation. + * + * @param deleteRequestBatchRequest + * @return Result of the DeleteRequestBatch operation returned by the service. + * @throws SdkException + * Base class for all exceptions that can be thrown by the SDK (both service and client). Can be used for + * catch all scenarios. + * @throws SdkClientException + * If any client side error occurs such as an IO related failure, failure to get credentials, etc. + * @throws BatchManagerTestException + * Base class for all service exceptions. Unknown exceptions will be thrown as an instance of this type. + * @sample BatchManagerTestClient.DeleteRequestBatch + * @see AWS API Documentation + */ + default DeleteRequestBatchResponse deleteRequestBatch(DeleteRequestBatchRequest deleteRequestBatchRequest) + throws AwsServiceException, SdkClientException, BatchManagerTestException { + throw new UnsupportedOperationException(); + } + + /** + * Invokes the DeleteRequestBatch operation.
+ *

+ * This is a convenience which creates an instance of the {@link DeleteRequestBatchRequest.Builder} avoiding the + * need to create one manually via {@link DeleteRequestBatchRequest#builder()} + *

+ * + * @param deleteRequestBatchRequest + * A {@link Consumer} that will call methods on {@link DeleteRequestBatchRequest.Builder} to create a + * request. + * @return Result of the DeleteRequestBatch operation returned by the service. + * @throws SdkException + * Base class for all exceptions that can be thrown by the SDK (both service and client). Can be used for + * catch all scenarios. + * @throws SdkClientException + * If any client side error occurs such as an IO related failure, failure to get credentials, etc. + * @throws BatchManagerTestException + * Base class for all service exceptions. Unknown exceptions will be thrown as an instance of this type. + * @sample BatchManagerTestClient.DeleteRequestBatch + * @see AWS API Documentation + */ + default DeleteRequestBatchResponse deleteRequestBatch(Consumer deleteRequestBatchRequest) + throws AwsServiceException, SdkClientException, BatchManagerTestException { + return deleteRequestBatch(DeleteRequestBatchRequest.builder().applyMutation(deleteRequestBatchRequest).build()); + } + + /** + * Invokes the SendRequest operation. + * + * @param sendRequestRequest + * @return Result of the SendRequest operation returned by the service. + * @throws SdkException + * Base class for all exceptions that can be thrown by the SDK (both service and client). Can be used for + * catch all scenarios. + * @throws SdkClientException + * If any client side error occurs such as an IO related failure, failure to get credentials, etc. + * @throws BatchManagerTestException + * Base class for all service exceptions. Unknown exceptions will be thrown as an instance of this type. + * @sample BatchManagerTestClient.SendRequest + * @see AWS + * API Documentation + */ + default SendRequestResponse sendRequest(SendRequestRequest sendRequestRequest) throws AwsServiceException, + SdkClientException, BatchManagerTestException { + throw new UnsupportedOperationException(); + } + + /** + * Invokes the SendRequest operation.
+ *

+ * This is a convenience which creates an instance of the {@link SendRequestRequest.Builder} avoiding the need to + * create one manually via {@link SendRequestRequest#builder()} + *

+ * + * @param sendRequestRequest + * A {@link Consumer} that will call methods on {@link SendRequestRequest.Builder} to create a request. + * @return Result of the SendRequest operation returned by the service. + * @throws SdkException + * Base class for all exceptions that can be thrown by the SDK (both service and client). Can be used for + * catch all scenarios. + * @throws SdkClientException + * If any client side error occurs such as an IO related failure, failure to get credentials, etc. + * @throws BatchManagerTestException + * Base class for all service exceptions. Unknown exceptions will be thrown as an instance of this type. + * @sample BatchManagerTestClient.SendRequest + * @see AWS + * API Documentation + */ + default SendRequestResponse sendRequest(Consumer sendRequestRequest) throws AwsServiceException, + SdkClientException, BatchManagerTestException { + return sendRequest(SendRequestRequest.builder().applyMutation(sendRequestRequest).build()); + } + + /** + * Invokes the SendRequestBatch operation. + * + * @param sendRequestBatchRequest + * @return Result of the SendRequestBatch operation returned by the service. + * @throws SdkException + * Base class for all exceptions that can be thrown by the SDK (both service and client). Can be used for + * catch all scenarios. + * @throws SdkClientException + * If any client side error occurs such as an IO related failure, failure to get credentials, etc. + * @throws BatchManagerTestException + * Base class for all service exceptions. Unknown exceptions will be thrown as an instance of this type. + * @sample BatchManagerTestClient.SendRequestBatch + * @see AWS API Documentation + */ + default SendRequestBatchResponse sendRequestBatch(SendRequestBatchRequest sendRequestBatchRequest) + throws AwsServiceException, SdkClientException, BatchManagerTestException { + throw new UnsupportedOperationException(); + } + + /** + * Invokes the SendRequestBatch operation.
+ *

+ * This is a convenience which creates an instance of the {@link SendRequestBatchRequest.Builder} avoiding the need + * to create one manually via {@link SendRequestBatchRequest#builder()} + *

+ * + * @param sendRequestBatchRequest + * A {@link Consumer} that will call methods on {@link SendRequestBatchRequest.Builder} to create a request. + * @return Result of the SendRequestBatch operation returned by the service. + * @throws SdkException + * Base class for all exceptions that can be thrown by the SDK (both service and client). Can be used for + * catch all scenarios. + * @throws SdkClientException + * If any client side error occurs such as an IO related failure, failure to get credentials, etc. + * @throws BatchManagerTestException + * Base class for all service exceptions. Unknown exceptions will be thrown as an instance of this type. + * @sample BatchManagerTestClient.SendRequestBatch + * @see AWS API Documentation + */ + default SendRequestBatchResponse sendRequestBatch(Consumer sendRequestBatchRequest) + throws AwsServiceException, SdkClientException, BatchManagerTestException { + return sendRequestBatch(SendRequestBatchRequest.builder().applyMutation(sendRequestBatchRequest).build()); } static ServiceMetadata serviceMetadata() { @@ -45,9 +246,9 @@ static ServiceMetadata serviceMetadata() { } /** - * Creates an instance of {@link SyncBatchManagerTest} object with the configuration set on this client. + * Creates an instance of {@link BatchManagerTestBatchManager} object with the configuration set on this client. */ - default SyncBatchManagerTest batchManager() { + default BatchManagerTestBatchManager batchManager() { throw new UnsupportedOperationException(); } } diff --git a/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/batchmanager/SqsAsyncBatchManager.java b/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/batchmanager/SqsAsyncBatchManager.java index ec175752ac99..6d6e82df4755 100644 --- a/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/batchmanager/SqsAsyncBatchManager.java +++ b/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/batchmanager/SqsAsyncBatchManager.java @@ -20,7 +20,7 @@ import software.amazon.awssdk.annotations.SdkPublicApi; import software.amazon.awssdk.core.batchmanager.BatchOverrideConfiguration; import software.amazon.awssdk.services.sqs.SqsAsyncClient; -import software.amazon.awssdk.services.sqs.internal.batchmanager.DefaultSqsAsyncBatchManager; +import software.amazon.awssdk.services.sqs.batchmanager.internal.DefaultSqsAsyncBatchManager; import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityRequest; import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityResponse; import software.amazon.awssdk.services.sqs.model.DeleteMessageRequest; diff --git a/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/batchmanager/SqsBatchManager.java b/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/batchmanager/SqsBatchManager.java index 559615dfd842..ee53f07a997d 100644 --- a/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/batchmanager/SqsBatchManager.java +++ b/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/batchmanager/SqsBatchManager.java @@ -21,7 +21,7 @@ import software.amazon.awssdk.annotations.SdkPublicApi; import software.amazon.awssdk.core.batchmanager.BatchOverrideConfiguration; import software.amazon.awssdk.services.sqs.SqsClient; -import software.amazon.awssdk.services.sqs.internal.batchmanager.DefaultSqsBatchManager; +import software.amazon.awssdk.services.sqs.batchmanager.internal.DefaultSqsBatchManager; import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityRequest; import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityResponse; import software.amazon.awssdk.services.sqs.model.DeleteMessageRequest; diff --git a/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/internal/batchmanager/DefaultSqsAsyncBatchManager.java b/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/batchmanager/internal/DefaultSqsAsyncBatchManager.java similarity index 86% rename from services/sqs/src/main/java/software/amazon/awssdk/services/sqs/internal/batchmanager/DefaultSqsAsyncBatchManager.java rename to services/sqs/src/main/java/software/amazon/awssdk/services/sqs/batchmanager/internal/DefaultSqsAsyncBatchManager.java index a18beb9641c7..d5dce5713499 100644 --- a/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/internal/batchmanager/DefaultSqsAsyncBatchManager.java +++ b/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/batchmanager/internal/DefaultSqsAsyncBatchManager.java @@ -13,17 +13,17 @@ * permissions and limitations under the License. */ -package software.amazon.awssdk.services.sqs.internal.batchmanager; - -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.changeVisibilityBatchAsyncFunction; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.changeVisibilityBatchKeyMapper; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.changeVisibilityResponseMapper; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.deleteMessageBatchAsyncFunction; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.deleteMessageBatchKeyMapper; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.deleteMessageResponseMapper; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.sendMessageBatchAsyncFunction; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.sendMessageBatchKeyMapper; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.sendMessageResponseMapper; +package software.amazon.awssdk.services.sqs.batchmanager.internal; + +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.changeMessageVisibilityBatchAsyncFunction; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.changeMessageVisibilityBatchKeyMapper; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.changeMessageVisibilityResponseMapper; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.deleteMessageBatchAsyncFunction; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.deleteMessageBatchKeyMapper; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.deleteMessageResponseMapper; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.sendMessageBatchAsyncFunction; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.sendMessageBatchKeyMapper; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.sendMessageResponseMapper; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ScheduledExecutorService; @@ -82,9 +82,9 @@ private DefaultSqsAsyncBatchManager(DefaultBuilder builder) { this.changeVisibilityBatchManager = BatchManager.builder(ChangeMessageVisibilityRequest.class, ChangeMessageVisibilityResponse.class, ChangeMessageVisibilityBatchResponse.class) - .batchFunction(changeVisibilityBatchAsyncFunction(client)) - .responseMapper(changeVisibilityResponseMapper()) - .batchKeyMapper(changeVisibilityBatchKeyMapper()) + .batchFunction(changeMessageVisibilityBatchAsyncFunction(client)) + .responseMapper(changeMessageVisibilityResponseMapper()) + .batchKeyMapper(changeMessageVisibilityBatchKeyMapper()) .overrideConfiguration(overrideConfiguration) .scheduledExecutor(scheduledExecutor) .build(); diff --git a/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/internal/batchmanager/DefaultSqsBatchManager.java b/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/batchmanager/internal/DefaultSqsBatchManager.java similarity index 88% rename from services/sqs/src/main/java/software/amazon/awssdk/services/sqs/internal/batchmanager/DefaultSqsBatchManager.java rename to services/sqs/src/main/java/software/amazon/awssdk/services/sqs/batchmanager/internal/DefaultSqsBatchManager.java index 69aa6ed2523a..87c99477c1ba 100644 --- a/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/internal/batchmanager/DefaultSqsBatchManager.java +++ b/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/batchmanager/internal/DefaultSqsBatchManager.java @@ -13,17 +13,17 @@ * permissions and limitations under the License. */ -package software.amazon.awssdk.services.sqs.internal.batchmanager; - -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.changeVisibilityBatchFunction; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.changeVisibilityBatchKeyMapper; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.changeVisibilityResponseMapper; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.deleteMessageBatchFunction; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.deleteMessageBatchKeyMapper; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.deleteMessageResponseMapper; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.sendMessageBatchFunction; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.sendMessageBatchKeyMapper; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.sendMessageResponseMapper; +package software.amazon.awssdk.services.sqs.batchmanager.internal; + +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.changeMessageVisibilityBatchFunction; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.changeMessageVisibilityBatchKeyMapper; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.changeMessageVisibilityResponseMapper; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.deleteMessageBatchFunction; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.deleteMessageBatchKeyMapper; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.deleteMessageResponseMapper; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.sendMessageBatchFunction; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.sendMessageBatchKeyMapper; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.sendMessageResponseMapper; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; @@ -97,9 +97,9 @@ private DefaultSqsBatchManager(DefaultBuilder builder) { this.changeVisibilityBatchManager = BatchManager.builder(ChangeMessageVisibilityRequest.class, ChangeMessageVisibilityResponse.class, ChangeMessageVisibilityBatchResponse.class) - .batchFunction(changeVisibilityBatchFunction(client, executor)) - .responseMapper(changeVisibilityResponseMapper()) - .batchKeyMapper(changeVisibilityBatchKeyMapper()) + .batchFunction(changeMessageVisibilityBatchFunction(client, executor)) + .responseMapper(changeMessageVisibilityResponseMapper()) + .batchKeyMapper(changeMessageVisibilityBatchKeyMapper()) .overrideConfiguration(overrideConfiguration) .scheduledExecutor(scheduledExecutor) .build(); diff --git a/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/internal/batchmanager/SqsBatchConfiguration.java b/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/batchmanager/internal/SqsBatchConfiguration.java similarity index 96% rename from services/sqs/src/main/java/software/amazon/awssdk/services/sqs/internal/batchmanager/SqsBatchConfiguration.java rename to services/sqs/src/main/java/software/amazon/awssdk/services/sqs/batchmanager/internal/SqsBatchConfiguration.java index c0b8e7ae07cb..5b755e336a37 100644 --- a/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/internal/batchmanager/SqsBatchConfiguration.java +++ b/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/batchmanager/internal/SqsBatchConfiguration.java @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -package software.amazon.awssdk.services.sqs.internal.batchmanager; +package software.amazon.awssdk.services.sqs.batchmanager.internal; import java.time.Duration; import software.amazon.awssdk.annotations.SdkInternalApi; diff --git a/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/internal/batchmanager/SqsBatchFunctions.java b/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/internal/batchmanager/SqsBatchFunctions.java deleted file mode 100644 index a323044e7447..000000000000 --- a/services/sqs/src/main/java/software/amazon/awssdk/services/sqs/internal/batchmanager/SqsBatchFunctions.java +++ /dev/null @@ -1,344 +0,0 @@ -/* - * 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.services.sqs.internal.batchmanager; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; -import java.util.stream.Collectors; -import software.amazon.awssdk.annotations.SdkInternalApi; -import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration; -import software.amazon.awssdk.core.batchmanager.BatchAndSend; -import software.amazon.awssdk.core.batchmanager.BatchKeyMapper; -import software.amazon.awssdk.core.batchmanager.BatchResponseMapper; -import software.amazon.awssdk.core.batchmanager.IdentifiableMessage; -import software.amazon.awssdk.services.sqs.SqsAsyncClient; -import software.amazon.awssdk.services.sqs.SqsClient; -import software.amazon.awssdk.services.sqs.model.BatchResultErrorEntry; -import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityBatchRequest; -import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityBatchRequestEntry; -import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityBatchResponse; -import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityRequest; -import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityResponse; -import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchRequest; -import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchRequestEntry; -import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchResponse; -import software.amazon.awssdk.services.sqs.model.DeleteMessageRequest; -import software.amazon.awssdk.services.sqs.model.DeleteMessageResponse; -import software.amazon.awssdk.services.sqs.model.SendMessageBatchRequest; -import software.amazon.awssdk.services.sqs.model.SendMessageBatchRequestEntry; -import software.amazon.awssdk.services.sqs.model.SendMessageBatchResponse; -import software.amazon.awssdk.services.sqs.model.SendMessageBatchResultEntry; -import software.amazon.awssdk.services.sqs.model.SendMessageRequest; -import software.amazon.awssdk.services.sqs.model.SendMessageResponse; -import software.amazon.awssdk.services.sqs.model.SqsException; -import software.amazon.awssdk.utils.Either; - -@SdkInternalApi -public final class SqsBatchFunctions { - - private SqsBatchFunctions() { - } - - public static BatchAndSend sendMessageBatchFunction(SqsClient client, - Executor executor) { - return (identifiedRequests, batchKey) -> { - SendMessageBatchRequest batchRequest = createSendMessageBatchRequest(identifiedRequests, batchKey); - return CompletableFuture.supplyAsync(() -> client.sendMessageBatch(batchRequest), executor); - }; - } - - public static BatchAndSend sendMessageBatchAsyncFunction(SqsAsyncClient - client) { - return (identifiedRequests, batchKey) -> { - SendMessageBatchRequest batchRequest = createSendMessageBatchRequest(identifiedRequests, batchKey); - return client.sendMessageBatch(batchRequest); - }; - } - - public static SendMessageBatchRequest createSendMessageBatchRequest( - List> identifiedRequests, String batchKey) { - List entries = - identifiedRequests.stream() - .map(identifiedRequest -> createSendMessageBatchRequestEntry(identifiedRequest.id(), - identifiedRequest.message())) - .collect(Collectors.toList()); - - // Since requests are batched together according to a combination of their queueUrl and overrideConfiguration, all - // requests must have the same overrideConfiguration so it is sufficient to retrieve it from the first request. - Optional overrideConfiguration = identifiedRequests.get(0) - .message() - .overrideConfiguration(); - return overrideConfiguration.map(overrideConfig -> SendMessageBatchRequest.builder() - .queueUrl(batchKey) - .overrideConfiguration(overrideConfig) - .entries(entries) - .build()) - .orElse(SendMessageBatchRequest.builder() - .queueUrl(batchKey) - .entries(entries) - .build()); - } - - public static BatchResponseMapper sendMessageResponseMapper() { - return sendMessageBatchResponse -> { - List, IdentifiableMessage>> - mappedResponses = new ArrayList<>(); - sendMessageBatchResponse.successful() - .forEach(batchResponseEntry -> { - String key = batchResponseEntry.id(); - SendMessageResponse response = createSendMessageResponse(batchResponseEntry, - sendMessageBatchResponse); - mappedResponses.add(Either.left(new IdentifiableMessage<>(key, response))); - }); - sendMessageBatchResponse.failed() - .forEach(batchResponseEntry -> { - String key = batchResponseEntry.id(); - Throwable response = createThrowable(batchResponseEntry); - mappedResponses.add(Either.right(new IdentifiableMessage<>(key, response))); - }); - return mappedResponses; - }; - } - - // TODO: The BatchKeyMappers for SQS is not set in stone. Could batch requests some other way. - public static BatchKeyMapper sendMessageBatchKeyMapper() { - return request -> request.overrideConfiguration() - .map(overrideConfig -> request.queueUrl() + overrideConfig.hashCode()) - .orElse(request.queueUrl()); - } - - public static BatchAndSend deleteMessageBatchFunction( - SqsClient client, Executor executor) { - return (identifiedRequests, batchKey) -> { - DeleteMessageBatchRequest batchRequest = createDeleteMessageBatchRequest(identifiedRequests, batchKey); - return CompletableFuture.supplyAsync(() -> client.deleteMessageBatch(batchRequest), executor); - }; - } - - public static BatchAndSend deleteMessageBatchAsyncFunction( - SqsAsyncClient client) { - return (identifiedRequests, batchKey) -> { - DeleteMessageBatchRequest batchRequest = createDeleteMessageBatchRequest(identifiedRequests, batchKey); - return client.deleteMessageBatch(batchRequest); - }; - } - - public static DeleteMessageBatchRequest createDeleteMessageBatchRequest( - List> identifiedRequests, String batchKey) { - List entries = - identifiedRequests.stream() - .map(identifiedRequest -> createDeleteMessageBatchRequestEntry(identifiedRequest.id(), - identifiedRequest.message())) - .collect(Collectors.toList()); - - // Since requests are batched together according to a combination of their queueUrl and overrideConfiguration, all - // requests must have the same overrideConfiguration so it is sufficient to retrieve it from the first request. - Optional overrideConfiguration = identifiedRequests.get(0) - .message() - .overrideConfiguration(); - return overrideConfiguration.map(overrideConfig -> DeleteMessageBatchRequest.builder() - .queueUrl(batchKey) - .overrideConfiguration(overrideConfig) - .entries(entries) - .build()) - .orElse(DeleteMessageBatchRequest.builder() - .queueUrl(batchKey) - .entries(entries) - .build()); - - } - - public static BatchResponseMapper deleteMessageResponseMapper() { - return deleteMessageBatchResponse -> { - List, IdentifiableMessage>> - mappedResponses = new ArrayList<>(); - deleteMessageBatchResponse.successful() - .forEach(batchResponseEntry -> { - String key = batchResponseEntry.id(); - DeleteMessageResponse response = - createDeleteMessageResponse(deleteMessageBatchResponse); - mappedResponses.add(Either.left(new IdentifiableMessage<>(key, response))); - }); - deleteMessageBatchResponse.failed() - .forEach(batchResponseEntry -> { - String key = batchResponseEntry.id(); - Throwable response = createThrowable(batchResponseEntry); - mappedResponses.add(Either.right(new IdentifiableMessage<>(key, response))); - }); - return mappedResponses; - }; - } - - public static BatchKeyMapper deleteMessageBatchKeyMapper() { - return request -> request.overrideConfiguration() - .map(overrideConfig -> request.queueUrl() + overrideConfig.hashCode()) - .orElse(request.queueUrl()); - } - - public static BatchAndSend - changeVisibilityBatchFunction(SqsClient client, Executor executor) { - return (identifiedRequests, batchKey) -> { - ChangeMessageVisibilityBatchRequest batchRequest = createChangeVisibilityBatchRequest(identifiedRequests, batchKey); - return CompletableFuture.supplyAsync(() -> client.changeMessageVisibilityBatch(batchRequest), executor); - }; - } - - public static BatchAndSend - changeVisibilityBatchAsyncFunction(SqsAsyncClient client) { - return (identifiedRequests, batchKey) -> { - ChangeMessageVisibilityBatchRequest batchRequest = createChangeVisibilityBatchRequest(identifiedRequests, batchKey); - return client.changeMessageVisibilityBatch(batchRequest); - }; - } - - public static ChangeMessageVisibilityBatchRequest createChangeVisibilityBatchRequest( - List> identifiedRequests, String batchKey) { - List entries = - identifiedRequests.stream() - .map(identifiedRequest -> createChangVisibilityBatchRequestEntry(identifiedRequest.id(), - identifiedRequest.message())) - .collect(Collectors.toList()); - - // Since requests are batched together according to a combination of their queueUrl and overrideConfiguration, all - // requests must have the same overrideConfiguration so it is sufficient to retrieve it from the first request. - Optional overrideConfiguration = identifiedRequests.get(0) - .message() - .overrideConfiguration(); - return overrideConfiguration.map(overrideConfig -> - ChangeMessageVisibilityBatchRequest.builder() - .queueUrl(batchKey) - .overrideConfiguration(overrideConfig) - .entries(entries) - .build()) - .orElse(ChangeMessageVisibilityBatchRequest.builder() - .queueUrl(batchKey) - .entries(entries) - .build()); - } - - public static BatchResponseMapper - changeVisibilityResponseMapper() { - return changeMessageVisibilityResponses -> { - List, IdentifiableMessage>> - mappedResponses = new ArrayList<>(); - changeMessageVisibilityResponses.successful() - .forEach(batchResponseEntry -> { - String key = batchResponseEntry.id(); - ChangeMessageVisibilityResponse response = - createChangeVisibilityResponse(changeMessageVisibilityResponses); - mappedResponses.add(Either.left(new IdentifiableMessage<>(key, response))); - }); - changeMessageVisibilityResponses.failed() - .forEach(batchResponseEntry -> { - String key = batchResponseEntry.id(); - Throwable response = createThrowable(batchResponseEntry); - mappedResponses.add(Either.right(new IdentifiableMessage<>(key, response))); - }); - return mappedResponses; - }; - } - - public static BatchKeyMapper changeVisibilityBatchKeyMapper() { - return request -> request.overrideConfiguration() - .map(overrideConfig -> request.queueUrl() + overrideConfig.hashCode()) - .orElse(request.queueUrl()); - } - - private static SendMessageBatchRequestEntry createSendMessageBatchRequestEntry(String id, SendMessageRequest request) { - return SendMessageBatchRequestEntry.builder() - .id(id) - .messageBody(request.messageBody()) - .delaySeconds(request.delaySeconds()) - .messageAttributes(request.messageAttributes()) - .messageDeduplicationId(request.messageDeduplicationId()) - .messageGroupId(request.messageGroupId()) - .messageSystemAttributes(request.messageSystemAttributes()) - .build(); - } - - private static SendMessageResponse createSendMessageResponse(SendMessageBatchResultEntry successfulEntry, - SendMessageBatchResponse batchResponse) { - SendMessageResponse.Builder builder = SendMessageResponse.builder() - .md5OfMessageAttributes(successfulEntry.md5OfMessageAttributes()) - .md5OfMessageBody(successfulEntry.md5OfMessageBody()) - .md5OfMessageSystemAttributes( - successfulEntry.md5OfMessageSystemAttributes()) - .messageId(successfulEntry.messageId()) - .sequenceNumber(successfulEntry.sequenceNumber()); - if (batchResponse.responseMetadata() != null) { - builder.responseMetadata(batchResponse.responseMetadata()); - } - - if (batchResponse.sdkHttpResponse() != null) { - builder.sdkHttpResponse(batchResponse.sdkHttpResponse()); - } - return builder.build(); - } - - private static Throwable createThrowable(BatchResultErrorEntry failedEntry) { - int code = Integer.parseInt(failedEntry.code()); - return SqsException.builder() - .statusCode(code) - .message(failedEntry.message()) - .build(); - } - - private static DeleteMessageBatchRequestEntry createDeleteMessageBatchRequestEntry(String id, DeleteMessageRequest request) { - return DeleteMessageBatchRequestEntry.builder() - .id(id) - .receiptHandle(request.receiptHandle()) - .build(); - } - - private static DeleteMessageResponse createDeleteMessageResponse(DeleteMessageBatchResponse batchResponse) { - DeleteMessageResponse.Builder builder = DeleteMessageResponse.builder(); - - if (batchResponse.responseMetadata() != null) { - builder.responseMetadata(batchResponse.responseMetadata()); - } - - if (batchResponse.sdkHttpResponse() != null) { - builder.sdkHttpResponse(batchResponse.sdkHttpResponse()); - } - return builder.build(); - } - - private static ChangeMessageVisibilityBatchRequestEntry createChangVisibilityBatchRequestEntry(String id, - ChangeMessageVisibilityRequest request) { - return ChangeMessageVisibilityBatchRequestEntry.builder() - .id(id) - .receiptHandle(request.receiptHandle()) - .visibilityTimeout(request.visibilityTimeout()) - .build(); - } - - private static ChangeMessageVisibilityResponse createChangeVisibilityResponse(ChangeMessageVisibilityBatchResponse - batchResponse) { - ChangeMessageVisibilityResponse.Builder builder = ChangeMessageVisibilityResponse.builder(); - - if (batchResponse.responseMetadata() != null) { - builder.responseMetadata(batchResponse.responseMetadata()); - } - - if (batchResponse.sdkHttpResponse() != null) { - builder.sdkHttpResponse(batchResponse.sdkHttpResponse()); - } - return builder.build(); - } -} diff --git a/services/sqs/src/main/resources/codegen-resources/customization.config b/services/sqs/src/main/resources/codegen-resources/customization.config index cde98df20a66..b4aa295d0ae6 100644 --- a/services/sqs/src/main/resources/codegen-resources/customization.config +++ b/services/sqs/src/main/resources/codegen-resources/customization.config @@ -2,8 +2,42 @@ "verifiedSimpleMethods" : [ "listQueues" ], - "batchManagerMethod": { - "returnType": "software.amazon.awssdk.services.sqs.batchmanager.SqsBatchManager", - "asyncReturnType": "software.amazon.awssdk.services.sqs.batchmanager.SqsAsyncBatchManager" + "batchManager": { + "sendMessage": { + "batchMethod": "sendMessageBatch", + "batchRequestEntry": "SendMessageBatchRequestEntry", + "successBatchEntry": "SendMessageBatchResultEntry", + "errorBatchEntry": "BatchResultErrorEntry", + "successEntriesMethod": "successful", + "errorEntriesMethod": "failed", + "batchKey": "queueUrl", + "errorCodeMethod": "code", + "errorMessageMethod": "message", + "batchRequestIdentifier": "id" + }, + "deleteMessage": { + "batchMethod": "deleteMessageBatch", + "batchRequestEntry": "DeleteMessageBatchRequestEntry", + "successBatchEntry": "DeleteMessageBatchResultEntry", + "errorBatchEntry": "BatchResultErrorEntry", + "successEntriesMethod": "successful", + "errorEntriesMethod": "failed", + "batchKey": "queueUrl", + "errorCodeMethod": "code", + "errorMessageMethod": "message", + "batchRequestIdentifier": "id" + }, + "changeMessageVisibility": { + "batchMethod": "changeMessageVisibilityBatch", + "batchRequestEntry": "ChangeMessageVisibilityBatchRequestEntry", + "successBatchEntry": "ChangeMessageVisibilityBatchResultEntry", + "errorBatchEntry": "BatchResultErrorEntry", + "successEntriesMethod": "successful", + "errorEntriesMethod": "failed", + "batchKey": "queueUrl", + "errorCodeMethod": "code", + "errorMessageMethod": "message", + "batchRequestIdentifier": "id" + } } } diff --git a/services/sqs/src/test/java/software/amazon/awssdk/services/sqs/SqsAsyncBatchManagerTest.java b/services/sqs/src/test/java/software/amazon/awssdk/services/sqs/SqsAsyncBatchManagerTest.java index 33e9eed4a779..615004a6cb8f 100644 --- a/services/sqs/src/test/java/software/amazon/awssdk/services/sqs/SqsAsyncBatchManagerTest.java +++ b/services/sqs/src/test/java/software/amazon/awssdk/services/sqs/SqsAsyncBatchManagerTest.java @@ -35,7 +35,7 @@ import software.amazon.awssdk.core.batchmanager.BatchManager; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.sqs.batchmanager.SqsAsyncBatchManager; -import software.amazon.awssdk.services.sqs.internal.batchmanager.DefaultSqsAsyncBatchManager; +import software.amazon.awssdk.services.sqs.batchmanager.internal.DefaultSqsAsyncBatchManager; import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityBatchResponse; import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityRequest; import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityResponse; diff --git a/services/sqs/src/test/java/software/amazon/awssdk/services/sqs/SqsBatchFunctionsTest.java b/services/sqs/src/test/java/software/amazon/awssdk/services/sqs/SqsBatchFunctionsTest.java index fc66e79340d9..2757286ed8ef 100644 --- a/services/sqs/src/test/java/software/amazon/awssdk/services/sqs/SqsBatchFunctionsTest.java +++ b/services/sqs/src/test/java/software/amazon/awssdk/services/sqs/SqsBatchFunctionsTest.java @@ -16,12 +16,12 @@ package software.amazon.awssdk.services.sqs; import static org.assertj.core.api.Assertions.assertThat; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.changeVisibilityBatchKeyMapper; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.changeVisibilityResponseMapper; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.deleteMessageBatchKeyMapper; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.deleteMessageResponseMapper; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.sendMessageBatchKeyMapper; -import static software.amazon.awssdk.services.sqs.internal.batchmanager.SqsBatchFunctions.sendMessageResponseMapper; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.changeMessageVisibilityBatchKeyMapper; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.changeMessageVisibilityResponseMapper; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.deleteMessageBatchKeyMapper; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.deleteMessageResponseMapper; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.sendMessageBatchKeyMapper; +import static software.amazon.awssdk.services.sqs.batchmanager.internal.SqsBatchFunctions.sendMessageResponseMapper; import java.nio.charset.StandardCharsets; import java.time.Duration; @@ -177,7 +177,7 @@ public void changeVisibilityResponseMapper_mapResponsesCorrectly() { ChangeMessageVisibilityBatchResponse batchResponse = createChangeVisibilityBatchResponse(responseMetadata, httpResponse, entry1, entry2); List, IdentifiableMessage>> mappedResponses = - changeVisibilityResponseMapper().mapBatchResponse(batchResponse); + changeMessageVisibilityResponseMapper().mapBatchResponse(batchResponse); IdentifiableMessage response1 = mappedResponses.get(0).left().get(); IdentifiableMessage response2 = mappedResponses.get(1).left().get(); @@ -194,8 +194,8 @@ public void changeVisibilityBatchKeyMapperWithoutOverrideConfig_hasSameBatchKey( String queueUrl = "myQueue"; ChangeMessageVisibilityRequest request1 = ChangeMessageVisibilityRequest.builder().queueUrl(queueUrl).build(); ChangeMessageVisibilityRequest request2 = ChangeMessageVisibilityRequest.builder().queueUrl(queueUrl).build(); - String batchKey1 = changeVisibilityBatchKeyMapper().getBatchKey(request1); - String batchKey2 = changeVisibilityBatchKeyMapper().getBatchKey(request2); + String batchKey1 = changeMessageVisibilityBatchKeyMapper().getBatchKey(request1); + String batchKey2 = changeMessageVisibilityBatchKeyMapper().getBatchKey(request2); assertThat(batchKey1).isEqualTo(queueUrl); assertThat(batchKey2).isEqualTo(queueUrl); @@ -207,8 +207,8 @@ public void changeVisibilityBatchKeyMapperWithOverrideConfig_hasSameBatchKey() { String queueUrl = "myQueue"; ChangeMessageVisibilityRequest request1 = createChangeVisibilityRequestWithOverrideConfig(queueUrl, 10); ChangeMessageVisibilityRequest request2 = createChangeVisibilityRequestWithOverrideConfig(queueUrl, 10); - String batchKey1 = changeVisibilityBatchKeyMapper().getBatchKey(request1); - String batchKey2 = changeVisibilityBatchKeyMapper().getBatchKey(request2); + String batchKey1 = changeMessageVisibilityBatchKeyMapper().getBatchKey(request1); + String batchKey2 = changeMessageVisibilityBatchKeyMapper().getBatchKey(request2); assertThat(batchKey1).isEqualTo(batchKey2); } @@ -217,8 +217,8 @@ public void changeVisibilityBatchKeyMapperWithDifferentOverrideConfig_hasDiffere String queueUrl = "myQueue"; ChangeMessageVisibilityRequest request1 = createChangeVisibilityRequestWithOverrideConfig(queueUrl, 10); ChangeMessageVisibilityRequest request2 = createChangeVisibilityRequestWithOverrideConfig(queueUrl, 20); - String batchKey1 = changeVisibilityBatchKeyMapper().getBatchKey(request1); - String batchKey2 = changeVisibilityBatchKeyMapper().getBatchKey(request2); + String batchKey1 = changeMessageVisibilityBatchKeyMapper().getBatchKey(request1); + String batchKey2 = changeMessageVisibilityBatchKeyMapper().getBatchKey(request2); assertThat(batchKey1).isNotEqualTo(batchKey2); } diff --git a/services/sqs/src/test/java/software/amazon/awssdk/services/sqs/SqsBatchManagerTest.java b/services/sqs/src/test/java/software/amazon/awssdk/services/sqs/SqsBatchManagerTest.java index c37027ee6893..94aadbb37cf1 100644 --- a/services/sqs/src/test/java/software/amazon/awssdk/services/sqs/SqsBatchManagerTest.java +++ b/services/sqs/src/test/java/software/amazon/awssdk/services/sqs/SqsBatchManagerTest.java @@ -22,7 +22,6 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import org.junit.After; import org.junit.AfterClass; @@ -37,7 +36,7 @@ import software.amazon.awssdk.core.batchmanager.BatchManager; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.sqs.batchmanager.SqsBatchManager; -import software.amazon.awssdk.services.sqs.internal.batchmanager.DefaultSqsBatchManager; +import software.amazon.awssdk.services.sqs.batchmanager.internal.DefaultSqsBatchManager; import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityBatchResponse; import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityRequest; import software.amazon.awssdk.services.sqs.model.ChangeMessageVisibilityResponse; diff --git a/utils/src/main/java/software/amazon/awssdk/utils/internal/CodegenNamingUtils.java b/utils/src/main/java/software/amazon/awssdk/utils/internal/CodegenNamingUtils.java index 3dc64996d43a..ee4115821a01 100644 --- a/utils/src/main/java/software/amazon/awssdk/utils/internal/CodegenNamingUtils.java +++ b/utils/src/main/java/software/amazon/awssdk/utils/internal/CodegenNamingUtils.java @@ -72,4 +72,10 @@ public static String lowercaseFirstChar(String word) { chars[0] = Character.toLowerCase(chars[0]); return String.valueOf(chars); } + + public static String uppercaseFirstChar(String word) { + char[] chars = word.toCharArray(); + chars[0] = Character.toUpperCase(chars[0]); + return String.valueOf(chars); + } }