Skip to content

Commit 7a28087

Browse files
authored
Adding a generic method invokeOperation for abstract delegating clien… (#3996)
Adding a generic method invokeOperation for abstract delegating client to allow overriding behavior changes for all operations
1 parent 8a6af9f commit 7a28087

File tree

4 files changed

+162
-52
lines changed

4 files changed

+162
-52
lines changed

codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/DelegatingAsyncClientClass.java

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,20 @@
2020
import static javax.lang.model.element.Modifier.ABSTRACT;
2121
import static javax.lang.model.element.Modifier.FINAL;
2222
import static javax.lang.model.element.Modifier.PRIVATE;
23+
import static javax.lang.model.element.Modifier.PROTECTED;
2324
import static javax.lang.model.element.Modifier.PUBLIC;
2425

2526
import com.squareup.javapoet.ClassName;
2627
import com.squareup.javapoet.FieldSpec;
2728
import com.squareup.javapoet.MethodSpec;
29+
import com.squareup.javapoet.ParameterSpec;
30+
import com.squareup.javapoet.ParameterizedTypeName;
2831
import com.squareup.javapoet.TypeSpec;
32+
import com.squareup.javapoet.TypeVariableName;
2933
import java.util.ArrayList;
3034
import java.util.Comparator;
3135
import java.util.List;
36+
import java.util.function.Function;
3237
import java.util.stream.Stream;
3338
import software.amazon.awssdk.annotations.SdkPublicApi;
3439
import software.amazon.awssdk.codegen.model.config.customization.UtilitiesMethod;
@@ -88,14 +93,9 @@ protected void addFields(TypeSpec.Builder type) {
8893

8994
@Override
9095
protected void addAdditionalMethods(TypeSpec.Builder type) {
91-
MethodSpec delegate = MethodSpec.methodBuilder("delegate")
92-
.addModifiers(PUBLIC)
93-
.addStatement("return this.delegate")
94-
.returns(SdkClient.class)
95-
.build();
96-
9796
type.addMethod(nameMethod())
98-
.addMethod(delegate);
97+
.addMethod(delegateMethod())
98+
.addMethod(invokeMethod());
9999
}
100100

101101
private MethodSpec nameMethod() {
@@ -107,6 +107,34 @@ private MethodSpec nameMethod() {
107107
.build();
108108
}
109109

110+
private MethodSpec delegateMethod() {
111+
return MethodSpec.methodBuilder("delegate")
112+
.addModifiers(PUBLIC)
113+
.addStatement("return this.delegate")
114+
.returns(SdkClient.class)
115+
.build();
116+
}
117+
118+
private MethodSpec invokeMethod() {
119+
TypeVariableName requestTypeVariableName =
120+
TypeVariableName.get("T", poetExtensions.getModelClass(model.getSdkRequestBaseClassName()));
121+
122+
TypeVariableName responseTypeVariableName = STREAMING_TYPE_VARIABLE;
123+
124+
ParameterizedTypeName functionTypeName = ParameterizedTypeName
125+
.get(ClassName.get(Function.class), requestTypeVariableName, responseTypeVariableName);
126+
127+
return MethodSpec.methodBuilder("invokeOperation")
128+
.addModifiers(PROTECTED)
129+
.addParameter(requestTypeVariableName, "request")
130+
.addParameter(functionTypeName, "operation")
131+
.addTypeVariable(requestTypeVariableName)
132+
.addTypeVariable(responseTypeVariableName)
133+
.returns(responseTypeVariableName)
134+
.addStatement("return operation.apply(request)")
135+
.build();
136+
}
137+
110138
@Override
111139
protected MethodSpec serviceClientConfigMethod() {
112140
return MethodSpec.methodBuilder("serviceClientConfiguration")
@@ -164,9 +192,19 @@ protected MethodSpec.Builder operationBody(MethodSpec.Builder builder, Operation
164192
builder.addModifiers(PUBLIC)
165193
.addAnnotation(Override.class);
166194

167-
builder.addStatement("return delegate.$N($L)",
195+
if (builder.parameters.size() < 1) {
196+
throw new IllegalStateException("All client methods must have an argument");
197+
}
198+
199+
List<ParameterSpec> parameters = new ArrayList<>(builder.parameters);
200+
String requestParameter = parameters.remove(0).name;
201+
String additionalParameters = String.format(", %s", parameters.stream().map(p -> p.name).collect(joining(", ")));
202+
203+
builder.addStatement("return invokeOperation($N, request -> delegate.$N(request$N))",
204+
requestParameter,
168205
opModel.getMethodName(),
169-
builder.parameters.stream().map(p -> p.name).collect(joining(", ")));
206+
parameters.isEmpty() ? "" : additionalParameters);
207+
170208
return builder;
171209
}
172210

@@ -175,7 +213,9 @@ protected MethodSpec.Builder paginatedMethodBody(MethodSpec.Builder builder, Ope
175213
String methodName = PaginatorUtils.getPaginatedMethodName(opModel.getMethodName());
176214
return builder.addModifiers(PUBLIC)
177215
.addAnnotation(Override.class)
178-
.addStatement("return delegate.$N($N)", methodName, opModel.getInput().getVariableName());
216+
.addStatement("return invokeOperation($N, request -> delegate.$N(request))",
217+
opModel.getInput().getVariableName(),
218+
methodName);
179219
}
180220

181221

codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/DelegatingSyncClientClass.java

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,20 @@
1919
import static javax.lang.model.element.Modifier.ABSTRACT;
2020
import static javax.lang.model.element.Modifier.FINAL;
2121
import static javax.lang.model.element.Modifier.PRIVATE;
22+
import static javax.lang.model.element.Modifier.PROTECTED;
2223
import static javax.lang.model.element.Modifier.PUBLIC;
24+
import static software.amazon.awssdk.codegen.poet.client.AsyncClientInterface.STREAMING_TYPE_VARIABLE;
2325

2426
import com.squareup.javapoet.ClassName;
2527
import com.squareup.javapoet.FieldSpec;
2628
import com.squareup.javapoet.MethodSpec;
29+
import com.squareup.javapoet.ParameterSpec;
30+
import com.squareup.javapoet.ParameterizedTypeName;
2731
import com.squareup.javapoet.TypeSpec;
32+
import com.squareup.javapoet.TypeVariableName;
33+
import java.util.ArrayList;
2834
import java.util.List;
35+
import java.util.function.Function;
2936
import software.amazon.awssdk.annotations.SdkPublicApi;
3037
import software.amazon.awssdk.codegen.docs.SimpleMethodOverload;
3138
import software.amazon.awssdk.codegen.model.config.customization.UtilitiesMethod;
@@ -89,14 +96,9 @@ protected void addConsumerMethod(List<MethodSpec> specs, MethodSpec spec, Simple
8996

9097
@Override
9198
protected void addAdditionalMethods(TypeSpec.Builder type) {
92-
MethodSpec delegate = MethodSpec.methodBuilder("delegate")
93-
.addModifiers(PUBLIC)
94-
.addStatement("return this.delegate")
95-
.returns(SdkClient.class)
96-
.build();
97-
9899
type.addMethod(nameMethod())
99-
.addMethod(delegate);
100+
.addMethod(delegateMethod())
101+
.addMethod(invokeMethod());
100102
}
101103

102104
@Override
@@ -125,9 +127,19 @@ protected MethodSpec.Builder operationBody(MethodSpec.Builder builder, Operation
125127
builder.addModifiers(PUBLIC)
126128
.addAnnotation(Override.class);
127129

128-
builder.addStatement("return delegate.$N($L)",
130+
if (builder.parameters.size() < 1) {
131+
throw new IllegalStateException("All client methods must have an argument");
132+
}
133+
134+
List<ParameterSpec> operationParameters = new ArrayList<>(builder.parameters);
135+
String requestParameter = operationParameters.remove(0).name;
136+
String additionalParameters = String.format(", %s", operationParameters.stream().map(p -> p.name).collect(joining(", ")));
137+
138+
builder.addStatement("return invokeOperation($N, request -> delegate.$N(request$N))",
139+
requestParameter,
129140
opModel.getMethodName(),
130-
builder.parameters.stream().map(p -> p.name).collect(joining(", ")));
141+
operationParameters.isEmpty() ? "" : additionalParameters);
142+
131143
return builder;
132144
}
133145

@@ -136,7 +148,9 @@ protected MethodSpec.Builder paginatedMethodBody(MethodSpec.Builder builder, Ope
136148
String methodName = PaginatorUtils.getPaginatedMethodName(opModel.getMethodName());
137149
return builder.addModifiers(PUBLIC)
138150
.addAnnotation(Override.class)
139-
.addStatement("return delegate.$N($N)", methodName, opModel.getInput().getVariableName());
151+
.addStatement("return invokeOperation($N, request -> delegate.$N(request))",
152+
opModel.getInput().getVariableName(),
153+
methodName);
140154
}
141155

142156
@Override
@@ -167,6 +181,34 @@ private MethodSpec nameMethod() {
167181
.build();
168182
}
169183

184+
private MethodSpec delegateMethod() {
185+
return MethodSpec.methodBuilder("delegate")
186+
.addModifiers(PUBLIC)
187+
.addStatement("return this.delegate")
188+
.returns(SdkClient.class)
189+
.build();
190+
}
191+
192+
private MethodSpec invokeMethod() {
193+
TypeVariableName requestTypeVariableName =
194+
TypeVariableName.get("T", poetExtensions.getModelClass(model.getSdkRequestBaseClassName()));
195+
196+
TypeVariableName responseTypeVariableName = STREAMING_TYPE_VARIABLE;
197+
198+
ParameterizedTypeName functionTypeName = ParameterizedTypeName
199+
.get(ClassName.get(Function.class), requestTypeVariableName, responseTypeVariableName);
200+
201+
return MethodSpec.methodBuilder("invokeOperation")
202+
.addModifiers(PROTECTED)
203+
.addParameter(requestTypeVariableName, "request")
204+
.addParameter(functionTypeName, "operation")
205+
.addTypeVariable(requestTypeVariableName)
206+
.addTypeVariable(responseTypeVariableName)
207+
.returns(responseTypeVariableName)
208+
.addStatement("return operation.apply(request)")
209+
.build();
210+
}
211+
170212
@Override
171213
protected MethodSpec serviceClientConfigMethod() {
172214
return MethodSpec.methodBuilder("serviceClientConfiguration")

0 commit comments

Comments
 (0)