Skip to content

Commit 2933e22

Browse files
committed
Generate service specific waiter sync and async interfaces
1 parent b5489c5 commit 2933e22

File tree

17 files changed

+599
-62
lines changed

17 files changed

+599
-62
lines changed

codegen/src/main/java/software/amazon/awssdk/codegen/AddMetadata.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ public static Metadata constructMetadata(ServiceModel serviceModel,
6868
.withTransformPackageName(namingStrategy.getTransformPackageName(serviceName))
6969
.withRequestTransformPackageName(namingStrategy.getRequestTransformPackageName(serviceName))
7070
.withPaginatorsPackageName(namingStrategy.getPaginatorsPackageName(serviceName))
71+
.withWaitersPackageName(namingStrategy.getWaitersPackageName(serviceName))
7172
.withServiceAbbreviation(serviceMetadata.getServiceAbbreviation())
7273
.withServiceFullName(serviceMetadata.getServiceFullName())
7374
.withServiceName(serviceName)
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.awssdk.codegen.docs;
17+
18+
import com.squareup.javapoet.ClassName;
19+
import com.squareup.javapoet.CodeBlock;
20+
import java.util.Map;
21+
import software.amazon.awssdk.codegen.model.intermediate.OperationModel;
22+
import software.amazon.awssdk.codegen.model.service.WaiterDefinition;
23+
import software.amazon.awssdk.core.waiters.PollingStrategy;
24+
25+
public final class WaiterDocs {
26+
27+
private WaiterDocs() {
28+
}
29+
30+
public static String waiterInterfaceJavadoc() {
31+
return "Waiter utility class that polls a resource until a desired state is reached or until it is "
32+
+ "determined that the resource will never enter into the desired state. This can be"
33+
+ " created using the static {@link #builder()} method";
34+
}
35+
36+
public static CodeBlock waiterOperationJavadoc(ClassName className, Map.Entry<String, WaiterDefinition> waiterDefinition,
37+
OperationModel operationModel) {
38+
String javadocs = new DocumentationBuilder().description("Polls {@link $T#$N} API until the desired condition "
39+
+ "{@code $N} is met, "
40+
+ "or until it is determined that the resource will never "
41+
+ "enter into the desired state")
42+
.param(operationModel.getInput().getVariableName(), "the request to be used"
43+
+ " for polling")
44+
.returns("WaiterResponse containing either a response or an exception that "
45+
+ "has matched with the waiter success condition")
46+
.build();
47+
return CodeBlock.builder()
48+
.add(javadocs, className, operationModel.getMethodName(), waiterDefinition.getKey())
49+
.build();
50+
51+
}
52+
53+
public static CodeBlock waiterBuilderMethodJavadoc(ClassName className) {
54+
String javadocs = new DocumentationBuilder()
55+
.description("Create a builder that can be used to configure and create a {@link $T}.")
56+
.returns("a builder")
57+
.build();
58+
59+
return CodeBlock.builder()
60+
.add(javadocs, className)
61+
.build();
62+
}
63+
64+
public static CodeBlock waiterBuilderPollingStrategy() {
65+
String javadocs = new DocumentationBuilder()
66+
.description("Defines a {@link $T} to use when polling a resource")
67+
.param("pollingStrategy", "the polling strategy to set")
68+
.returns("a reference to this object so that method calls can be chained together.")
69+
.build();
70+
71+
return CodeBlock.builder()
72+
.add(javadocs, ClassName.get(PollingStrategy.class))
73+
.build();
74+
}
75+
76+
public static CodeBlock waiterBuilderClientJavadoc(ClassName className) {
77+
String javadocs = new DocumentationBuilder()
78+
.description("Defines the {@link $T} to use when polling a resource")
79+
.param("client", "the client to send the request")
80+
.returns("a reference to this object so that method calls can be chained together.")
81+
.build();
82+
83+
return CodeBlock.builder()
84+
.add(javadocs, className)
85+
.build();
86+
}
87+
88+
public static CodeBlock waiterBuilderBuildJavadoc(ClassName className) {
89+
String javadocs = new DocumentationBuilder()
90+
.description("Builds an instance of {@link $T} based on the configurations supplied to this builder ")
91+
.returns("An initialized {@link $T}")
92+
.build();
93+
94+
return CodeBlock.builder()
95+
.add(javadocs, className, className)
96+
.build();
97+
}
98+
}

codegen/src/main/java/software/amazon/awssdk/codegen/emitters/tasks/AwsGeneratorTasks.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public AwsGeneratorTasks(GeneratorTaskParams params) {
2525
super(new CommonGeneratorTasks(params),
2626
new AsyncClientGeneratorTasks(params),
2727
new PaginatorsGeneratorTasks(params),
28-
new EventStreamGeneratorTasks(params));
28+
new EventStreamGeneratorTasks(params),
29+
new WaitersGeneratorTasks(params));
2930
}
3031
}

