diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/AddShapes.java b/codegen/src/main/java/software/amazon/awssdk/codegen/AddShapes.java index 19600e33210e..e6daed69595e 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/AddShapes.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/AddShapes.java @@ -311,18 +311,67 @@ private ParameterHttpMapping generateParameterHttpMapping(Shape parentShape, ParameterHttpMapping mapping = new ParameterHttpMapping(); + // Per the Smithy spec, HTTP binding traits are only honored on top-level shapes (direct operation + // input/output/error). When a location trait is ignored, its locationName is also ignored so the member + // name is used as the wire name. https://smithy.io/2.0/spec/http-bindings.html + Location resolvedLocation = resolveLocation(parentShape, member, allC2jShapes); + boolean locationIgnored = member.getLocation() != null && resolvedLocation == null; + Shape memberShape = allC2jShapes.get(member.getShape()); - mapping.withLocation(Location.forValue(member.getLocation())) + String marshallLocationName = locationIgnored + ? memberName : deriveMarshallerLocationName(memberShape, memberName, member, protocol); + String unmarshallLocationName = locationIgnored + ? memberName : deriveUnmarshallerLocationName(memberShape, memberName, member); + + mapping.withLocation(resolvedLocation) .withPayload(member.isPayload()).withStreaming(member.isStreaming()) .withFlattened(isFlattened(member, memberShape)) - .withUnmarshallLocationName(deriveUnmarshallerLocationName(memberShape, memberName, member)) - .withMarshallLocationName( - deriveMarshallerLocationName(memberShape, memberName, member, protocol)) + .withUnmarshallLocationName(unmarshallLocationName) + .withMarshallLocationName(marshallLocationName) .withIsGreedy(isGreedy(parentShape, allC2jShapes, mapping)); return mapping; } + private Location resolveLocation(Shape parentShape, Member member, Map allC2jShapes) { + Location location = Location.forValue(member.getLocation()); + if (location == null) { + return null; + } + switch (location) { + case URI: + case QUERY_STRING: + return isDirectInputShape(parentShape, allC2jShapes) ? location : null; + case HEADER: + case HEADERS: + return isTopLevelShape(parentShape, allC2jShapes) ? location : null; + case STATUS_CODE: + return isDirectOutputShape(parentShape, allC2jShapes) ? location : null; + default: + return location; + } + } + + private boolean isDirectInputShape(Shape shape, Map allC2jShapes) { + return builder.getService().getOperations().values().stream() + .filter(o -> o.getInput() != null) + .anyMatch(o -> allC2jShapes.get(o.getInput().getShape()).equals(shape)); + } + + private boolean isDirectOutputShape(Shape shape, Map allC2jShapes) { + return builder.getService().getOperations().values().stream() + .filter(o -> o.getOutput() != null) + .anyMatch(o -> allC2jShapes.get(o.getOutput().getShape()).equals(shape)); + } + + private boolean isTopLevelShape(Shape shape, Map allC2jShapes) { + return builder.getService().getOperations().values().stream() + .anyMatch(o -> (o.getInput() != null && allC2jShapes.get(o.getInput().getShape()).equals(shape)) + || (o.getOutput() != null && allC2jShapes.get(o.getOutput().getShape()).equals(shape)) + || (o.getErrors() != null && o.getErrors().stream() + .anyMatch(e -> allC2jShapes.get(e.getShape()).equals(shape)))); + } + private boolean isFlattened(Member member, Shape memberShape) { return member.isFlattened() || memberShape.isFlattened(); @@ -342,9 +391,9 @@ private boolean isRequiredMember(String memberName, Shape memberShape) { */ private boolean isGreedy(Shape parentShape, Map allC2jShapes, ParameterHttpMapping mapping) { if (mapping.getLocation() == Location.URI) { - // If the location is URI we can assume the parent shape is an input shape. - String requestUri = findRequestUri(parentShape, allC2jShapes); - if (requestUri.contains(String.format("{%s+}", mapping.getMarshallLocationName()))) { + Optional requestUri = findRequestUri(parentShape, allC2jShapes); + if (requestUri.isPresent() + && requestUri.get().contains(String.format("{%s+}", mapping.getMarshallLocationName()))) { return true; } } @@ -352,28 +401,42 @@ private boolean isGreedy(Shape parentShape, Map allC2jShapes, Par } /** - * Given an input shape, finds the Request URI for the operation that input is referenced from. + * Given a shape, finds the Request URI for the operation that references it as input. + * Returns empty if the shape is not a direct operation input. * - * @param parentShape Input shape to find operation's request URI for. + * @param parentShape Shape to find operation's request URI for. * @param allC2jShapes All shapes in the service model. - * @return Request URI for operation. - * @throws RuntimeException If operation can't be found. + * @return Request URI for operation, or empty if the shape is not a direct operation input. */ - private String findRequestUri(Shape parentShape, Map allC2jShapes) { + private Optional findRequestUri(Shape parentShape, Map allC2jShapes) { Optional operation = builder.getService().getOperations().values().stream() .filter(o -> o.getInput() != null) .filter(o -> allC2jShapes.get(o.getInput().getShape()).equals(parentShape)) .findFirst(); - return operation.map(o -> o.getHttp().getRequestUri()) - .orElseThrow(() -> { - String detailMsg = "Could not find request URI for input shape for operation: " + operation; - ValidationEntry entry = - new ValidationEntry().withErrorId(ValidationErrorId.REQUEST_URI_NOT_FOUND) - .withDetailMessage(detailMsg) - .withSeverity(ValidationErrorSeverity.DANGER); - return ModelInvalidException.builder().validationEntries(Collections.singletonList(entry)).build(); - }); + if (!operation.isPresent()) { + // Not a direct operation input shape, should be ignored. + // https://smithy.io/2.0/spec/http-bindings.html#httplabel-is-only-used-on-top-level-input + return Optional.empty(); + } + + String requestUri = operation.get().getHttp().getRequestUri(); + if (requestUri == null) { + String shapeName = allC2jShapes.entrySet().stream() + .filter(e -> e.getValue().equals(parentShape)) + .map(Map.Entry::getKey) + .findFirst() + .orElseThrow(() -> new IllegalStateException("Shape not found in model: " + parentShape)); + String detailMsg = "Operation referencing input shape '" + shapeName + + "' has no requestUri configured in its HTTP binding."; + ValidationEntry entry = + new ValidationEntry().withErrorId(ValidationErrorId.REQUEST_URI_NOT_FOUND) + .withDetailMessage(detailMsg) + .withSeverity(ValidationErrorSeverity.DANGER); + throw ModelInvalidException.builder().validationEntries(Collections.singletonList(entry)).build(); + } + + return Optional.of(requestUri); } private String deriveUnmarshallerLocationName(Shape memberShape, String memberName, Member member) { diff --git a/codegen/src/test/java/software/amazon/awssdk/codegen/AddShapesTest.java b/codegen/src/test/java/software/amazon/awssdk/codegen/AddShapesTest.java index dde88dd226e0..992ae5d602e8 100644 --- a/codegen/src/test/java/software/amazon/awssdk/codegen/AddShapesTest.java +++ b/codegen/src/test/java/software/amazon/awssdk/codegen/AddShapesTest.java @@ -84,8 +84,37 @@ void generateShapeModel_memberRequiredByNestedShape_setsMemberModelAsRequired() MemberModel requiredMemberModel = requestShapeModel.findMemberModelByC2jName(queryParamName); assertThat(requestShapeModel.getRequired()).contains(queryParamName); - assertThat(requiredMemberModel.getHttp().getLocation()).isEqualTo(Location.QUERY_STRING); + assertThat(requiredMemberModel.getHttp().getLocation()).isNull(); assertThat(requiredMemberModel.isRequired()).isTrue(); } + @Test + void generateShapeModel_locationOnNestedShape_isIgnored() { + ShapeModel nestedShape = intermediateModel.getShapes().get("NestedQueryParameterOperation"); + MemberModel queryParam = nestedShape.findMemberModelByC2jName("QueryParamOne"); + assertThat(queryParam.getHttp().getLocation()).isNull(); + } + + @Test + void generateShapeModel_locationOnDirectInputShape_isPreserved() { + ShapeModel inputShape = intermediateModel.getShapes().get("QueryParameterOperationRequest"); + assertThat(inputShape.findMemberModelByC2jName("PathParam").getHttp().getLocation()).isEqualTo(Location.URI); + assertThat(inputShape.findMemberModelByC2jName("QueryParamOne").getHttp().getLocation()).isEqualTo(Location.QUERY_STRING); + assertThat(inputShape.findMemberModelByC2jName("StringHeaderMember").getHttp().getLocation()).isEqualTo(Location.HEADER); + } + + @Test + void generateShapeModel_locationNameOnNestedShape_usesMemberNameForMarshalling() { + ShapeModel inputShape = intermediateModel.getShapes().get("NestedQueryParameterOperation"); + assertThat(inputShape.findMemberModelByC2jName("NestedHeaderMember").getHttp().getMarshallLocationName()).isEqualTo("NestedHeaderMember"); + } + + @Test + void generateShapeModel_locationNameOnTopLevelShape_honorsLocationName() { + ShapeModel inputShape = intermediateModel.getShapes().get("QueryParameterOperationRequest"); + MemberModel member = inputShape.findMemberModelByC2jName("PayloadMemberWithCustomName"); + assertThat(member.getHttp().getLocation()).isNull(); + assertThat(member.getHttp().getMarshallLocationName()).isEqualTo("CustomWireName"); + } + } diff --git a/codegen/src/test/java/software/amazon/awssdk/codegen/CodeGeneratorTest.java b/codegen/src/test/java/software/amazon/awssdk/codegen/CodeGeneratorTest.java index 05a492ca24c4..26b65c66d04e 100644 --- a/codegen/src/test/java/software/amazon/awssdk/codegen/CodeGeneratorTest.java +++ b/codegen/src/test/java/software/amazon/awssdk/codegen/CodeGeneratorTest.java @@ -16,6 +16,7 @@ package software.amazon.awssdk.codegen; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatNoException; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; @@ -43,7 +44,9 @@ import software.amazon.awssdk.codegen.model.config.customization.CustomizationConfig; import software.amazon.awssdk.codegen.model.config.customization.UnderscoresInNameBehavior; import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel; +import software.amazon.awssdk.codegen.model.intermediate.ShapeModel; import software.amazon.awssdk.codegen.model.rules.endpoints.EndpointTestSuiteModel; +import software.amazon.awssdk.codegen.model.service.Location; import software.amazon.awssdk.codegen.model.service.ServiceModel; import software.amazon.awssdk.codegen.poet.ClientTestModels; import software.amazon.awssdk.codegen.validation.ModelInvalidException; @@ -176,6 +179,41 @@ void execute_endpointsTestReferencesUnknownOperationMember_throwsValidationError }); } + @Test + void execute_uriLocationOnNonInputShape_isIgnored() throws IOException { + C2jModels models = C2jModels.builder() + .customizationConfig(CustomizationConfig.create()) + .serviceModel(getUriOnNonInputShapeServiceModel()) + .build(); + + // Per the Smithy spec, httpLabel on non-input shapes has no meaning and is simply ignored. + assertThatNoException().isThrownBy( + () -> generateCodeFromC2jModels(models, outputDir, true, Collections.emptyList())); + + IntermediateModel intermediateModel = new IntermediateModelBuilder(models).build(); + + ShapeModel inputShape = intermediateModel.getShapes().get("SomeOperationRequest"); + assertThat(inputShape.findMemberModelByC2jName("thingId").getHttp().getLocation()).isEqualTo(Location.URI); + + ShapeModel nestedShape = intermediateModel.getShapes().get("NestedOptions"); + assertThat(nestedShape.findMemberModelByC2jName("pageSize").getHttp().getLocation()).isNull(); + assertThat(nestedShape.findMemberModelByC2jName("pageSize").getHttp().isGreedy()).isFalse(); + assertThat(nestedShape.findMemberModelByC2jName("headerParam").getHttp().getLocation()).isNull(); + assertThat(nestedShape.findMemberModelByC2jName("queryParam").getHttp().getLocation()).isNull(); + assertThat(nestedShape.findMemberModelByC2jName("prefixHeaders").getHttp().getLocation()).isNull(); + + ShapeModel sharedShape = intermediateModel.getShapes().get("SharedShapeOperationRequest"); + assertThat(sharedShape.findMemberModelByC2jName("sharedId").getHttp().getLocation()).isEqualTo(Location.URI); + + Path generatedNestedOptions = Files.walk(outputDir) + .filter(p -> p.getFileName().toString().equals("NestedOptions.java")) + .findFirst() + .orElseThrow(() -> new AssertionError("NestedOptions.java not found in generated output")); + String actual = new String(Files.readAllBytes(generatedNestedOptions), StandardCharsets.UTF_8); + String expected = resourceAsString("expected-nested-options.java"); + assertThat(actual).isEqualTo(expected); + } + @Test void execute_operationHasNoRequestUri_throwsValidationError() throws IOException { C2jModels models = C2jModels.builder() @@ -186,7 +224,10 @@ void execute_operationHasNoRequestUri_throwsValidationError() throws IOException assertThatThrownBy(() -> generateCodeFromC2jModels(models, outputDir, true, Collections.emptyList())) .isInstanceOf(ModelInvalidException.class) .matches(e -> ((ModelInvalidException) e).validationEntries().get(0).getErrorId() - == ValidationErrorId.REQUEST_URI_NOT_FOUND); + == ValidationErrorId.REQUEST_URI_NOT_FOUND) + .matches(e -> ((ModelInvalidException) e).validationEntries().get(0).getDetailMessage() + .equals("Operation referencing input shape 'OperationWithUriMappedParamRequest'" + + " has no requestUri configured in its HTTP binding.")); } private void generateCodeFromC2jModels(C2jModels c2jModels, Path outputDir) { @@ -244,6 +285,11 @@ private ServiceModel getMissingRequestUriServiceModel() throws IOException { return Jackson.load(ServiceModel.class, json); } + private ServiceModel getUriOnNonInputShapeServiceModel() throws IOException { + String json = resourceAsString("uri-on-non-input-shape-service.json"); + return Jackson.load(ServiceModel.class, json); + } + private String resourceAsString(String name) throws IOException { ByteArrayOutputStream baos; try (InputStream resourceAsStream = getClass().getResourceAsStream(name)) { diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/expected-nested-options.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/expected-nested-options.java new file mode 100644 index 000000000000..b08ba3f6b643 --- /dev/null +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/expected-nested-options.java @@ -0,0 +1,378 @@ +/* + * 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.restjson.model; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.Function; +import software.amazon.awssdk.annotations.Generated; +import software.amazon.awssdk.annotations.Mutable; +import software.amazon.awssdk.annotations.NotThreadSafe; +import software.amazon.awssdk.core.SdkField; +import software.amazon.awssdk.core.SdkPojo; +import software.amazon.awssdk.core.protocol.MarshallLocation; +import software.amazon.awssdk.core.protocol.MarshallingType; +import software.amazon.awssdk.core.traits.LocationTrait; +import software.amazon.awssdk.core.traits.MapTrait; +import software.amazon.awssdk.core.util.DefaultSdkAutoConstructMap; +import software.amazon.awssdk.core.util.SdkAutoConstructMap; +import software.amazon.awssdk.utils.ToString; +import software.amazon.awssdk.utils.builder.CopyableBuilder; +import software.amazon.awssdk.utils.builder.ToCopyableBuilder; + +/** + */ +@Generated("software.amazon.awssdk:codegen") +public final class NestedOptions implements SdkPojo, Serializable, ToCopyableBuilder { + private static final SdkField PAGE_SIZE_FIELD = SdkField. builder(MarshallingType.STRING) + .memberName("pageSize").getter(getter(NestedOptions::pageSize)).setter(setter(Builder::pageSize)) + .traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("pageSize").build()).build(); + + private static final SdkField HEADER_PARAM_FIELD = SdkField. builder(MarshallingType.STRING) + .memberName("headerParam").getter(getter(NestedOptions::headerParam)).setter(setter(Builder::headerParam)) + .traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("headerParam").build()).build(); + + private static final SdkField QUERY_PARAM_FIELD = SdkField. builder(MarshallingType.STRING) + .memberName("queryParam").getter(getter(NestedOptions::queryParam)).setter(setter(Builder::queryParam)) + .traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("queryParam").build()).build(); + + private static final SdkField> PREFIX_HEADERS_FIELD = SdkField + .> builder(MarshallingType.MAP) + .memberName("prefixHeaders") + .getter(getter(NestedOptions::prefixHeaders)) + .setter(setter(Builder::prefixHeaders)) + .traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("prefixHeaders").build(), + MapTrait.builder() + .keyLocationName("key") + .valueLocationName("value") + .valueFieldInfo( + SdkField. builder(MarshallingType.STRING) + .traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD) + .locationName("value").build()).build()).build()).build(); + + private static final List> SDK_FIELDS = Collections.unmodifiableList(Arrays.asList(PAGE_SIZE_FIELD, + HEADER_PARAM_FIELD, QUERY_PARAM_FIELD, PREFIX_HEADERS_FIELD)); + + private static final Map> SDK_NAME_TO_FIELD = memberNameToFieldInitializer(); + + private static final long serialVersionUID = 1L; + + private final String pageSize; + + private final String headerParam; + + private final String queryParam; + + private final Map prefixHeaders; + + private NestedOptions(BuilderImpl builder) { + this.pageSize = builder.pageSize; + this.headerParam = builder.headerParam; + this.queryParam = builder.queryParam; + this.prefixHeaders = builder.prefixHeaders; + } + + /** + * Returns the value of the PageSize property for this object. + * + * @return The value of the PageSize property for this object. + */ + public final String pageSize() { + return pageSize; + } + + /** + * Returns the value of the HeaderParam property for this object. + * + * @return The value of the HeaderParam property for this object. + */ + public final String headerParam() { + return headerParam; + } + + /** + * Returns the value of the QueryParam property for this object. + * + * @return The value of the QueryParam property for this object. + */ + public final String queryParam() { + return queryParam; + } + + /** + * For responses, this returns true if the service returned a value for the PrefixHeaders property. This DOES NOT + * check that the value is non-empty (for which, you should check the {@code isEmpty()} method on the property). + * This is useful because the SDK will never return a null collection or map, but you may need to differentiate + * between the service returning nothing (or null) and the service returning an empty collection or map. For + * requests, this returns true if a value for the property was specified in the request builder, and false if a + * value was not specified. + */ + public final boolean hasPrefixHeaders() { + return prefixHeaders != null && !(prefixHeaders instanceof SdkAutoConstructMap); + } + + /** + * Returns the value of the PrefixHeaders property for this object. + *

+ * Attempts to modify the collection returned by this method will result in an UnsupportedOperationException. + *

+ *

+ * This method will never return null. If you would like to know whether the service returned this field (so that + * you can differentiate between null and empty), you can use the {@link #hasPrefixHeaders} method. + *

+ * + * @return The value of the PrefixHeaders property for this object. + */ + public final Map prefixHeaders() { + return prefixHeaders; + } + + @Override + public Builder toBuilder() { + return new BuilderImpl(this); + } + + public static Builder builder() { + return new BuilderImpl(); + } + + public static Class serializableBuilderClass() { + return BuilderImpl.class; + } + + @Override + public final int hashCode() { + int hashCode = 1; + hashCode = 31 * hashCode + Objects.hashCode(pageSize()); + hashCode = 31 * hashCode + Objects.hashCode(headerParam()); + hashCode = 31 * hashCode + Objects.hashCode(queryParam()); + hashCode = 31 * hashCode + Objects.hashCode(hasPrefixHeaders() ? prefixHeaders() : null); + return hashCode; + } + + @Override + public final boolean equals(Object obj) { + return equalsBySdkFields(obj); + } + + @Override + public final boolean equalsBySdkFields(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof NestedOptions)) { + return false; + } + NestedOptions other = (NestedOptions) obj; + return Objects.equals(pageSize(), other.pageSize()) && Objects.equals(headerParam(), other.headerParam()) + && Objects.equals(queryParam(), other.queryParam()) && hasPrefixHeaders() == other.hasPrefixHeaders() + && Objects.equals(prefixHeaders(), other.prefixHeaders()); + } + + /** + * Returns a string representation of this object. This is useful for testing and debugging. Sensitive data will be + * redacted from this string using a placeholder value. + */ + @Override + public final String toString() { + return ToString.builder("NestedOptions").add("PageSize", pageSize()).add("HeaderParam", headerParam()) + .add("QueryParam", queryParam()).add("PrefixHeaders", hasPrefixHeaders() ? prefixHeaders() : null).build(); + } + + public final Optional getValueForField(String fieldName, Class clazz) { + switch (fieldName) { + case "pageSize": + return Optional.ofNullable(clazz.cast(pageSize())); + case "headerParam": + return Optional.ofNullable(clazz.cast(headerParam())); + case "queryParam": + return Optional.ofNullable(clazz.cast(queryParam())); + case "prefixHeaders": + return Optional.ofNullable(clazz.cast(prefixHeaders())); + default: + return Optional.empty(); + } + } + + @Override + public final List> sdkFields() { + return SDK_FIELDS; + } + + @Override + public final Map> sdkFieldNameToField() { + return SDK_NAME_TO_FIELD; + } + + private static Map> memberNameToFieldInitializer() { + Map> map = new HashMap<>(); + map.put("pageSize", PAGE_SIZE_FIELD); + map.put("headerParam", HEADER_PARAM_FIELD); + map.put("queryParam", QUERY_PARAM_FIELD); + map.put("prefixHeaders", PREFIX_HEADERS_FIELD); + return Collections.unmodifiableMap(map); + } + + private static Function getter(Function g) { + return obj -> g.apply((NestedOptions) obj); + } + + private static BiConsumer setter(BiConsumer s) { + return (obj, val) -> s.accept((Builder) obj, val); + } + + @Mutable + @NotThreadSafe + public interface Builder extends SdkPojo, CopyableBuilder { + /** + * Sets the value of the PageSize property for this object. + * + * @param pageSize + * The new value for the PageSize property for this object. + * @return Returns a reference to this object so that method calls can be chained together. + */ + Builder pageSize(String pageSize); + + /** + * Sets the value of the HeaderParam property for this object. + * + * @param headerParam + * The new value for the HeaderParam property for this object. + * @return Returns a reference to this object so that method calls can be chained together. + */ + Builder headerParam(String headerParam); + + /** + * Sets the value of the QueryParam property for this object. + * + * @param queryParam + * The new value for the QueryParam property for this object. + * @return Returns a reference to this object so that method calls can be chained together. + */ + Builder queryParam(String queryParam); + + /** + * Sets the value of the PrefixHeaders property for this object. + * + * @param prefixHeaders + * The new value for the PrefixHeaders property for this object. + * @return Returns a reference to this object so that method calls can be chained together. + */ + Builder prefixHeaders(Map prefixHeaders); + } + + static final class BuilderImpl implements Builder { + private String pageSize; + + private String headerParam; + + private String queryParam; + + private Map prefixHeaders = DefaultSdkAutoConstructMap.getInstance(); + + private BuilderImpl() { + } + + private BuilderImpl(NestedOptions model) { + pageSize(model.pageSize); + headerParam(model.headerParam); + queryParam(model.queryParam); + prefixHeaders(model.prefixHeaders); + } + + public final String getPageSize() { + return pageSize; + } + + public final void setPageSize(String pageSize) { + this.pageSize = pageSize; + } + + @Override + public final Builder pageSize(String pageSize) { + this.pageSize = pageSize; + return this; + } + + public final String getHeaderParam() { + return headerParam; + } + + public final void setHeaderParam(String headerParam) { + this.headerParam = headerParam; + } + + @Override + public final Builder headerParam(String headerParam) { + this.headerParam = headerParam; + return this; + } + + public final String getQueryParam() { + return queryParam; + } + + public final void setQueryParam(String queryParam) { + this.queryParam = queryParam; + } + + @Override + public final Builder queryParam(String queryParam) { + this.queryParam = queryParam; + return this; + } + + public final Map getPrefixHeaders() { + if (prefixHeaders instanceof SdkAutoConstructMap) { + return null; + } + return prefixHeaders; + } + + public final void setPrefixHeaders(Map prefixHeaders) { + this.prefixHeaders = MapOfStringsCopier.copy(prefixHeaders); + } + + @Override + public final Builder prefixHeaders(Map prefixHeaders) { + this.prefixHeaders = MapOfStringsCopier.copy(prefixHeaders); + return this; + } + + @Override + public NestedOptions build() { + return new NestedOptions(this); + } + + @Override + public List> sdkFields() { + return SDK_FIELDS; + } + + @Override + public Map> sdkFieldNameToField() { + return SDK_NAME_TO_FIELD; + } + } +} diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/nestedqueryparameteroperation.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/nestedqueryparameteroperation.java index c935db9281f0..7b04d3d9f97d 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/nestedqueryparameteroperation.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/nestedqueryparameteroperation.java @@ -26,218 +26,308 @@ /** */ @Generated("software.amazon.awssdk:codegen") -public final class NestedQueryParameterOperation implements SdkPojo, Serializable, - ToCopyableBuilder { - private static final SdkField QUERY_PARAM_ONE_FIELD = SdkField - . builder(MarshallingType.STRING) - .memberName("QueryParamOne") - .getter(getter(NestedQueryParameterOperation::queryParamOne)) - .setter(setter(Builder::queryParamOne)) - .traits(LocationTrait.builder().location(MarshallLocation.QUERY_PARAM).locationName("QueryParamOne").build(), - RequiredTrait.create()).build(); - - private static final SdkField QUERY_PARAM_TWO_FIELD = SdkField. builder(MarshallingType.STRING) - .memberName("QueryParamTwo").getter(getter(NestedQueryParameterOperation::queryParamTwo)) - .setter(setter(Builder::queryParamTwo)) - .traits(LocationTrait.builder().location(MarshallLocation.QUERY_PARAM).locationName("QueryParamTwo").build()).build(); - - private static final List> SDK_FIELDS = Collections.unmodifiableList(Arrays.asList(QUERY_PARAM_ONE_FIELD, - QUERY_PARAM_TWO_FIELD)); - - private static final Map> SDK_NAME_TO_FIELD = memberNameToFieldInitializer(); - - private static final long serialVersionUID = 1L; - - private final String queryParamOne; - - private final String queryParamTwo; - - private NestedQueryParameterOperation(BuilderImpl builder) { - this.queryParamOne = builder.queryParamOne; - this.queryParamTwo = builder.queryParamTwo; +public final class NestedQueryParameterOperation implements SdkPojo, Serializable, ToCopyableBuilder { + private static final SdkField QUERY_PARAM_ONE_FIELD = SdkField.builder(MarshallingType.STRING) + .memberName("QueryParamOne") + .getter(getter(NestedQueryParameterOperation::queryParamOne)) + .setter(setter(Builder::queryParamOne)) + .traits(LocationTrait.builder() + .location(MarshallLocation.PAYLOAD) + .locationName("QueryParamOne") + .build(), RequiredTrait.create()).build(); + + private static final SdkField QUERY_PARAM_TWO_FIELD = SdkField.builder(MarshallingType.STRING) + .memberName("QueryParamTwo") + .getter(getter(NestedQueryParameterOperation::queryParamTwo)) + .setter(setter(Builder::queryParamTwo)) + .traits(LocationTrait.builder() + .location(MarshallLocation.PAYLOAD) + .locationName("QueryParamTwo") + .build()).build(); + + private static final SdkField NESTED_HEADER_MEMBER_FIELD = SdkField.builder(MarshallingType.STRING) + .memberName("NestedHeaderMember") + .getter(getter(NestedQueryParameterOperation::nestedHeaderMember)) + .setter(setter(Builder::nestedHeaderMember)) + .traits(LocationTrait.builder() + .location(MarshallLocation.PAYLOAD) + .locationName("NestedHeaderMember") + .build()).build(); + + private static final SdkField NESTED_STATUS_CODE_FIELD = SdkField.builder(MarshallingType.INTEGER) + .memberName("NestedStatusCode") + .getter(getter(NestedQueryParameterOperation::nestedStatusCode)) + .setter(setter(Builder::nestedStatusCode)) + .traits(LocationTrait.builder() + .location(MarshallLocation.PAYLOAD) + .locationName("NestedStatusCode") + .build()).build(); + + private static final List> SDK_FIELDS = Collections.unmodifiableList(Arrays.asList(QUERY_PARAM_ONE_FIELD,QUERY_PARAM_TWO_FIELD,NESTED_HEADER_MEMBER_FIELD,NESTED_STATUS_CODE_FIELD)); + + private static final Map> SDK_NAME_TO_FIELD = memberNameToFieldInitializer(); + + private static final long serialVersionUID = 1L; + + private final String queryParamOne; + + private final String queryParamTwo; + + private final String nestedHeaderMember; + + private final Integer nestedStatusCode; + + private NestedQueryParameterOperation(BuilderImpl builder) { + this.queryParamOne = builder.queryParamOne; + this.queryParamTwo = builder.queryParamTwo; + this.nestedHeaderMember = builder.nestedHeaderMember; + this.nestedStatusCode = builder.nestedStatusCode; + } + + /** + * Returns the value of the QueryParamOne property for this object. + * @return The value of the QueryParamOne property for this object. + */ + public final String queryParamOne() { + return queryParamOne; + } + + /** + * Returns the value of the QueryParamTwo property for this object. + * @return The value of the QueryParamTwo property for this object. + */ + public final String queryParamTwo() { + return queryParamTwo; + } + + /** + * Returns the value of the NestedHeaderMember property for this object. + * @return The value of the NestedHeaderMember property for this object. + */ + public final String nestedHeaderMember() { + return nestedHeaderMember; + } + + /** + * Returns the value of the NestedStatusCode property for this object. + * @return The value of the NestedStatusCode property for this object. + */ + public final Integer nestedStatusCode() { + return nestedStatusCode; + } + + @Override + public Builder toBuilder() { + return new BuilderImpl(this); + } + + public static Builder builder() { + return new BuilderImpl(); + } + + public static Class serializableBuilderClass() { + return BuilderImpl.class; + } + + @Override + public final int hashCode() { + int hashCode = 1; + hashCode = 31 * hashCode + Objects.hashCode(queryParamOne()); + hashCode = 31 * hashCode + Objects.hashCode(queryParamTwo()); + hashCode = 31 * hashCode + Objects.hashCode(nestedHeaderMember()); + hashCode = 31 * hashCode + Objects.hashCode(nestedStatusCode()); + return hashCode; + } + + @Override + public final boolean equals(Object obj) { + return equalsBySdkFields(obj); + } + + @Override + public final boolean equalsBySdkFields(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof NestedQueryParameterOperation)) { + return false; } + NestedQueryParameterOperation other = (NestedQueryParameterOperation) obj; + return Objects.equals(queryParamOne(), other.queryParamOne())&&Objects.equals(queryParamTwo(), other.queryParamTwo())&&Objects.equals(nestedHeaderMember(), other.nestedHeaderMember())&&Objects.equals(nestedStatusCode(), other.nestedStatusCode()); + } + + /** + * Returns a string representation of this object. This is useful for testing and debugging. Sensitive data will be redacted from this string using a placeholder value. + */ + @Override + public final String toString() { + return ToString.builder("NestedQueryParameterOperation").add("QueryParamOne", queryParamOne()).add("QueryParamTwo", queryParamTwo()).add("NestedHeaderMember", nestedHeaderMember()).add("NestedStatusCode", nestedStatusCode()).build(); + } + + public final Optional getValueForField(String fieldName, Class clazz) { + switch (fieldName) { + case "QueryParamOne":return Optional.ofNullable(clazz.cast(queryParamOne())); + case "QueryParamTwo":return Optional.ofNullable(clazz.cast(queryParamTwo())); + case "NestedHeaderMember":return Optional.ofNullable(clazz.cast(nestedHeaderMember())); + case "NestedStatusCode":return Optional.ofNullable(clazz.cast(nestedStatusCode())); + default:return Optional.empty(); + } + } + + @Override + public final List> sdkFields() { + return SDK_FIELDS; + } + + @Override + public final Map> sdkFieldNameToField() { + return SDK_NAME_TO_FIELD; + } + + private static Map> memberNameToFieldInitializer() { + Map> map = new HashMap<>(); + map.put("QueryParamOne", QUERY_PARAM_ONE_FIELD); + map.put("QueryParamTwo", QUERY_PARAM_TWO_FIELD); + map.put("NestedHeaderMember", NESTED_HEADER_MEMBER_FIELD); + map.put("NestedStatusCode", NESTED_STATUS_CODE_FIELD); + return Collections.unmodifiableMap(map); + } + + private static Function getter(Function g) { + return obj -> g.apply((NestedQueryParameterOperation) obj); + } + + private static BiConsumer setter(BiConsumer s) { + return (obj, val) -> s.accept((Builder) obj, val); + } + + @Mutable + @NotThreadSafe + public interface Builder extends SdkPojo, CopyableBuilder { + /** + * Sets the value of the QueryParamOne property for this object. + * + * @param queryParamOne The new value for the QueryParamOne property for this object. + * @return Returns a reference to this object so that method calls can be chained together. + */ + Builder queryParamOne(String queryParamOne); /** - * Returns the value of the QueryParamOne property for this object. + * Sets the value of the QueryParamTwo property for this object. * - * @return The value of the QueryParamOne property for this object. + * @param queryParamTwo The new value for the QueryParamTwo property for this object. + * @return Returns a reference to this object so that method calls can be chained together. */ - public final String queryParamOne() { - return queryParamOne; - } + Builder queryParamTwo(String queryParamTwo); + + /** + * Sets the value of the NestedHeaderMember property for this object. + * + * @param nestedHeaderMember The new value for the NestedHeaderMember property for this object. + * @return Returns a reference to this object so that method calls can be chained together. + */ + Builder nestedHeaderMember(String nestedHeaderMember); /** - * Returns the value of the QueryParamTwo property for this object. + * Sets the value of the NestedStatusCode property for this object. * - * @return The value of the QueryParamTwo property for this object. + * @param nestedStatusCode The new value for the NestedStatusCode property for this object. + * @return Returns a reference to this object so that method calls can be chained together. */ - public final String queryParamTwo() { - return queryParamTwo; + Builder nestedStatusCode(Integer nestedStatusCode); + } + + static final class BuilderImpl implements Builder { + private String queryParamOne; + + private String queryParamTwo; + + private String nestedHeaderMember; + + private Integer nestedStatusCode; + + private BuilderImpl() { } - @Override - public Builder toBuilder() { - return new BuilderImpl(this); + private BuilderImpl(NestedQueryParameterOperation model) { + queryParamOne(model.queryParamOne); + queryParamTwo(model.queryParamTwo); + nestedHeaderMember(model.nestedHeaderMember); + nestedStatusCode(model.nestedStatusCode); } - public static Builder builder() { - return new BuilderImpl(); + public final String getQueryParamOne() { + return queryParamOne; } - public static Class serializableBuilderClass() { - return BuilderImpl.class; + public final void setQueryParamOne(String queryParamOne) { + this.queryParamOne = queryParamOne; } @Override - public final int hashCode() { - int hashCode = 1; - hashCode = 31 * hashCode + Objects.hashCode(queryParamOne()); - hashCode = 31 * hashCode + Objects.hashCode(queryParamTwo()); - return hashCode; + public final Builder queryParamOne(String queryParamOne) { + this.queryParamOne = queryParamOne; + return this; } - @Override - public final boolean equals(Object obj) { - return equalsBySdkFields(obj); + public final String getQueryParamTwo() { + return queryParamTwo; } - @Override - public final boolean equalsBySdkFields(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof NestedQueryParameterOperation)) { - return false; - } - NestedQueryParameterOperation other = (NestedQueryParameterOperation) obj; - return Objects.equals(queryParamOne(), other.queryParamOne()) && Objects.equals(queryParamTwo(), other.queryParamTwo()); + public final void setQueryParamTwo(String queryParamTwo) { + this.queryParamTwo = queryParamTwo; } - /** - * Returns a string representation of this object. This is useful for testing and debugging. Sensitive data will be - * redacted from this string using a placeholder value. - */ @Override - public final String toString() { - return ToString.builder("NestedQueryParameterOperation").add("QueryParamOne", queryParamOne()) - .add("QueryParamTwo", queryParamTwo()).build(); + public final Builder queryParamTwo(String queryParamTwo) { + this.queryParamTwo = queryParamTwo; + return this; } - public final Optional getValueForField(String fieldName, Class clazz) { - switch (fieldName) { - case "QueryParamOne": - return Optional.ofNullable(clazz.cast(queryParamOne())); - case "QueryParamTwo": - return Optional.ofNullable(clazz.cast(queryParamTwo())); - default: - return Optional.empty(); - } + public final String getNestedHeaderMember() { + return nestedHeaderMember; } - @Override - public final List> sdkFields() { - return SDK_FIELDS; + public final void setNestedHeaderMember(String nestedHeaderMember) { + this.nestedHeaderMember = nestedHeaderMember; } @Override - public final Map> sdkFieldNameToField() { - return SDK_NAME_TO_FIELD; + public final Builder nestedHeaderMember(String nestedHeaderMember) { + this.nestedHeaderMember = nestedHeaderMember; + return this; } - private static Map> memberNameToFieldInitializer() { - Map> map = new HashMap<>(); - map.put("QueryParamOne", QUERY_PARAM_ONE_FIELD); - map.put("QueryParamTwo", QUERY_PARAM_TWO_FIELD); - return Collections.unmodifiableMap(map); + public final Integer getNestedStatusCode() { + return nestedStatusCode; } - private static Function getter(Function g) { - return obj -> g.apply((NestedQueryParameterOperation) obj); + public final void setNestedStatusCode(Integer nestedStatusCode) { + this.nestedStatusCode = nestedStatusCode; } - private static BiConsumer setter(BiConsumer s) { - return (obj, val) -> s.accept((Builder) obj, val); + @Override + public final Builder nestedStatusCode(Integer nestedStatusCode) { + this.nestedStatusCode = nestedStatusCode; + return this; } - @Mutable - @NotThreadSafe - public interface Builder extends SdkPojo, CopyableBuilder { - /** - * Sets the value of the QueryParamOne property for this object. - * - * @param queryParamOne - * The new value for the QueryParamOne property for this object. - * @return Returns a reference to this object so that method calls can be chained together. - */ - Builder queryParamOne(String queryParamOne); - - /** - * Sets the value of the QueryParamTwo property for this object. - * - * @param queryParamTwo - * The new value for the QueryParamTwo property for this object. - * @return Returns a reference to this object so that method calls can be chained together. - */ - Builder queryParamTwo(String queryParamTwo); + @Override + public NestedQueryParameterOperation build() { + return new NestedQueryParameterOperation(this); } - static final class BuilderImpl implements Builder { - private String queryParamOne; - - private String queryParamTwo; - - private BuilderImpl() { - } - - private BuilderImpl(NestedQueryParameterOperation model) { - queryParamOne(model.queryParamOne); - queryParamTwo(model.queryParamTwo); - } - - public final String getQueryParamOne() { - return queryParamOne; - } - - public final void setQueryParamOne(String queryParamOne) { - this.queryParamOne = queryParamOne; - } - - @Override - public final Builder queryParamOne(String queryParamOne) { - this.queryParamOne = queryParamOne; - return this; - } - - public final String getQueryParamTwo() { - return queryParamTwo; - } - - public final void setQueryParamTwo(String queryParamTwo) { - this.queryParamTwo = queryParamTwo; - } - - @Override - public final Builder queryParamTwo(String queryParamTwo) { - this.queryParamTwo = queryParamTwo; - return this; - } - - @Override - public NestedQueryParameterOperation build() { - return new NestedQueryParameterOperation(this); - } - - @Override - public List> sdkFields() { - return SDK_FIELDS; - } + @Override + public List> sdkFields() { + return SDK_FIELDS; + } - @Override - public Map> sdkFieldNameToField() { - return SDK_NAME_TO_FIELD; - } + @Override + public Map> sdkFieldNameToField() { + return SDK_NAME_TO_FIELD; } + } } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/queryparameteroperationrequest.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/queryparameteroperationrequest.java index 6e5452cb2e58..681f3d3f17e5 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/queryparameteroperationrequest.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/queryparameteroperationrequest.java @@ -34,612 +34,712 @@ @Generated("software.amazon.awssdk:codegen") public final class QueryParameterOperationRequest extends JsonProtocolTestsRequest implements ToCopyableBuilder { - private static final SdkField PATH_PARAM_FIELD = SdkField - . builder(MarshallingType.STRING) - .memberName("PathParam") - .getter(getter(QueryParameterOperationRequest::pathParam)) - .setter(setter(Builder::pathParam)) - .traits(LocationTrait.builder().location(MarshallLocation.PATH).locationName("PathParam").build(), - RequiredTrait.create()).build(); - - private static final SdkField QUERY_PARAM_ONE_FIELD = SdkField - . builder(MarshallingType.STRING) - .memberName("QueryParamOne") - .getter(getter(QueryParameterOperationRequest::queryParamOne)) - .setter(setter(Builder::queryParamOne)) - .traits(LocationTrait.builder().location(MarshallLocation.QUERY_PARAM).locationName("QueryParamOne").build(), - RequiredTrait.create()).build(); - - private static final SdkField QUERY_PARAM_TWO_FIELD = SdkField. builder(MarshallingType.STRING) - .memberName("QueryParamTwo").getter(getter(QueryParameterOperationRequest::queryParamTwo)) - .setter(setter(Builder::queryParamTwo)) - .traits(LocationTrait.builder().location(MarshallLocation.QUERY_PARAM).locationName("QueryParamTwo").build()).build(); - - private static final SdkField STRING_HEADER_MEMBER_FIELD = SdkField - . builder(MarshallingType.STRING) - .memberName("StringHeaderMember") - .getter(getter(QueryParameterOperationRequest::stringHeaderMember)) - .setter(setter(Builder::stringHeaderMember)) - .traits(LocationTrait.builder().location(MarshallLocation.HEADER).locationName("x-amz-header-string").build(), - RequiredTrait.create()).build(); - - private static final SdkField NESTED_QUERY_PARAMETER_OPERATION_FIELD = SdkField - . builder(MarshallingType.SDK_POJO) - .memberName("NestedQueryParameterOperation") - .getter(getter(QueryParameterOperationRequest::nestedQueryParameterOperation)) - .setter(setter(Builder::nestedQueryParameterOperation)) - .constructor(NestedQueryParameterOperation::builder) - .traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("NestedQueryParameterOperation") - .build(), PayloadTrait.create()).build(); - - private static final SdkField> REQUIRED_LIST_QUERY_PARAMS_FIELD = SdkField - .> builder(MarshallingType.LIST) - .memberName("RequiredListQueryParams") - .getter(getter(QueryParameterOperationRequest::requiredListQueryParams)) - .setter(setter(Builder::requiredListQueryParams)) - .traits(LocationTrait.builder().location(MarshallLocation.QUERY_PARAM).locationName("RequiredListQueryParams") - .build(), - ListTrait - .builder() - .memberLocationName(null) - .memberFieldInfo( - SdkField. builder(MarshallingType.INTEGER) - .traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD) - .locationName("member").build()).build()).build(), RequiredTrait.create()) - .build(); - - private static final SdkField> OPTIONAL_LIST_QUERY_PARAMS_FIELD = SdkField - .> builder(MarshallingType.LIST) - .memberName("OptionalListQueryParams") - .getter(getter(QueryParameterOperationRequest::optionalListQueryParams)) - .setter(setter(Builder::optionalListQueryParams)) - .traits(LocationTrait.builder().location(MarshallLocation.QUERY_PARAM).locationName("OptionalListQueryParams") - .build(), - ListTrait - .builder() - .memberLocationName(null) - .memberFieldInfo( - SdkField. builder(MarshallingType.INTEGER) - .traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD) - .locationName("member").build()).build()).build()).build(); - - private static final List> SDK_FIELDS = Collections.unmodifiableList(Arrays.asList(PATH_PARAM_FIELD, - QUERY_PARAM_ONE_FIELD, QUERY_PARAM_TWO_FIELD, STRING_HEADER_MEMBER_FIELD, NESTED_QUERY_PARAMETER_OPERATION_FIELD, - REQUIRED_LIST_QUERY_PARAMS_FIELD, OPTIONAL_LIST_QUERY_PARAMS_FIELD)); - - private static final Map> SDK_NAME_TO_FIELD = memberNameToFieldInitializer(); - - private final String pathParam; - - private final String queryParamOne; - - private final String queryParamTwo; - - private final String stringHeaderMember; - - private final NestedQueryParameterOperation nestedQueryParameterOperation; - - private final List requiredListQueryParams; - - private final List optionalListQueryParams; - - private QueryParameterOperationRequest(BuilderImpl builder) { - super(builder); - this.pathParam = builder.pathParam; - this.queryParamOne = builder.queryParamOne; - this.queryParamTwo = builder.queryParamTwo; - this.stringHeaderMember = builder.stringHeaderMember; - this.nestedQueryParameterOperation = builder.nestedQueryParameterOperation; - this.requiredListQueryParams = builder.requiredListQueryParams; - this.optionalListQueryParams = builder.optionalListQueryParams; + private static final SdkField PATH_PARAM_FIELD = SdkField + . builder(MarshallingType.STRING) + .memberName("PathParam") + .getter(getter(QueryParameterOperationRequest::pathParam)) + .setter(setter(Builder::pathParam)) + .traits(LocationTrait.builder().location(MarshallLocation.PATH).locationName("PathParam").build(), + RequiredTrait.create()).build(); + + private static final SdkField QUERY_PARAM_ONE_FIELD = SdkField + . builder(MarshallingType.STRING) + .memberName("QueryParamOne") + .getter(getter(QueryParameterOperationRequest::queryParamOne)) + .setter(setter(Builder::queryParamOne)) + .traits(LocationTrait.builder().location(MarshallLocation.QUERY_PARAM).locationName("QueryParamOne").build(), + RequiredTrait.create()).build(); + + private static final SdkField QUERY_PARAM_TWO_FIELD = SdkField. builder(MarshallingType.STRING) + .memberName("QueryParamTwo").getter(getter(QueryParameterOperationRequest::queryParamTwo)) + .setter(setter(Builder::queryParamTwo)) + .traits(LocationTrait.builder().location(MarshallLocation.QUERY_PARAM).locationName("QueryParamTwo").build()).build(); + + private static final SdkField STRING_HEADER_MEMBER_FIELD = SdkField + . builder(MarshallingType.STRING) + .memberName("StringHeaderMember") + .getter(getter(QueryParameterOperationRequest::stringHeaderMember)) + .setter(setter(Builder::stringHeaderMember)) + .traits(LocationTrait.builder().location(MarshallLocation.HEADER).locationName("x-amz-header-string").build(), + RequiredTrait.create()).build(); + + private static final SdkField NESTED_QUERY_PARAMETER_OPERATION_FIELD = SdkField + . builder(MarshallingType.SDK_POJO) + .memberName("NestedQueryParameterOperation") + .getter(getter(QueryParameterOperationRequest::nestedQueryParameterOperation)) + .setter(setter(Builder::nestedQueryParameterOperation)) + .constructor(NestedQueryParameterOperation::builder) + .traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("NestedQueryParameterOperation") + .build(), PayloadTrait.create()).build(); + + private static final SdkField> REQUIRED_LIST_QUERY_PARAMS_FIELD = SdkField + .> builder(MarshallingType.LIST) + .memberName("RequiredListQueryParams") + .getter(getter(QueryParameterOperationRequest::requiredListQueryParams)) + .setter(setter(Builder::requiredListQueryParams)) + .traits(LocationTrait.builder().location(MarshallLocation.QUERY_PARAM).locationName("RequiredListQueryParams") + .build(), + ListTrait + .builder() + .memberLocationName(null) + .memberFieldInfo( + SdkField. builder(MarshallingType.INTEGER) + .traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD) + .locationName("member").build()).build()).build(), RequiredTrait.create()) + .build(); + + private static final SdkField> OPTIONAL_LIST_QUERY_PARAMS_FIELD = SdkField + .> builder(MarshallingType.LIST) + .memberName("OptionalListQueryParams") + .getter(getter(QueryParameterOperationRequest::optionalListQueryParams)) + .setter(setter(Builder::optionalListQueryParams)) + .traits(LocationTrait.builder().location(MarshallLocation.QUERY_PARAM).locationName("OptionalListQueryParams") + .build(), + ListTrait + .builder() + .memberLocationName(null) + .memberFieldInfo( + SdkField. builder(MarshallingType.INTEGER) + .traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD) + .locationName("member").build()).build()).build()).build(); + + private static final SdkField STATUS_CODE_ON_INPUT_FIELD = SdkField. builder(MarshallingType.INTEGER) + .memberName("StatusCodeOnInput").getter(getter(QueryParameterOperationRequest::statusCodeOnInput)) + .setter(setter(Builder::statusCodeOnInput)) + .traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("StatusCodeOnInput").build()).build(); + + private static final SdkField PAYLOAD_MEMBER_WITH_CUSTOM_NAME_FIELD = SdkField + . builder(MarshallingType.STRING).memberName("PayloadMemberWithCustomName") + .getter(getter(QueryParameterOperationRequest::payloadMemberWithCustomName)) + .setter(setter(Builder::payloadMemberWithCustomName)) + .traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("CustomWireName").build()).build(); + + private static final List> SDK_FIELDS = Collections.unmodifiableList(Arrays.asList(PATH_PARAM_FIELD, + QUERY_PARAM_ONE_FIELD, QUERY_PARAM_TWO_FIELD, STRING_HEADER_MEMBER_FIELD, NESTED_QUERY_PARAMETER_OPERATION_FIELD, + REQUIRED_LIST_QUERY_PARAMS_FIELD, OPTIONAL_LIST_QUERY_PARAMS_FIELD, STATUS_CODE_ON_INPUT_FIELD, + PAYLOAD_MEMBER_WITH_CUSTOM_NAME_FIELD)); + + private static final Map> SDK_NAME_TO_FIELD = memberNameToFieldInitializer(); + + private final String pathParam; + + private final String queryParamOne; + + private final String queryParamTwo; + + private final String stringHeaderMember; + + private final NestedQueryParameterOperation nestedQueryParameterOperation; + + private final List requiredListQueryParams; + + private final List optionalListQueryParams; + + private final Integer statusCodeOnInput; + + private final String payloadMemberWithCustomName; + + private QueryParameterOperationRequest(BuilderImpl builder) { + super(builder); + this.pathParam = builder.pathParam; + this.queryParamOne = builder.queryParamOne; + this.queryParamTwo = builder.queryParamTwo; + this.stringHeaderMember = builder.stringHeaderMember; + this.nestedQueryParameterOperation = builder.nestedQueryParameterOperation; + this.requiredListQueryParams = builder.requiredListQueryParams; + this.optionalListQueryParams = builder.optionalListQueryParams; + this.statusCodeOnInput = builder.statusCodeOnInput; + this.payloadMemberWithCustomName = builder.payloadMemberWithCustomName; + } + + /** + * Returns the value of the PathParam property for this object. + * + * @return The value of the PathParam property for this object. + */ + public final String pathParam() { + return pathParam; + } + + /** + * Returns the value of the QueryParamOne property for this object. + * + * @return The value of the QueryParamOne property for this object. + */ + public final String queryParamOne() { + return queryParamOne; + } + + /** + * Returns the value of the QueryParamTwo property for this object. + * + * @return The value of the QueryParamTwo property for this object. + */ + public final String queryParamTwo() { + return queryParamTwo; + } + + /** + * Returns the value of the StringHeaderMember property for this object. + * + * @return The value of the StringHeaderMember property for this object. + */ + public final String stringHeaderMember() { + return stringHeaderMember; + } + + /** + * Returns the value of the NestedQueryParameterOperation property for this object. + * + * @return The value of the NestedQueryParameterOperation property for this object. + */ + public final NestedQueryParameterOperation nestedQueryParameterOperation() { + return nestedQueryParameterOperation; + } + + /** + * For responses, this returns true if the service returned a value for the RequiredListQueryParams property. This + * DOES NOT check that the value is non-empty (for which, you should check the {@code isEmpty()} method on the + * property). This is useful because the SDK will never return a null collection or map, but you may need to + * differentiate between the service returning nothing (or null) and the service returning an empty collection or + * map. For requests, this returns true if a value for the property was specified in the request builder, and false + * if a value was not specified. + */ + public final boolean hasRequiredListQueryParams() { + return requiredListQueryParams != null && !(requiredListQueryParams instanceof SdkAutoConstructList); + } + + /** + * Returns the value of the RequiredListQueryParams property for this object. + *

+ * Attempts to modify the collection returned by this method will result in an UnsupportedOperationException. + *

+ *

+ * This method will never return null. If you would like to know whether the service returned this field (so that + * you can differentiate between null and empty), you can use the {@link #hasRequiredListQueryParams} method. + *

+ * + * @return The value of the RequiredListQueryParams property for this object. + */ + public final List requiredListQueryParams() { + return requiredListQueryParams; + } + + /** + * For responses, this returns true if the service returned a value for the OptionalListQueryParams property. This + * DOES NOT check that the value is non-empty (for which, you should check the {@code isEmpty()} method on the + * property). This is useful because the SDK will never return a null collection or map, but you may need to + * differentiate between the service returning nothing (or null) and the service returning an empty collection or + * map. For requests, this returns true if a value for the property was specified in the request builder, and false + * if a value was not specified. + */ + public final boolean hasOptionalListQueryParams() { + return optionalListQueryParams != null && !(optionalListQueryParams instanceof SdkAutoConstructList); + } + + /** + * Returns the value of the OptionalListQueryParams property for this object. + *

+ * Attempts to modify the collection returned by this method will result in an UnsupportedOperationException. + *

+ *

+ * This method will never return null. If you would like to know whether the service returned this field (so that + * you can differentiate between null and empty), you can use the {@link #hasOptionalListQueryParams} method. + *

+ * + * @return The value of the OptionalListQueryParams property for this object. + */ + public final List optionalListQueryParams() { + return optionalListQueryParams; + } + + /** + * Returns the value of the StatusCodeOnInput property for this object. + * + * @return The value of the StatusCodeOnInput property for this object. + */ + public final Integer statusCodeOnInput() { + return statusCodeOnInput; + } + + /** + * Returns the value of the PayloadMemberWithCustomName property for this object. + * + * @return The value of the PayloadMemberWithCustomName property for this object. + */ + public final String payloadMemberWithCustomName() { + return payloadMemberWithCustomName; + } + + @Override + public Builder toBuilder() { + return new BuilderImpl(this); + } + + public static Builder builder() { + return new BuilderImpl(); + } + + public static Class serializableBuilderClass() { + return BuilderImpl.class; + } + + @Override + public final int hashCode() { + int hashCode = 1; + hashCode = 31 * hashCode + super.hashCode(); + hashCode = 31 * hashCode + Objects.hashCode(pathParam()); + hashCode = 31 * hashCode + Objects.hashCode(queryParamOne()); + hashCode = 31 * hashCode + Objects.hashCode(queryParamTwo()); + hashCode = 31 * hashCode + Objects.hashCode(stringHeaderMember()); + hashCode = 31 * hashCode + Objects.hashCode(nestedQueryParameterOperation()); + hashCode = 31 * hashCode + Objects.hashCode(hasRequiredListQueryParams() ? requiredListQueryParams() : null); + hashCode = 31 * hashCode + Objects.hashCode(hasOptionalListQueryParams() ? optionalListQueryParams() : null); + hashCode = 31 * hashCode + Objects.hashCode(statusCodeOnInput()); + hashCode = 31 * hashCode + Objects.hashCode(payloadMemberWithCustomName()); + return hashCode; + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj) && equalsBySdkFields(obj); + } + + @Override + public final boolean equalsBySdkFields(Object obj) { + if (this == obj) { + return true; } + if (obj == null) { + return false; + } + if (!(obj instanceof QueryParameterOperationRequest)) { + return false; + } + QueryParameterOperationRequest other = (QueryParameterOperationRequest) obj; + return Objects.equals(pathParam(), other.pathParam()) && Objects.equals(queryParamOne(), other.queryParamOne()) + && Objects.equals(queryParamTwo(), other.queryParamTwo()) + && Objects.equals(stringHeaderMember(), other.stringHeaderMember()) + && Objects.equals(nestedQueryParameterOperation(), other.nestedQueryParameterOperation()) + && hasRequiredListQueryParams() == other.hasRequiredListQueryParams() + && Objects.equals(requiredListQueryParams(), other.requiredListQueryParams()) + && hasOptionalListQueryParams() == other.hasOptionalListQueryParams() + && Objects.equals(optionalListQueryParams(), other.optionalListQueryParams()) + && Objects.equals(statusCodeOnInput(), other.statusCodeOnInput()) + && Objects.equals(payloadMemberWithCustomName(), other.payloadMemberWithCustomName()); + } + + /** + * Returns a string representation of this object. This is useful for testing and debugging. Sensitive data will be + * redacted from this string using a placeholder value. + */ + @Override + public final String toString() { + return ToString.builder("QueryParameterOperationRequest").add("PathParam", pathParam()) + .add("QueryParamOne", queryParamOne()).add("QueryParamTwo", queryParamTwo()) + .add("StringHeaderMember", stringHeaderMember()) + .add("NestedQueryParameterOperation", nestedQueryParameterOperation()) + .add("RequiredListQueryParams", hasRequiredListQueryParams() ? requiredListQueryParams() : null) + .add("OptionalListQueryParams", hasOptionalListQueryParams() ? optionalListQueryParams() : null) + .add("StatusCodeOnInput", statusCodeOnInput()).add("PayloadMemberWithCustomName", payloadMemberWithCustomName()) + .build(); + } + + public final Optional getValueForField(String fieldName, Class clazz) { + switch (fieldName) { + case "PathParam": + return Optional.ofNullable(clazz.cast(pathParam())); + case "QueryParamOne": + return Optional.ofNullable(clazz.cast(queryParamOne())); + case "QueryParamTwo": + return Optional.ofNullable(clazz.cast(queryParamTwo())); + case "StringHeaderMember": + return Optional.ofNullable(clazz.cast(stringHeaderMember())); + case "NestedQueryParameterOperation": + return Optional.ofNullable(clazz.cast(nestedQueryParameterOperation())); + case "RequiredListQueryParams": + return Optional.ofNullable(clazz.cast(requiredListQueryParams())); + case "OptionalListQueryParams": + return Optional.ofNullable(clazz.cast(optionalListQueryParams())); + case "StatusCodeOnInput": + return Optional.ofNullable(clazz.cast(statusCodeOnInput())); + case "PayloadMemberWithCustomName": + return Optional.ofNullable(clazz.cast(payloadMemberWithCustomName())); + default: + return Optional.empty(); + } + } + + @Override + public final List> sdkFields() { + return SDK_FIELDS; + } + + @Override + public final Map> sdkFieldNameToField() { + return SDK_NAME_TO_FIELD; + } + + private static Map> memberNameToFieldInitializer() { + Map> map = new HashMap<>(); + map.put("PathParam", PATH_PARAM_FIELD); + map.put("QueryParamOne", QUERY_PARAM_ONE_FIELD); + map.put("QueryParamTwo", QUERY_PARAM_TWO_FIELD); + map.put("x-amz-header-string", STRING_HEADER_MEMBER_FIELD); + map.put("NestedQueryParameterOperation", NESTED_QUERY_PARAMETER_OPERATION_FIELD); + map.put("RequiredListQueryParams", REQUIRED_LIST_QUERY_PARAMS_FIELD); + map.put("OptionalListQueryParams", OPTIONAL_LIST_QUERY_PARAMS_FIELD); + map.put("StatusCodeOnInput", STATUS_CODE_ON_INPUT_FIELD); + map.put("CustomWireName", PAYLOAD_MEMBER_WITH_CUSTOM_NAME_FIELD); + return Collections.unmodifiableMap(map); + } + + private static Function getter(Function g) { + return obj -> g.apply((QueryParameterOperationRequest) obj); + } + + private static BiConsumer setter(BiConsumer s) { + return (obj, val) -> s.accept((Builder) obj, val); + } + + @Mutable + @NotThreadSafe + public interface Builder extends JsonProtocolTestsRequest.Builder, SdkPojo, + CopyableBuilder { + /** + * Sets the value of the PathParam property for this object. + * + * @param pathParam + * The new value for the PathParam property for this object. + * @return Returns a reference to this object so that method calls can be chained together. + */ + Builder pathParam(String pathParam); /** - * Returns the value of the PathParam property for this object. + * Sets the value of the QueryParamOne property for this object. * - * @return The value of the PathParam property for this object. + * @param queryParamOne + * The new value for the QueryParamOne property for this object. + * @return Returns a reference to this object so that method calls can be chained together. */ - public final String pathParam() { - return pathParam; - } + Builder queryParamOne(String queryParamOne); /** - * Returns the value of the QueryParamOne property for this object. + * Sets the value of the QueryParamTwo property for this object. * - * @return The value of the QueryParamOne property for this object. + * @param queryParamTwo + * The new value for the QueryParamTwo property for this object. + * @return Returns a reference to this object so that method calls can be chained together. */ - public final String queryParamOne() { - return queryParamOne; - } + Builder queryParamTwo(String queryParamTwo); /** - * Returns the value of the QueryParamTwo property for this object. + * Sets the value of the StringHeaderMember property for this object. * - * @return The value of the QueryParamTwo property for this object. + * @param stringHeaderMember + * The new value for the StringHeaderMember property for this object. + * @return Returns a reference to this object so that method calls can be chained together. */ - public final String queryParamTwo() { - return queryParamTwo; - } + Builder stringHeaderMember(String stringHeaderMember); /** - * Returns the value of the StringHeaderMember property for this object. + * Sets the value of the NestedQueryParameterOperation property for this object. * - * @return The value of the StringHeaderMember property for this object. + * @param nestedQueryParameterOperation + * The new value for the NestedQueryParameterOperation property for this object. + * @return Returns a reference to this object so that method calls can be chained together. */ - public final String stringHeaderMember() { - return stringHeaderMember; - } + Builder nestedQueryParameterOperation(NestedQueryParameterOperation nestedQueryParameterOperation); /** - * Returns the value of the NestedQueryParameterOperation property for this object. + * Sets the value of the NestedQueryParameterOperation property for this object. + * + * This is a convenience method that creates an instance of the {@link NestedQueryParameterOperation.Builder} + * avoiding the need to create one manually via {@link NestedQueryParameterOperation#builder()}. * - * @return The value of the NestedQueryParameterOperation property for this object. + *

+ * When the {@link Consumer} completes, {@link NestedQueryParameterOperation.Builder#build()} is called + * immediately and its result is passed to {@link #nestedQueryParameterOperation(NestedQueryParameterOperation)}. + * + * @param nestedQueryParameterOperation + * a consumer that will call methods on {@link NestedQueryParameterOperation.Builder} + * @return Returns a reference to this object so that method calls can be chained together. + * @see #nestedQueryParameterOperation(NestedQueryParameterOperation) */ - public final NestedQueryParameterOperation nestedQueryParameterOperation() { - return nestedQueryParameterOperation; + default Builder nestedQueryParameterOperation( + Consumer nestedQueryParameterOperation) { + return nestedQueryParameterOperation(NestedQueryParameterOperation.builder() + .applyMutation(nestedQueryParameterOperation).build()); } /** - * For responses, this returns true if the service returned a value for the RequiredListQueryParams property. This - * DOES NOT check that the value is non-empty (for which, you should check the {@code isEmpty()} method on the - * property). This is useful because the SDK will never return a null collection or map, but you may need to - * differentiate between the service returning nothing (or null) and the service returning an empty collection or - * map. For requests, this returns true if a value for the property was specified in the request builder, and false - * if a value was not specified. + * Sets the value of the RequiredListQueryParams property for this object. + * + * @param requiredListQueryParams + * The new value for the RequiredListQueryParams property for this object. + * @return Returns a reference to this object so that method calls can be chained together. */ - public final boolean hasRequiredListQueryParams() { - return requiredListQueryParams != null && !(requiredListQueryParams instanceof SdkAutoConstructList); - } + Builder requiredListQueryParams(Collection requiredListQueryParams); /** - * Returns the value of the RequiredListQueryParams property for this object. - *

- * Attempts to modify the collection returned by this method will result in an UnsupportedOperationException. - *

- *

- * This method will never return null. If you would like to know whether the service returned this field (so that - * you can differentiate between null and empty), you can use the {@link #hasRequiredListQueryParams} method. - *

+ * Sets the value of the RequiredListQueryParams property for this object. * - * @return The value of the RequiredListQueryParams property for this object. + * @param requiredListQueryParams + * The new value for the RequiredListQueryParams property for this object. + * @return Returns a reference to this object so that method calls can be chained together. */ - public final List requiredListQueryParams() { - return requiredListQueryParams; - } + Builder requiredListQueryParams(Integer... requiredListQueryParams); /** - * For responses, this returns true if the service returned a value for the OptionalListQueryParams property. This - * DOES NOT check that the value is non-empty (for which, you should check the {@code isEmpty()} method on the - * property). This is useful because the SDK will never return a null collection or map, but you may need to - * differentiate between the service returning nothing (or null) and the service returning an empty collection or - * map. For requests, this returns true if a value for the property was specified in the request builder, and false - * if a value was not specified. + * Sets the value of the OptionalListQueryParams property for this object. + * + * @param optionalListQueryParams + * The new value for the OptionalListQueryParams property for this object. + * @return Returns a reference to this object so that method calls can be chained together. */ - public final boolean hasOptionalListQueryParams() { - return optionalListQueryParams != null && !(optionalListQueryParams instanceof SdkAutoConstructList); - } + Builder optionalListQueryParams(Collection optionalListQueryParams); /** - * Returns the value of the OptionalListQueryParams property for this object. - *

- * Attempts to modify the collection returned by this method will result in an UnsupportedOperationException. - *

- *

- * This method will never return null. If you would like to know whether the service returned this field (so that - * you can differentiate between null and empty), you can use the {@link #hasOptionalListQueryParams} method. - *

+ * Sets the value of the OptionalListQueryParams property for this object. + * + * @param optionalListQueryParams + * The new value for the OptionalListQueryParams property for this object. + * @return Returns a reference to this object so that method calls can be chained together. + */ + Builder optionalListQueryParams(Integer... optionalListQueryParams); + + /** + * Sets the value of the StatusCodeOnInput property for this object. + * + * @param statusCodeOnInput + * The new value for the StatusCodeOnInput property for this object. + * @return Returns a reference to this object so that method calls can be chained together. + */ + Builder statusCodeOnInput(Integer statusCodeOnInput); + + /** + * Sets the value of the PayloadMemberWithCustomName property for this object. * - * @return The value of the OptionalListQueryParams property for this object. + * @param payloadMemberWithCustomName + * The new value for the PayloadMemberWithCustomName property for this object. + * @return Returns a reference to this object so that method calls can be chained together. */ - public final List optionalListQueryParams() { - return optionalListQueryParams; + Builder payloadMemberWithCustomName(String payloadMemberWithCustomName); + + @Override + Builder overrideConfiguration(AwsRequestOverrideConfiguration overrideConfiguration); + + @Override + Builder overrideConfiguration(Consumer builderConsumer); + } + + static final class BuilderImpl extends JsonProtocolTestsRequest.BuilderImpl implements Builder { + private String pathParam; + + private String queryParamOne; + + private String queryParamTwo; + + private String stringHeaderMember; + + private NestedQueryParameterOperation nestedQueryParameterOperation; + + private List requiredListQueryParams = DefaultSdkAutoConstructList.getInstance(); + + private List optionalListQueryParams = DefaultSdkAutoConstructList.getInstance(); + + private Integer statusCodeOnInput; + + private String payloadMemberWithCustomName; + + private BuilderImpl() { + } + + private BuilderImpl(QueryParameterOperationRequest model) { + super(model); + pathParam(model.pathParam); + queryParamOne(model.queryParamOne); + queryParamTwo(model.queryParamTwo); + stringHeaderMember(model.stringHeaderMember); + nestedQueryParameterOperation(model.nestedQueryParameterOperation); + requiredListQueryParams(model.requiredListQueryParams); + optionalListQueryParams(model.optionalListQueryParams); + statusCodeOnInput(model.statusCodeOnInput); + payloadMemberWithCustomName(model.payloadMemberWithCustomName); + } + + public final String getPathParam() { + return pathParam; + } + + public final void setPathParam(String pathParam) { + this.pathParam = pathParam; } @Override - public Builder toBuilder() { - return new BuilderImpl(this); + public final Builder pathParam(String pathParam) { + this.pathParam = pathParam; + return this; } - public static Builder builder() { - return new BuilderImpl(); + public final String getQueryParamOne() { + return queryParamOne; } - public static Class serializableBuilderClass() { - return BuilderImpl.class; + public final void setQueryParamOne(String queryParamOne) { + this.queryParamOne = queryParamOne; } @Override - public final int hashCode() { - int hashCode = 1; - hashCode = 31 * hashCode + super.hashCode(); - hashCode = 31 * hashCode + Objects.hashCode(pathParam()); - hashCode = 31 * hashCode + Objects.hashCode(queryParamOne()); - hashCode = 31 * hashCode + Objects.hashCode(queryParamTwo()); - hashCode = 31 * hashCode + Objects.hashCode(stringHeaderMember()); - hashCode = 31 * hashCode + Objects.hashCode(nestedQueryParameterOperation()); - hashCode = 31 * hashCode + Objects.hashCode(hasRequiredListQueryParams() ? requiredListQueryParams() : null); - hashCode = 31 * hashCode + Objects.hashCode(hasOptionalListQueryParams() ? optionalListQueryParams() : null); - return hashCode; + public final Builder queryParamOne(String queryParamOne) { + this.queryParamOne = queryParamOne; + return this; + } + + public final String getQueryParamTwo() { + return queryParamTwo; + } + + public final void setQueryParamTwo(String queryParamTwo) { + this.queryParamTwo = queryParamTwo; } @Override - public final boolean equals(Object obj) { - return super.equals(obj) && equalsBySdkFields(obj); + public final Builder queryParamTwo(String queryParamTwo) { + this.queryParamTwo = queryParamTwo; + return this; + } + + public final String getStringHeaderMember() { + return stringHeaderMember; + } + + public final void setStringHeaderMember(String stringHeaderMember) { + this.stringHeaderMember = stringHeaderMember; } @Override - public final boolean equalsBySdkFields(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof QueryParameterOperationRequest)) { - return false; - } - QueryParameterOperationRequest other = (QueryParameterOperationRequest) obj; - return Objects.equals(pathParam(), other.pathParam()) && Objects.equals(queryParamOne(), other.queryParamOne()) - && Objects.equals(queryParamTwo(), other.queryParamTwo()) - && Objects.equals(stringHeaderMember(), other.stringHeaderMember()) - && Objects.equals(nestedQueryParameterOperation(), other.nestedQueryParameterOperation()) - && hasRequiredListQueryParams() == other.hasRequiredListQueryParams() - && Objects.equals(requiredListQueryParams(), other.requiredListQueryParams()) - && hasOptionalListQueryParams() == other.hasOptionalListQueryParams() - && Objects.equals(optionalListQueryParams(), other.optionalListQueryParams()); + public final Builder stringHeaderMember(String stringHeaderMember) { + this.stringHeaderMember = stringHeaderMember; + return this; + } + + public final NestedQueryParameterOperation.Builder getNestedQueryParameterOperation() { + return nestedQueryParameterOperation != null ? nestedQueryParameterOperation.toBuilder() : null; + } + + public final void setNestedQueryParameterOperation(NestedQueryParameterOperation.BuilderImpl nestedQueryParameterOperation) { + this.nestedQueryParameterOperation = nestedQueryParameterOperation != null ? nestedQueryParameterOperation.build() + : null; + } + + @Override + public final Builder nestedQueryParameterOperation(NestedQueryParameterOperation nestedQueryParameterOperation) { + this.nestedQueryParameterOperation = nestedQueryParameterOperation; + return this; + } + + public final Collection getRequiredListQueryParams() { + if (requiredListQueryParams instanceof SdkAutoConstructList) { + return null; + } + return requiredListQueryParams; + } + + public final void setRequiredListQueryParams(Collection requiredListQueryParams) { + this.requiredListQueryParams = ListOfIntegersCopier.copy(requiredListQueryParams); + } + + @Override + public final Builder requiredListQueryParams(Collection requiredListQueryParams) { + this.requiredListQueryParams = ListOfIntegersCopier.copy(requiredListQueryParams); + return this; + } + + @Override + @SafeVarargs + public final Builder requiredListQueryParams(Integer... requiredListQueryParams) { + requiredListQueryParams(Arrays.asList(requiredListQueryParams)); + return this; + } + + public final Collection getOptionalListQueryParams() { + if (optionalListQueryParams instanceof SdkAutoConstructList) { + return null; + } + return optionalListQueryParams; + } + + public final void setOptionalListQueryParams(Collection optionalListQueryParams) { + this.optionalListQueryParams = ListOfIntegersCopier.copy(optionalListQueryParams); + } + + @Override + public final Builder optionalListQueryParams(Collection optionalListQueryParams) { + this.optionalListQueryParams = ListOfIntegersCopier.copy(optionalListQueryParams); + return this; + } + + @Override + @SafeVarargs + public final Builder optionalListQueryParams(Integer... optionalListQueryParams) { + optionalListQueryParams(Arrays.asList(optionalListQueryParams)); + return this; + } + + public final Integer getStatusCodeOnInput() { + return statusCodeOnInput; + } + + public final void setStatusCodeOnInput(Integer statusCodeOnInput) { + this.statusCodeOnInput = statusCodeOnInput; + } + + @Override + public final Builder statusCodeOnInput(Integer statusCodeOnInput) { + this.statusCodeOnInput = statusCodeOnInput; + return this; + } + + public final String getPayloadMemberWithCustomName() { + return payloadMemberWithCustomName; + } + + public final void setPayloadMemberWithCustomName(String payloadMemberWithCustomName) { + this.payloadMemberWithCustomName = payloadMemberWithCustomName; + } + + @Override + public final Builder payloadMemberWithCustomName(String payloadMemberWithCustomName) { + this.payloadMemberWithCustomName = payloadMemberWithCustomName; + return this; + } + + @Override + public Builder overrideConfiguration(AwsRequestOverrideConfiguration overrideConfiguration) { + super.overrideConfiguration(overrideConfiguration); + return this; + } + + @Override + public Builder overrideConfiguration(Consumer builderConsumer) { + super.overrideConfiguration(builderConsumer); + return this; } - /** - * Returns a string representation of this object. This is useful for testing and debugging. Sensitive data will be - * redacted from this string using a placeholder value. - */ @Override - public final String toString() { - return ToString.builder("QueryParameterOperationRequest").add("PathParam", pathParam()) - .add("QueryParamOne", queryParamOne()).add("QueryParamTwo", queryParamTwo()) - .add("StringHeaderMember", stringHeaderMember()) - .add("NestedQueryParameterOperation", nestedQueryParameterOperation()) - .add("RequiredListQueryParams", hasRequiredListQueryParams() ? requiredListQueryParams() : null) - .add("OptionalListQueryParams", hasOptionalListQueryParams() ? optionalListQueryParams() : null).build(); - } - - public final Optional getValueForField(String fieldName, Class clazz) { - switch (fieldName) { - case "PathParam": - return Optional.ofNullable(clazz.cast(pathParam())); - case "QueryParamOne": - return Optional.ofNullable(clazz.cast(queryParamOne())); - case "QueryParamTwo": - return Optional.ofNullable(clazz.cast(queryParamTwo())); - case "StringHeaderMember": - return Optional.ofNullable(clazz.cast(stringHeaderMember())); - case "NestedQueryParameterOperation": - return Optional.ofNullable(clazz.cast(nestedQueryParameterOperation())); - case "RequiredListQueryParams": - return Optional.ofNullable(clazz.cast(requiredListQueryParams())); - case "OptionalListQueryParams": - return Optional.ofNullable(clazz.cast(optionalListQueryParams())); - default: - return Optional.empty(); - } + public QueryParameterOperationRequest build() { + return new QueryParameterOperationRequest(this); } @Override - public final List> sdkFields() { - return SDK_FIELDS; + public List> sdkFields() { + return SDK_FIELDS; } @Override - public final Map> sdkFieldNameToField() { - return SDK_NAME_TO_FIELD; - } - - private static Map> memberNameToFieldInitializer() { - Map> map = new HashMap<>(); - map.put("PathParam", PATH_PARAM_FIELD); - map.put("QueryParamOne", QUERY_PARAM_ONE_FIELD); - map.put("QueryParamTwo", QUERY_PARAM_TWO_FIELD); - map.put("x-amz-header-string", STRING_HEADER_MEMBER_FIELD); - map.put("NestedQueryParameterOperation", NESTED_QUERY_PARAMETER_OPERATION_FIELD); - map.put("RequiredListQueryParams", REQUIRED_LIST_QUERY_PARAMS_FIELD); - map.put("OptionalListQueryParams", OPTIONAL_LIST_QUERY_PARAMS_FIELD); - return Collections.unmodifiableMap(map); - } - - private static Function getter(Function g) { - return obj -> g.apply((QueryParameterOperationRequest) obj); - } - - private static BiConsumer setter(BiConsumer s) { - return (obj, val) -> s.accept((Builder) obj, val); - } - - @Mutable - @NotThreadSafe - public interface Builder extends JsonProtocolTestsRequest.Builder, SdkPojo, - CopyableBuilder { - /** - * Sets the value of the PathParam property for this object. - * - * @param pathParam - * The new value for the PathParam property for this object. - * @return Returns a reference to this object so that method calls can be chained together. - */ - Builder pathParam(String pathParam); - - /** - * Sets the value of the QueryParamOne property for this object. - * - * @param queryParamOne - * The new value for the QueryParamOne property for this object. - * @return Returns a reference to this object so that method calls can be chained together. - */ - Builder queryParamOne(String queryParamOne); - - /** - * Sets the value of the QueryParamTwo property for this object. - * - * @param queryParamTwo - * The new value for the QueryParamTwo property for this object. - * @return Returns a reference to this object so that method calls can be chained together. - */ - Builder queryParamTwo(String queryParamTwo); - - /** - * Sets the value of the StringHeaderMember property for this object. - * - * @param stringHeaderMember - * The new value for the StringHeaderMember property for this object. - * @return Returns a reference to this object so that method calls can be chained together. - */ - Builder stringHeaderMember(String stringHeaderMember); - - /** - * Sets the value of the NestedQueryParameterOperation property for this object. - * - * @param nestedQueryParameterOperation - * The new value for the NestedQueryParameterOperation property for this object. - * @return Returns a reference to this object so that method calls can be chained together. - */ - Builder nestedQueryParameterOperation(NestedQueryParameterOperation nestedQueryParameterOperation); - - /** - * Sets the value of the NestedQueryParameterOperation property for this object. - * - * This is a convenience method that creates an instance of the {@link NestedQueryParameterOperation.Builder} - * avoiding the need to create one manually via {@link NestedQueryParameterOperation#builder()}. - * - *

- * When the {@link Consumer} completes, {@link NestedQueryParameterOperation.Builder#build()} is called - * immediately and its result is passed to {@link #nestedQueryParameterOperation(NestedQueryParameterOperation)}. - * - * @param nestedQueryParameterOperation - * a consumer that will call methods on {@link NestedQueryParameterOperation.Builder} - * @return Returns a reference to this object so that method calls can be chained together. - * @see #nestedQueryParameterOperation(NestedQueryParameterOperation) - */ - default Builder nestedQueryParameterOperation( - Consumer nestedQueryParameterOperation) { - return nestedQueryParameterOperation(NestedQueryParameterOperation.builder() - .applyMutation(nestedQueryParameterOperation).build()); - } - - /** - * Sets the value of the RequiredListQueryParams property for this object. - * - * @param requiredListQueryParams - * The new value for the RequiredListQueryParams property for this object. - * @return Returns a reference to this object so that method calls can be chained together. - */ - Builder requiredListQueryParams(Collection requiredListQueryParams); - - /** - * Sets the value of the RequiredListQueryParams property for this object. - * - * @param requiredListQueryParams - * The new value for the RequiredListQueryParams property for this object. - * @return Returns a reference to this object so that method calls can be chained together. - */ - Builder requiredListQueryParams(Integer... requiredListQueryParams); - - /** - * Sets the value of the OptionalListQueryParams property for this object. - * - * @param optionalListQueryParams - * The new value for the OptionalListQueryParams property for this object. - * @return Returns a reference to this object so that method calls can be chained together. - */ - Builder optionalListQueryParams(Collection optionalListQueryParams); - - /** - * Sets the value of the OptionalListQueryParams property for this object. - * - * @param optionalListQueryParams - * The new value for the OptionalListQueryParams property for this object. - * @return Returns a reference to this object so that method calls can be chained together. - */ - Builder optionalListQueryParams(Integer... optionalListQueryParams); - - @Override - Builder overrideConfiguration(AwsRequestOverrideConfiguration overrideConfiguration); - - @Override - Builder overrideConfiguration(Consumer builderConsumer); - } - - static final class BuilderImpl extends JsonProtocolTestsRequest.BuilderImpl implements Builder { - private String pathParam; - - private String queryParamOne; - - private String queryParamTwo; - - private String stringHeaderMember; - - private NestedQueryParameterOperation nestedQueryParameterOperation; - - private List requiredListQueryParams = DefaultSdkAutoConstructList.getInstance(); - - private List optionalListQueryParams = DefaultSdkAutoConstructList.getInstance(); - - private BuilderImpl() { - } - - private BuilderImpl(QueryParameterOperationRequest model) { - super(model); - pathParam(model.pathParam); - queryParamOne(model.queryParamOne); - queryParamTwo(model.queryParamTwo); - stringHeaderMember(model.stringHeaderMember); - nestedQueryParameterOperation(model.nestedQueryParameterOperation); - requiredListQueryParams(model.requiredListQueryParams); - optionalListQueryParams(model.optionalListQueryParams); - } - - public final String getPathParam() { - return pathParam; - } - - public final void setPathParam(String pathParam) { - this.pathParam = pathParam; - } - - @Override - public final Builder pathParam(String pathParam) { - this.pathParam = pathParam; - return this; - } - - public final String getQueryParamOne() { - return queryParamOne; - } - - public final void setQueryParamOne(String queryParamOne) { - this.queryParamOne = queryParamOne; - } - - @Override - public final Builder queryParamOne(String queryParamOne) { - this.queryParamOne = queryParamOne; - return this; - } - - public final String getQueryParamTwo() { - return queryParamTwo; - } - - public final void setQueryParamTwo(String queryParamTwo) { - this.queryParamTwo = queryParamTwo; - } - - @Override - public final Builder queryParamTwo(String queryParamTwo) { - this.queryParamTwo = queryParamTwo; - return this; - } - - public final String getStringHeaderMember() { - return stringHeaderMember; - } - - public final void setStringHeaderMember(String stringHeaderMember) { - this.stringHeaderMember = stringHeaderMember; - } - - @Override - public final Builder stringHeaderMember(String stringHeaderMember) { - this.stringHeaderMember = stringHeaderMember; - return this; - } - - public final NestedQueryParameterOperation.Builder getNestedQueryParameterOperation() { - return nestedQueryParameterOperation != null ? nestedQueryParameterOperation.toBuilder() : null; - } - - public final void setNestedQueryParameterOperation(NestedQueryParameterOperation.BuilderImpl nestedQueryParameterOperation) { - this.nestedQueryParameterOperation = nestedQueryParameterOperation != null ? nestedQueryParameterOperation.build() - : null; - } - - @Override - public final Builder nestedQueryParameterOperation(NestedQueryParameterOperation nestedQueryParameterOperation) { - this.nestedQueryParameterOperation = nestedQueryParameterOperation; - return this; - } - - public final Collection getRequiredListQueryParams() { - if (requiredListQueryParams instanceof SdkAutoConstructList) { - return null; - } - return requiredListQueryParams; - } - - public final void setRequiredListQueryParams(Collection requiredListQueryParams) { - this.requiredListQueryParams = ListOfIntegersCopier.copy(requiredListQueryParams); - } - - @Override - public final Builder requiredListQueryParams(Collection requiredListQueryParams) { - this.requiredListQueryParams = ListOfIntegersCopier.copy(requiredListQueryParams); - return this; - } - - @Override - @SafeVarargs - public final Builder requiredListQueryParams(Integer... requiredListQueryParams) { - requiredListQueryParams(Arrays.asList(requiredListQueryParams)); - return this; - } - - public final Collection getOptionalListQueryParams() { - if (optionalListQueryParams instanceof SdkAutoConstructList) { - return null; - } - return optionalListQueryParams; - } - - public final void setOptionalListQueryParams(Collection optionalListQueryParams) { - this.optionalListQueryParams = ListOfIntegersCopier.copy(optionalListQueryParams); - } - - @Override - public final Builder optionalListQueryParams(Collection optionalListQueryParams) { - this.optionalListQueryParams = ListOfIntegersCopier.copy(optionalListQueryParams); - return this; - } - - @Override - @SafeVarargs - public final Builder optionalListQueryParams(Integer... optionalListQueryParams) { - optionalListQueryParams(Arrays.asList(optionalListQueryParams)); - return this; - } - - @Override - public Builder overrideConfiguration(AwsRequestOverrideConfiguration overrideConfiguration) { - super.overrideConfiguration(overrideConfiguration); - return this; - } - - @Override - public Builder overrideConfiguration(Consumer builderConsumer) { - super.overrideConfiguration(builderConsumer); - return this; - } - - @Override - public QueryParameterOperationRequest build() { - return new QueryParameterOperationRequest(this); - } - - @Override - public List> sdkFields() { - return SDK_FIELDS; - } - - @Override - public Map> sdkFieldNameToField() { - return SDK_NAME_TO_FIELD; - } + public Map> sdkFieldNameToField() { + return SDK_NAME_TO_FIELD; } + } } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/queryparameteroperationresponse.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/queryparameteroperationresponse.java index 14376b1d1c97..e87e085e71de 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/queryparameteroperationresponse.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/queryparameteroperationresponse.java @@ -1,122 +1,331 @@ package software.amazon.awssdk.services.jsonprotocoltests.model; +import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.Function; import software.amazon.awssdk.annotations.Generated; import software.amazon.awssdk.annotations.Mutable; import software.amazon.awssdk.annotations.NotThreadSafe; import software.amazon.awssdk.core.SdkField; import software.amazon.awssdk.core.SdkPojo; +import software.amazon.awssdk.core.protocol.MarshallLocation; +import software.amazon.awssdk.core.protocol.MarshallingType; +import software.amazon.awssdk.core.traits.LocationTrait; import software.amazon.awssdk.utils.ToString; import software.amazon.awssdk.utils.builder.CopyableBuilder; import software.amazon.awssdk.utils.builder.ToCopyableBuilder; +/** + */ @Generated("software.amazon.awssdk:codegen") -public final class QueryParameterOperationResponse extends JsonProtocolTestsResponse implements - ToCopyableBuilder { - private static final List> SDK_FIELDS = Collections.emptyList(); +public final class QueryParameterOperationResponse extends JsonProtocolTestsResponse implements ToCopyableBuilder { + private static final SdkField RESPONSE_HEADER_MEMBER_FIELD = SdkField.builder(MarshallingType.STRING) + .memberName("ResponseHeaderMember") + .getter(getter(QueryParameterOperationResponse::responseHeaderMember)) + .setter(setter(Builder::responseHeaderMember)) + .traits(LocationTrait.builder() + .location(MarshallLocation.HEADER) + .locationName("x-amz-response-header") + .build()).build(); - private static final Map> SDK_NAME_TO_FIELD = memberNameToFieldInitializer(); + private static final SdkField RESPONSE_STATUS_CODE_FIELD = SdkField.builder(MarshallingType.INTEGER) + .memberName("ResponseStatusCode") + .getter(getter(QueryParameterOperationResponse::responseStatusCode)) + .setter(setter(Builder::responseStatusCode)) + .traits(LocationTrait.builder() + .location(MarshallLocation.STATUS_CODE) + .locationName("ResponseStatusCode") + .build()).build(); - private QueryParameterOperationResponse(BuilderImpl builder) { - super(builder); + private static final SdkField URI_MEMBER_ON_OUTPUT_FIELD = SdkField.builder(MarshallingType.STRING) + .memberName("UriMemberOnOutput") + .getter(getter(QueryParameterOperationResponse::uriMemberOnOutput)) + .setter(setter(Builder::uriMemberOnOutput)) + .traits(LocationTrait.builder() + .location(MarshallLocation.PAYLOAD) + .locationName("UriMemberOnOutput") + .build()).build(); + + private static final SdkField QUERY_MEMBER_ON_OUTPUT_FIELD = SdkField.builder(MarshallingType.STRING) + .memberName("QueryMemberOnOutput") + .getter(getter(QueryParameterOperationResponse::queryMemberOnOutput)) + .setter(setter(Builder::queryMemberOnOutput)) + .traits(LocationTrait.builder() + .location(MarshallLocation.PAYLOAD) + .locationName("QueryMemberOnOutput") + .build()).build(); + + private static final List> SDK_FIELDS = Collections.unmodifiableList(Arrays.asList(RESPONSE_HEADER_MEMBER_FIELD,RESPONSE_STATUS_CODE_FIELD,URI_MEMBER_ON_OUTPUT_FIELD,QUERY_MEMBER_ON_OUTPUT_FIELD)); + + private static final Map> SDK_NAME_TO_FIELD = memberNameToFieldInitializer(); + + private final String responseHeaderMember; + + private final Integer responseStatusCode; + + private final String uriMemberOnOutput; + + private final String queryMemberOnOutput; + + private QueryParameterOperationResponse(BuilderImpl builder) { + super(builder); + this.responseHeaderMember = builder.responseHeaderMember; + this.responseStatusCode = builder.responseStatusCode; + this.uriMemberOnOutput = builder.uriMemberOnOutput; + this.queryMemberOnOutput = builder.queryMemberOnOutput; + } + + /** + * Returns the value of the ResponseHeaderMember property for this object. + * @return The value of the ResponseHeaderMember property for this object. + */ + public final String responseHeaderMember() { + return responseHeaderMember; + } + + /** + * Returns the value of the ResponseStatusCode property for this object. + * @return The value of the ResponseStatusCode property for this object. + */ + public final Integer responseStatusCode() { + return responseStatusCode; + } + + /** + * Returns the value of the UriMemberOnOutput property for this object. + * @return The value of the UriMemberOnOutput property for this object. + */ + public final String uriMemberOnOutput() { + return uriMemberOnOutput; + } + + /** + * Returns the value of the QueryMemberOnOutput property for this object. + * @return The value of the QueryMemberOnOutput property for this object. + */ + public final String queryMemberOnOutput() { + return queryMemberOnOutput; + } + + @Override + public Builder toBuilder() { + return new BuilderImpl(this); + } + + public static Builder builder() { + return new BuilderImpl(); + } + + public static Class serializableBuilderClass() { + return BuilderImpl.class; + } + + @Override + public final int hashCode() { + int hashCode = 1; + hashCode = 31 * hashCode + super.hashCode(); + hashCode = 31 * hashCode + Objects.hashCode(responseHeaderMember()); + hashCode = 31 * hashCode + Objects.hashCode(responseStatusCode()); + hashCode = 31 * hashCode + Objects.hashCode(uriMemberOnOutput()); + hashCode = 31 * hashCode + Objects.hashCode(queryMemberOnOutput()); + return hashCode; + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj) && equalsBySdkFields(obj); + } + + @Override + public final boolean equalsBySdkFields(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; } + if (!(obj instanceof QueryParameterOperationResponse)) { + return false; + } + QueryParameterOperationResponse other = (QueryParameterOperationResponse) obj; + return Objects.equals(responseHeaderMember(), other.responseHeaderMember())&&Objects.equals(responseStatusCode(), other.responseStatusCode())&&Objects.equals(uriMemberOnOutput(), other.uriMemberOnOutput())&&Objects.equals(queryMemberOnOutput(), other.queryMemberOnOutput()); + } - @Override - public Builder toBuilder() { - return new BuilderImpl(this); + /** + * Returns a string representation of this object. This is useful for testing and debugging. Sensitive data will be redacted from this string using a placeholder value. + */ + @Override + public final String toString() { + return ToString.builder("QueryParameterOperationResponse").add("ResponseHeaderMember", responseHeaderMember()).add("ResponseStatusCode", responseStatusCode()).add("UriMemberOnOutput", uriMemberOnOutput()).add("QueryMemberOnOutput", queryMemberOnOutput()).build(); + } + + public final Optional getValueForField(String fieldName, Class clazz) { + switch (fieldName) { + case "ResponseHeaderMember":return Optional.ofNullable(clazz.cast(responseHeaderMember())); + case "ResponseStatusCode":return Optional.ofNullable(clazz.cast(responseStatusCode())); + case "UriMemberOnOutput":return Optional.ofNullable(clazz.cast(uriMemberOnOutput())); + case "QueryMemberOnOutput":return Optional.ofNullable(clazz.cast(queryMemberOnOutput())); + default:return Optional.empty(); + } + } + + @Override + public final List> sdkFields() { + return SDK_FIELDS; + } + + @Override + public final Map> sdkFieldNameToField() { + return SDK_NAME_TO_FIELD; + } + + private static Map> memberNameToFieldInitializer() { + Map> map = new HashMap<>(); + map.put("x-amz-response-header", RESPONSE_HEADER_MEMBER_FIELD); + map.put("ResponseStatusCode", RESPONSE_STATUS_CODE_FIELD); + map.put("UriMemberOnOutput", URI_MEMBER_ON_OUTPUT_FIELD); + map.put("QueryMemberOnOutput", QUERY_MEMBER_ON_OUTPUT_FIELD); + return Collections.unmodifiableMap(map); + } + + private static Function getter(Function g) { + return obj -> g.apply((QueryParameterOperationResponse) obj); + } + + private static BiConsumer setter(BiConsumer s) { + return (obj, val) -> s.accept((Builder) obj, val); + } + + @Mutable + @NotThreadSafe + public interface Builder extends JsonProtocolTestsResponse.Builder, SdkPojo, CopyableBuilder { + /** + * Sets the value of the ResponseHeaderMember property for this object. + * + * @param responseHeaderMember The new value for the ResponseHeaderMember property for this object. + * @return Returns a reference to this object so that method calls can be chained together. + */ + Builder responseHeaderMember(String responseHeaderMember); + + /** + * Sets the value of the ResponseStatusCode property for this object. + * + * @param responseStatusCode The new value for the ResponseStatusCode property for this object. + * @return Returns a reference to this object so that method calls can be chained together. + */ + Builder responseStatusCode(Integer responseStatusCode); + + /** + * Sets the value of the UriMemberOnOutput property for this object. + * + * @param uriMemberOnOutput The new value for the UriMemberOnOutput property for this object. + * @return Returns a reference to this object so that method calls can be chained together. + */ + Builder uriMemberOnOutput(String uriMemberOnOutput); + + /** + * Sets the value of the QueryMemberOnOutput property for this object. + * + * @param queryMemberOnOutput The new value for the QueryMemberOnOutput property for this object. + * @return Returns a reference to this object so that method calls can be chained together. + */ + Builder queryMemberOnOutput(String queryMemberOnOutput); + } + + static final class BuilderImpl extends JsonProtocolTestsResponse.BuilderImpl implements Builder { + private String responseHeaderMember; + + private Integer responseStatusCode; + + private String uriMemberOnOutput; + + private String queryMemberOnOutput; + + private BuilderImpl() { } - public static Builder builder() { - return new BuilderImpl(); + private BuilderImpl(QueryParameterOperationResponse model) { + super(model);responseHeaderMember(model.responseHeaderMember); + responseStatusCode(model.responseStatusCode); + uriMemberOnOutput(model.uriMemberOnOutput); + queryMemberOnOutput(model.queryMemberOnOutput); } - public static Class serializableBuilderClass() { - return BuilderImpl.class; + public final String getResponseHeaderMember() { + return responseHeaderMember; } - @Override - public final int hashCode() { - int hashCode = 1; - hashCode = 31 * hashCode + super.hashCode(); - return hashCode; + public final void setResponseHeaderMember(String responseHeaderMember) { + this.responseHeaderMember = responseHeaderMember; } @Override - public final boolean equals(Object obj) { - return super.equals(obj) && equalsBySdkFields(obj); + public final Builder responseHeaderMember(String responseHeaderMember) { + this.responseHeaderMember = responseHeaderMember; + return this; } - @Override - public final boolean equalsBySdkFields(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof QueryParameterOperationResponse)) { - return false; - } - return true; + public final Integer getResponseStatusCode() { + return responseStatusCode; + } + + public final void setResponseStatusCode(Integer responseStatusCode) { + this.responseStatusCode = responseStatusCode; } - /** - * Returns a string representation of this object. This is useful for testing and debugging. Sensitive data will be - * redacted from this string using a placeholder value. - */ @Override - public final String toString() { - return ToString.builder("QueryParameterOperationResponse").build(); + public final Builder responseStatusCode(Integer responseStatusCode) { + this.responseStatusCode = responseStatusCode; + return this; } - public final Optional getValueForField(String fieldName, Class clazz) { - return Optional.empty(); + public final String getUriMemberOnOutput() { + return uriMemberOnOutput; } - @Override - public final List> sdkFields() { - return SDK_FIELDS; + public final void setUriMemberOnOutput(String uriMemberOnOutput) { + this.uriMemberOnOutput = uriMemberOnOutput; } @Override - public final Map> sdkFieldNameToField() { - return SDK_NAME_TO_FIELD; + public final Builder uriMemberOnOutput(String uriMemberOnOutput) { + this.uriMemberOnOutput = uriMemberOnOutput; + return this; } - private static Map> memberNameToFieldInitializer() { - return Collections.emptyMap(); + public final String getQueryMemberOnOutput() { + return queryMemberOnOutput; } - @Mutable - @NotThreadSafe - public interface Builder extends JsonProtocolTestsResponse.Builder, SdkPojo, - CopyableBuilder { + public final void setQueryMemberOnOutput(String queryMemberOnOutput) { + this.queryMemberOnOutput = queryMemberOnOutput; } - static final class BuilderImpl extends JsonProtocolTestsResponse.BuilderImpl implements Builder { - private BuilderImpl() { - } - - private BuilderImpl(QueryParameterOperationResponse model) { - super(model); - } + @Override + public final Builder queryMemberOnOutput(String queryMemberOnOutput) { + this.queryMemberOnOutput = queryMemberOnOutput; + return this; + } - @Override - public QueryParameterOperationResponse build() { - return new QueryParameterOperationResponse(this); - } + @Override + public QueryParameterOperationResponse build() { + return new QueryParameterOperationResponse(this); + } - @Override - public List> sdkFields() { - return SDK_FIELDS; - } + @Override + public List> sdkFields() { + return SDK_FIELDS; + } - @Override - public Map> sdkFieldNameToField() { - return SDK_NAME_TO_FIELD; - } + @Override + public Map> sdkFieldNameToField() { + return SDK_NAME_TO_FIELD; } + } } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/service-2.json b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/service-2.json index 5b2f1c8ebcaf..0699c8297a79 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/service-2.json +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/service-2.json @@ -127,7 +127,8 @@ "method":"DELETE", "requestUri":"/2016-03-11/queryParameterOperation/{PathParam}" }, - "input":{"shape":"QueryParameterOperationRequest"} + "input":{"shape":"QueryParameterOperationRequest"}, + "output":{"shape":"QueryParameterOperationResponse"} }, "OperationWithReservedKeywordMember": { "name": "DeprecatedRename", @@ -640,6 +641,15 @@ "shape":"String", "location":"querystring", "locationName":"QueryParamTwo" + }, + "NestedHeaderMember":{ + "shape":"String", + "location":"header", + "locationName":"x-amz-nested-header" + }, + "NestedStatusCode":{ + "shape":"Integer", + "location":"statusCode" } } }, @@ -682,10 +692,42 @@ "OptionalListQueryParams":{ "shape":"ListOfIntegers", "location":"querystring" + }, + "StatusCodeOnInput":{ + "shape":"Integer", + "location":"statusCode" + }, + "PayloadMemberWithCustomName":{ + "shape":"String", + "locationName":"CustomWireName" } }, "payload":"NestedQueryParameterOperation" }, + "QueryParameterOperationResponse":{ + "type":"structure", + "members":{ + "ResponseHeaderMember":{ + "shape":"String", + "location":"header", + "locationName":"x-amz-response-header" + }, + "ResponseStatusCode":{ + "shape":"Integer", + "location":"statusCode" + }, + "UriMemberOnOutput":{ + "shape":"String", + "location":"uri", + "locationName":"UriMemberOnOutput" + }, + "QueryMemberOnOutput":{ + "shape":"String", + "location":"querystring", + "locationName":"QueryMemberOnOutput" + } + } + }, "ContainsReservedKeyword": { "type": "structure", "members": { diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/uri-on-non-input-shape-service.json b/codegen/src/test/resources/software/amazon/awssdk/codegen/uri-on-non-input-shape-service.json new file mode 100644 index 000000000000..f858a11b94ed --- /dev/null +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/uri-on-non-input-shape-service.json @@ -0,0 +1,100 @@ +{ + "version": "2.0", + "metadata": { + "apiVersion": "2010-05-08", + "endpointPrefix": "json-service-endpoint", + "globalEndpoint": "json-service.amazonaws.com", + "protocol": "rest-json", + "serviceAbbreviation": "Rest Json Service", + "serviceFullName": "Some Service That Uses Rest-Json Protocol", + "serviceId": "Rest Json Service", + "signingName": "json-service", + "signatureVersion": "v4", + "uid": "json-service-2010-05-08", + "xmlNamespace": "https://json-service.amazonaws.com/doc/2010-05-08/" + }, + "operations": { + "SomeOperation": { + "name": "SomeOperation", + "http": { + "method": "POST", + "requestUri": "/things/{thingId}" + }, + "input": { + "shape": "SomeOperationRequest" + } + }, + "SharedShapeOperation": { + "name": "SharedShapeOperation", + "http": { + "method": "GET", + "requestUri": "/shared/{sharedId}" + }, + "input": { + "shape": "SharedShape" + } + } + }, + "shapes": { + "SomeOperationRequest": { + "type": "structure", + "members": { + "thingId": { + "shape": "String", + "location": "uri", + "locationName": "thingId" + }, + "options": { + "shape": "NestedOptions" + }, + "shared": { + "shape": "SharedShape" + } + } + }, + "NestedOptions": { + "type": "structure", + "members": { + "pageSize": { + "shape": "String", + "location": "uri", + "locationName": "pageSize" + }, + "headerParam": { + "shape": "String", + "location": "header", + "locationName": "x-amz-nested-header" + }, + "queryParam": { + "shape": "String", + "location": "querystring", + "locationName": "nestedQuery" + }, + "prefixHeaders": { + "shape": "MapOfStrings", + "location": "headers", + "locationName": "x-amz-prefix-" + } + } + }, + "SharedShape": { + "type": "structure", + "members": { + "sharedId": { + "shape": "String", + "location": "uri", + "locationName": "sharedId" + } + } + }, + "String": { + "type": "string" + }, + "MapOfStrings": { + "type": "map", + "key": {"shape": "String"}, + "value": {"shape": "String"} + } + }, + "documentation": "A service with HTTP binding locations on non-input shapes" +} diff --git a/test/protocol-tests/src/main/resources/codegen-resources/restjson/service-2.json b/test/protocol-tests/src/main/resources/codegen-resources/restjson/service-2.json index c0348f5b1ca6..24d50a060735 100644 --- a/test/protocol-tests/src/main/resources/codegen-resources/restjson/service-2.json +++ b/test/protocol-tests/src/main/resources/codegen-resources/restjson/service-2.json @@ -255,6 +255,15 @@ "requestUri":"/2016-03-11/documentInputOperation" }, "input":{"shape":"StructureWithDocumentMember"} + }, + "NestedLocationOperation":{ + "name":"NestedLocationOperation", + "http":{ + "method":"POST", + "requestUri":"/2016-03-11/nestedLocationOperation" + }, + "input":{"shape":"NestedLocationOperationInput"}, + "output":{"shape":"NestedLocationOperationOutput"} } }, "shapes":{ @@ -782,6 +791,50 @@ "StringMember":{"shape":"String"} } }, + "NestedLocationOperationInput":{ + "type":"structure", + "members":{ + "TopLevelQueryParam":{ + "shape":"String", + "location":"querystring", + "locationName":"topLevel" + }, + "Nested":{"shape":"NestedShapeWithLocations"} + } + }, + "NestedShapeWithLocations":{ + "type":"structure", + "members":{ + "NestedQueryParam":{ + "shape":"String", + "location":"querystring", + "locationName":"shouldBeIgnored" + }, + "StringMember":{"shape":"String"} + } + }, + "NestedLocationOperationOutput":{ + "type":"structure", + "members":{ + "TopLevelHeader":{ + "shape":"String", + "location":"header", + "locationName":"x-amz-top-level" + }, + "NestedResult":{"shape":"NestedResponseData"} + } + }, + "NestedResponseData":{ + "type":"structure", + "members":{ + "NestedHeader":{ + "shape":"String", + "location":"header", + "locationName":"x-amz-should-be-ignored" + }, + "Value":{"shape":"String"} + } + }, "StatusCodeInOutputStructure":{ "type":"structure", "members":{ diff --git a/test/protocol-tests/src/test/java/software/amazon/awssdk/protocol/tests/NestedLocationSerializationTest.java b/test/protocol-tests/src/test/java/software/amazon/awssdk/protocol/tests/NestedLocationSerializationTest.java new file mode 100644 index 000000000000..9941c0226d28 --- /dev/null +++ b/test/protocol-tests/src/test/java/software/amazon/awssdk/protocol/tests/NestedLocationSerializationTest.java @@ -0,0 +1,93 @@ +/* + * 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.protocol.tests; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.anyUrl; +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; +import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.verify; +import static org.assertj.core.api.Assertions.assertThat; + +import com.github.tomakehurst.wiremock.junit.WireMockRule; +import java.net.URI; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.protocolrestjson.ProtocolRestJsonClient; +import software.amazon.awssdk.services.protocolrestjson.model.NestedLocationOperationRequest; +import software.amazon.awssdk.services.protocolrestjson.model.NestedLocationOperationResponse; +import software.amazon.awssdk.services.protocolrestjson.model.NestedShapeWithLocations; + +/** + * Verifies that HTTP binding locations on non-input shapes are ignored per the Smithy spec, + * and the members are serialized into the request body instead. + */ +public class NestedLocationSerializationTest { + + @Rule + public WireMockRule wireMock = new WireMockRule(0); + + private ProtocolRestJsonClient client; + + @Before + public void setup() { + client = ProtocolRestJsonClient.builder() + .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("akid", "skid"))) + .region(Region.US_EAST_1) + .endpointOverride(URI.create("http://localhost:" + wireMock.port())) + .build(); + } + + @Test + public void nestedMemberWithLocation_serializedToBodyNotQueryParam() { + stubFor(post(anyUrl()).willReturn(aResponse().withStatus(200).withBody("{}"))); + + client.nestedLocationOperation(NestedLocationOperationRequest.builder() + .topLevelQueryParam("topValue") + .nested(NestedShapeWithLocations.builder() + .nestedQueryParam("nestedValue") + .stringMember("hello") + .build()) + .build()); + + verify(postRequestedFor(anyUrl()).withQueryParam("topLevel", equalTo("topValue"))); + + verify(postRequestedFor(anyUrl()).withRequestBody( + equalToJson("{\"Nested\":{\"NestedQueryParam\":\"nestedValue\",\"StringMember\":\"hello\"}}"))); + } + + @Test + public void nestedMemberWithLocation_deserializedFromBodyNotHeader() { + stubFor(post(anyUrl()).willReturn(aResponse() + .withStatus(200) + .withHeader("x-amz-top-level", "headerValue") + .withBody("{\"NestedResult\":{\"NestedHeader\":\"from-body\",\"Value\":\"hello\"}}"))); + + NestedLocationOperationResponse response = client.nestedLocationOperation( + NestedLocationOperationRequest.builder().build()); + + assertThat(response.topLevelHeader()).isEqualTo("headerValue"); + assertThat(response.nestedResult().nestedHeader()).isEqualTo("from-body"); + assertThat(response.nestedResult().value()).isEqualTo("hello"); + } +}