Skip to content

Commit 3352194

Browse files
authored
Validate required params present before running rules (#3946)
Add validation that ensures that required params are present on the endpoint params object before evaluating the rule-set.
1 parent 520956a commit 3352194

File tree

3 files changed

+62
-0
lines changed

3 files changed

+62
-0
lines changed

codegen/src/main/java/software/amazon/awssdk/codegen/poet/rules/EndpointProviderSpec.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import software.amazon.awssdk.codegen.poet.ClassSpec;
3434
import software.amazon.awssdk.codegen.poet.PoetUtils;
3535
import software.amazon.awssdk.utils.CompletableFutureUtils;
36+
import software.amazon.awssdk.utils.Validate;
3637

3738
public class EndpointProviderSpec implements ClassSpec {
3839
private static final String RULE_SET_FIELD_NAME = "ENDPOINT_RULE_SET";
@@ -132,6 +133,8 @@ private MethodSpec resolveEndpointMethod() {
132133
.addAnnotation(Override.class)
133134
.addParameter(endpointRulesSpecUtils.parametersClassName(), paramsName);
134135

136+
b.addCode(validateRequiredParams());
137+
135138
b.addStatement("$T res = new $T().evaluate($N, toIdentifierValueMap($N))",
136139
endpointRulesSpecUtils.rulesRuntimeClassName("Value"),
137140
endpointRulesSpecUtils.rulesRuntimeClassName("DefaultRuleEngine"),
@@ -161,4 +164,21 @@ private MethodSpec ruleSetBuildMethod(TypeSpec.Builder classBuilder) {
161164
ruleSetCreationSpec.helperMethods().forEach(classBuilder::addMethod);
162165
return b.build();
163166
}
167+
168+
private CodeBlock validateRequiredParams() {
169+
CodeBlock.Builder b = CodeBlock.builder();
170+
171+
Map<String, ParameterModel> parameters = intermediateModel.getEndpointRuleSetModel().getParameters();
172+
parameters.entrySet().stream()
173+
.filter(e -> Boolean.TRUE.equals(e.getValue().isRequired()))
174+
.forEach(e -> {
175+
b.addStatement("$T.notNull($N.$N(), $S)",
176+
Validate.class,
177+
"endpointParams",
178+
endpointRulesSpecUtils.paramMethodName(e.getKey()),
179+
String.format("Parameter '%s' must not be null", e.getKey()));
180+
});
181+
182+
return b.build();
183+
}
164184
}

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/rules/endpoint-provider-class.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import software.amazon.awssdk.services.query.endpoints.QueryEndpointProvider;
1212
import software.amazon.awssdk.utils.CompletableFutureUtils;
1313
import software.amazon.awssdk.utils.MapUtils;
14+
import software.amazon.awssdk.utils.Validate;
1415

1516
@Generated("software.amazon.awssdk:codegen")
1617
@SdkInternalApi
@@ -19,6 +20,7 @@ public final class DefaultQueryEndpointProvider implements QueryEndpointProvider
1920

2021
@Override
2122
public CompletableFuture<Endpoint> resolveEndpoint(QueryEndpointParams endpointParams) {
23+
Validate.notNull(endpointParams.region(), "Parameter 'region' must not be null");
2224
Value res = new DefaultRuleEngine().evaluate(ENDPOINT_RULE_SET, toIdentifierValueMap(endpointParams));
2325
try {
2426
return CompletableFuture.completedFuture(AwsEndpointProviderUtils.valueAsEndpointOrThrow(res));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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.services.endpointproviders;
17+
18+
import static org.assertj.core.api.Assertions.assertThatNoException;
19+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
20+
21+
import org.junit.jupiter.api.Test;
22+
import software.amazon.awssdk.regions.Region;
23+
import software.amazon.awssdk.services.restjsonendpointproviders.endpoints.RestJsonEndpointProvidersEndpointProvider;
24+
25+
public class EndpointProviderTest {
26+
@Test
27+
public void resolveEndpoint_requiredParamNotPresent_throws() {
28+
assertThatThrownBy(() -> RestJsonEndpointProvidersEndpointProvider.defaultProvider()
29+
.resolveEndpoint(r -> {}))
30+
.hasMessageContaining("must not be null");
31+
}
32+
33+
@Test
34+
public void resolveEndpoint_optionalParamNotPresent_doesNotThrow() {
35+
assertThatNoException().isThrownBy(() ->
36+
RestJsonEndpointProvidersEndpointProvider.defaultProvider()
37+
.resolveEndpoint(r -> r.useFips(null)
38+
.region(Region.of("us-mars-1"))));
39+
}
40+
}

0 commit comments

Comments
 (0)