codegen/src/main/java/software/amazon/awssdk/codegen/emitters/tasks/WaitersGeneratorTasks.java

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,13 @@
1515

1616
package software.amazon.awssdk.codegen.emitters.tasks;
1717

18-
import static software.amazon.awssdk.utils.FunctionalUtils.safeFunction;
19-
20-
import java.io.IOException;
18+
import java.util.ArrayList;
2119
import java.util.List;
22-
import java.util.Map;
23-
import java.util.stream.Collectors;
24-
import java.util.stream.Stream;
2520
import software.amazon.awssdk.codegen.emitters.GeneratorTask;
2621
import software.amazon.awssdk.codegen.emitters.GeneratorTaskParams;
2722
import software.amazon.awssdk.codegen.emitters.PoetGeneratorTask;
28-
import software.amazon.awssdk.codegen.model.service.WaiterDefinition;
29-
import software.amazon.awssdk.codegen.poet.waiters.WaitersClassSpec;
23+
import software.amazon.awssdk.codegen.poet.waiters.AsyncWaiterInterfaceSpec;
24+
import software.amazon.awssdk.codegen.poet.waiters.WaiterInterfaceSpec;
3025

3126
public class WaitersGeneratorTasks extends BaseGeneratorTasks {
3227

@@ -43,22 +38,24 @@ protected boolean hasTasks() {
4338
}
4439

4540
@Override
46-
protected List<GeneratorTask> createTasks() throws Exception {
47-
return model.getWaiters().entrySet().stream()
48-
.flatMap(safeFunction(this::createSyncAndAsyncTasks))
49-
.collect(Collectors.toList());
50-
}
51-
52-
private Stream<GeneratorTask> createSyncAndAsyncTasks(Map.Entry<String, WaiterDefinition> entry) throws IOException {
53-
return Stream.of(createSyncTask(entry), createAsyncTask(entry));
41+
protected List<GeneratorTask> createTasks() {
42+
List<GeneratorTask> generatorTasks = new ArrayList<>();
43+
generatorTasks.addAll(createSyncTasks());
44+
generatorTasks.addAll(createAsyncTasks());
45+
return generatorTasks;
5446
}
5547

56-
private GeneratorTask createSyncTask(Map.Entry<String, WaiterDefinition> entry) throws IOException {
57-
return new PoetGeneratorTask(waitersClassDir, model.getFileHeader(),
58-
new WaitersClassSpec(model, entry.getKey(), entry.getValue()));
48+
private List<GeneratorTask> createSyncTasks() {
49+
List<GeneratorTask> syncTasks = new ArrayList<>();
50+
syncTasks.add(new PoetGeneratorTask(waitersClassDir, model.getFileHeader(),
51+
new WaiterInterfaceSpec(model)));
52+
return syncTasks;
5953
}
6054

61-
private GeneratorTask createAsyncTask(Map.Entry<String, WaiterDefinition> entry) throws IOException {
62-
throw new UnsupportedOperationException();
55+
private List<GeneratorTask> createAsyncTasks() {
56+
List<GeneratorTask> asyncTasks = new ArrayList<>();
57+
asyncTasks.add(new PoetGeneratorTask(waitersClassDir, model.getFileHeader(),
58+
new AsyncWaiterInterfaceSpec(model)));
59+
return asyncTasks;
6360
}
6461
}

codegen/src/main/java/software/amazon/awssdk/codegen/internal/Constant.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ public final class Constant {
5252

5353
public static final String PACKAGE_NAME_PAGINATORS_PATTERN = "%s.paginators";
5454

55+
public static final String PACKAGE_NAME_WAITERS_PATTERN = "%s.waiters";
56+
5557
public static final String PACKAGE_NAME_SMOKE_TEST_PATTERN = "%s.smoketests";
5658

5759
public static final String PACKAGE_NAME_CUSTOM_AUTH_PATTERN = "%s.auth";

codegen/src/main/java/software/amazon/awssdk/codegen/model/intermediate/Metadata.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,12 @@ public void setWaitersPackageName(String waitersPackageName) {
673673
this.waitersPackageName = waitersPackageName;
674674
}
675675

676+
public Metadata withWaitersPackageName(String waitersPackageName) {
677+
setWaitersPackageName(waitersPackageName);
678+
return this;
679+
}
680+
681+
676682
public String getFullWaitersPackageName() {
677683
return joinPackageNames(rootPackageName, getWaitersPackageName());
678684
}

codegen/src/main/java/software/amazon/awssdk/codegen/naming/DefaultNamingStrategy.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,11 @@ public String getPaginatorsPackageName(String serviceName) {
162162
return getCustomizedPackageName(concatServiceNameIfShareModel(serviceName), Constant.PACKAGE_NAME_PAGINATORS_PATTERN);
163163
}
164164

165+
@Override
166+
public String getWaitersPackageName(String serviceName) {
167+
return getCustomizedPackageName(concatServiceNameIfShareModel(serviceName), Constant.PACKAGE_NAME_WAITERS_PATTERN);
168+
}
169+
165170
@Override
166171
public String getSmokeTestPackageName(String serviceName) {
167172

codegen/src/main/java/software/amazon/awssdk/codegen/naming/NamingStrategy.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ public interface NamingStrategy {
5252
*/
5353
String getPaginatorsPackageName(String serviceName);
5454

55+
/**
56+
* Retrieve the waiters package name that should be used based on the service name.
57+
*/
58+
String getWaitersPackageName(String serviceName);
59+
5560
/**
5661
* Retrieve the smote test package name that should be used based on the service name.
5762
*/

codegen/src/main/java/software/amazon/awssdk/codegen/poet/PoetExtensions.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,15 @@ public ClassName getResponseClassForPaginatedSyncOperation(String operationName)
7676
return ClassName.get(model.getMetadata().getFullPaginatorsPackageName(), operationName + "Iterable");
7777
}
7878

79+
public ClassName getSyncWaiterInterface() {
80+
return ClassName.get(model.getMetadata().getFullWaitersPackageName(), model.getMetadata().getServiceName() + "Waiter");
81+
}
82+
83+
public ClassName getAsyncWaiterInterface() {
84+
return ClassName.get(model.getMetadata().getFullWaitersPackageName(), model.getMetadata().getServiceName() +
85+
"AsyncWaiter");
86+
}
87+
7988
/**
8089
* @param operationName Name of the operation
8190
* @return A Poet {@link ClassName} for the response type of a async paginated operation in the base service package.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.awssdk.codegen.poet.waiters;
17+
18+
import com.squareup.javapoet.ClassName;
19+
import com.squareup.javapoet.ParameterizedTypeName;
20+
import java.util.concurrent.CompletableFuture;
21+
import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel;
22+
import software.amazon.awssdk.codegen.model.intermediate.OperationModel;
23+
import software.amazon.awssdk.codegen.poet.PoetExtensions;
24+
import software.amazon.awssdk.core.waiters.WaiterResponse;
25+
26+
public final class AsyncWaiterInterfaceSpec extends BaseWaiterInterfaceSpec {
27+
28+
private final IntermediateModel model;
29+
private final PoetExtensions poetExtensions;
30+
private final ClassName className;
31+
private final String modelPackage;
32+
33+
public AsyncWaiterInterfaceSpec(IntermediateModel model) {
34+
super(model);
35+
this.modelPackage = model.getMetadata().getFullModelPackageName();
36+
this.model = model;
37+
this.poetExtensions = new PoetExtensions(model);
38+
this.className = poetExtensions.getAsyncWaiterInterface();
39+
}
40+
41+
@Override
42+
protected ClassName clientClassName() {
43+
return poetExtensions.getClientClass(model.getMetadata().getAsyncInterface());
44+
}
45+
46+
@Override
47+
public ClassName className() {
48+
return className;
49+
}
50+
51+
@Override
52+
protected ParameterizedTypeName getWaiterResponseType(OperationModel opModel) {
53+
ClassName pojoResponse = ClassName.get(modelPackage, opModel.getReturnType().getReturnType());
54+
ParameterizedTypeName waiterResponse = ParameterizedTypeName.get(ClassName.get(WaiterResponse.class), pojoResponse);
55+
56+
return ParameterizedTypeName.get(ClassName.get(CompletableFuture.class),
57+
waiterResponse);
58+
}
59+
}

0 commit comments

Comments
 (0)