Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify SDK to not fail on invalid Expires header #5056

Merged
merged 27 commits into from Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
2501c57
Add Warnings in the async client interface and CrtClient against pass…
anirudh9391 Mar 14, 2024
273ce0f
Update warning message
anirudh9391 Mar 14, 2024
5c22f5c
Updated warning message
anirudh9391 Mar 14, 2024
10ae28e
Added paragraph notation
anirudh9391 Mar 25, 2024
5ab3dec
Add a paragraph notation
anirudh9391 Mar 25, 2024
1141cb4
Merge branch 'master' into warnings
anirudh9391 Mar 25, 2024
04d4c39
Merge branch 'master' into warnings
anirudh9391 Mar 25, 2024
c5c251a
Merge branch 'master' into warnings
anirudh9391 Mar 26, 2024
512dee9
Modify S3 expires field to not fail on parsing errors and instead, lo…
anirudh9391 Mar 29, 2024
b4b4301
Merge branch 'master' into anirudkr/s3-sep-expires
anirudh9391 Mar 29, 2024
138afae
Fix checkstyle issues
anirudh9391 Mar 29, 2024
b24643e
Merge branch 'master' into anirudkr/s3-sep-expires
anirudh9391 Mar 29, 2024
a5d94d5
Fixed duplicates in customization.config definition
anirudh9391 Mar 29, 2024
9142048
Remove duplicate definitions
anirudh9391 Mar 31, 2024
3038755
Merge branch 'master' into anirudkr/s3-sep-expires
anirudh9391 Apr 23, 2024
a57a378
Facilitate custom handling of data type conversion errors
anirudh9391 Apr 25, 2024
05f0467
Merge branch 'master' into anirudkr/s3-sep-expires
anirudh9391 Apr 25, 2024
af0aa2d
Removed test class
anirudh9391 Apr 25, 2024
4dc79bf
Remove incorrectly added statements
anirudh9391 Apr 25, 2024
a6824f3
Added Unit tests
anirudh9391 Apr 29, 2024
480112b
Merge branch 'master' into anirudkr/s3-sep-expires
anirudh9391 Apr 29, 2024
fb9d299
Changed to Junit5
anirudh9391 Apr 29, 2024
e2e52e1
Fixed checkstyle issues
anirudh9391 Apr 29, 2024
db0952d
Added wiremock
anirudh9391 Apr 29, 2024
b032c93
assertThat instead of assertTrue and logged the entire exception stack
anirudh9391 Apr 29, 2024
b0c759a
modified error message
anirudh9391 Apr 29, 2024
0579070
Merge branch 'master' into anirudkr/s3-sep-expires
anirudh9391 Apr 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -160,6 +160,11 @@ private void postprocessModifyMemberProperty(ShapeModel shapeModel, String membe
.getUnmarshallLocationName());
}

if (modifyModel.isIgnoreDataTypeConversionFailures()) {
MemberModel memberModel = shapeModel.findMemberModelByC2jName(memberName);
memberModel.ignoreDataTypeConversionFailures(true);
}

}

/**
Expand Down
Expand Up @@ -59,6 +59,11 @@ public class ModifyModelShapeModifier {

private String unmarshallLocationName;

/**
* Indicates whether data type conversion failures are to be ignored
*/
private boolean ignoreDataTypeConversionFailures;

public String getDeprecatedMessage() {
return deprecatedMessage;
}
Expand Down Expand Up @@ -130,4 +135,12 @@ public String getEmitAsType() {
public void setEmitAsType(String emitAsType) {
this.emitAsType = emitAsType;
}

public void setIgnoreDataTypeConversionFailures(boolean ignoreDataTypeConversionFailures) {
this.ignoreDataTypeConversionFailures = ignoreDataTypeConversionFailures;
}

public boolean isIgnoreDataTypeConversionFailures() {
return ignoreDataTypeConversionFailures;
}
}
Expand Up @@ -115,6 +115,8 @@ public class MemberModel extends DocumentationModel {

private ContextParam contextParam;

private boolean ignoreDataTypeConversionFailures;

public String getName() {
return name;
}
Expand Down Expand Up @@ -775,4 +777,12 @@ public ContextParam getContextParam() {
public void setContextParam(ContextParam contextParam) {
this.contextParam = contextParam;
}

public void ignoreDataTypeConversionFailures(boolean ignoreDataTypeConversionFailures) {
this.ignoreDataTypeConversionFailures = ignoreDataTypeConversionFailures;
}

public boolean ignoreDataTypeConversionFailures() {
return ignoreDataTypeConversionFailures;
}
}
Expand Up @@ -39,6 +39,7 @@
import software.amazon.awssdk.core.SdkField;
import software.amazon.awssdk.core.protocol.MarshallLocation;
import software.amazon.awssdk.core.protocol.MarshallingType;
import software.amazon.awssdk.core.traits.DataTypeConversionFailureHandlingTrait;
import software.amazon.awssdk.core.traits.DefaultValueTrait;
import software.amazon.awssdk.core.traits.JsonValueTrait;
import software.amazon.awssdk.core.traits.ListTrait;
Expand Down Expand Up @@ -186,6 +187,10 @@ private CodeBlock traits(MemberModel m) {
if (m.isXmlAttribute()) {
traits.add(createXmlAttributeTrait());
}

if (m.ignoreDataTypeConversionFailures()) {
traits.add(createDataTypeConversionFailureHandlingTrait());
}
if (customizationConfig.isRequiredTraitValidationEnabled() && m.isRequired()) {
traits.add(createRequiredTrait());
}
Expand All @@ -206,6 +211,12 @@ private boolean attachPayloadTraitToMember(MemberModel m) {
.equals(m.getC2jName());
}

private CodeBlock createDataTypeConversionFailureHandlingTrait() {
return CodeBlock.builder()
.add("new $T()", ClassName.get(DataTypeConversionFailureHandlingTrait.class))
.build();
}

private CodeBlock createTimestampFormatTrait(MemberModel m) {
TimestampFormatTrait.Format format = TimestampFormatTrait.Format.fromString(m.getTimestampFormat());
ClassName traitClass = ClassName.get(TimestampFormatTrait.class);
Expand Down
Expand Up @@ -26,6 +26,11 @@
"deprecated": true,
"deprecatedMessage": "This field is modified as deprecated."
}
},
{
"MemberIgnoreDataTypeFailureHandling": {
"ignoreDataTypeConversionFailures": "true"
}
}
]
},
Expand Down
Expand Up @@ -14,6 +14,7 @@
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.DataTypeConversionFailureHandlingTrait;
import software.amazon.awssdk.core.traits.LocationTrait;
import software.amazon.awssdk.utils.ToString;
import software.amazon.awssdk.utils.builder.CopyableBuilder;
Expand Down Expand Up @@ -45,20 +46,33 @@ public final class OperationWithDeprecatedMemberRequest extends JsonProtocolTest
.traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("UndeprecatedMember").build())
.build();

private static final SdkField<String> MEMBER_IGNORE_DATA_TYPE_FAILURE_HANDLING_FIELD = SdkField
.<String> builder(MarshallingType.STRING)
.memberName("MemberIgnoreDataTypeFailureHandling")
.getter(getter(OperationWithDeprecatedMemberRequest::memberIgnoreDataTypeFailureHandling))
.setter(setter(Builder::memberIgnoreDataTypeFailureHandling))
.traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD)
.locationName("MemberIgnoreDataTypeFailureHandling").build(), new DataTypeConversionFailureHandlingTrait())
.build();

private static final List<SdkField<?>> SDK_FIELDS = Collections.unmodifiableList(Arrays.asList(
MEMBER_MODELED_AS_DEPRECATED_FIELD, MEMBER_MODIFIED_AS_DEPRECATED_FIELD, UNDEPRECATED_MEMBER_FIELD));
MEMBER_MODELED_AS_DEPRECATED_FIELD, MEMBER_MODIFIED_AS_DEPRECATED_FIELD, UNDEPRECATED_MEMBER_FIELD,
MEMBER_IGNORE_DATA_TYPE_FAILURE_HANDLING_FIELD));

private final String memberModeledAsDeprecated;

private final String memberModifiedAsDeprecated;

private final String undeprecatedMember;

private final String memberIgnoreDataTypeFailureHandling;

private OperationWithDeprecatedMemberRequest(BuilderImpl builder) {
super(builder);
this.memberModeledAsDeprecated = builder.memberModeledAsDeprecated;
this.memberModifiedAsDeprecated = builder.memberModifiedAsDeprecated;
this.undeprecatedMember = builder.undeprecatedMember;
this.memberIgnoreDataTypeFailureHandling = builder.memberIgnoreDataTypeFailureHandling;
}

/**
Expand Down Expand Up @@ -92,6 +106,15 @@ public final String undeprecatedMember() {
return undeprecatedMember;
}

/**
* Returns the value of the MemberIgnoreDataTypeFailureHandling property for this object.
*
* @return The value of the MemberIgnoreDataTypeFailureHandling property for this object.
*/
public final String memberIgnoreDataTypeFailureHandling() {
return memberIgnoreDataTypeFailureHandling;
}

@Override
public Builder toBuilder() {
return new BuilderImpl(this);
Expand All @@ -112,6 +135,7 @@ public final int hashCode() {
hashCode = 31 * hashCode + Objects.hashCode(memberModeledAsDeprecated());
hashCode = 31 * hashCode + Objects.hashCode(memberModifiedAsDeprecated());
hashCode = 31 * hashCode + Objects.hashCode(undeprecatedMember());
hashCode = 31 * hashCode + Objects.hashCode(memberIgnoreDataTypeFailureHandling());
return hashCode;
}

Expand All @@ -134,7 +158,8 @@ public final boolean equalsBySdkFields(Object obj) {
OperationWithDeprecatedMemberRequest other = (OperationWithDeprecatedMemberRequest) obj;
return Objects.equals(memberModeledAsDeprecated(), other.memberModeledAsDeprecated())
&& Objects.equals(memberModifiedAsDeprecated(), other.memberModifiedAsDeprecated())
&& Objects.equals(undeprecatedMember(), other.undeprecatedMember());
&& Objects.equals(undeprecatedMember(), other.undeprecatedMember())
&& Objects.equals(memberIgnoreDataTypeFailureHandling(), other.memberIgnoreDataTypeFailureHandling());
}

/**
Expand All @@ -146,7 +171,7 @@ public final String toString() {
return ToString.builder("OperationWithDeprecatedMemberRequest")
.add("MemberModeledAsDeprecated", memberModeledAsDeprecated())
.add("MemberModifiedAsDeprecated", memberModifiedAsDeprecated()).add("UndeprecatedMember", undeprecatedMember())
.build();
.add("MemberIgnoreDataTypeFailureHandling", memberIgnoreDataTypeFailureHandling()).build();
}

public final <T> Optional<T> getValueForField(String fieldName, Class<T> clazz) {
Expand All @@ -157,6 +182,8 @@ public final <T> Optional<T> getValueForField(String fieldName, Class<T> clazz)
return Optional.ofNullable(clazz.cast(memberModifiedAsDeprecated()));
case "UndeprecatedMember":
return Optional.ofNullable(clazz.cast(undeprecatedMember()));
case "MemberIgnoreDataTypeFailureHandling":
return Optional.ofNullable(clazz.cast(memberIgnoreDataTypeFailureHandling()));
default:
return Optional.empty();
}
Expand Down Expand Up @@ -208,6 +235,15 @@ public interface Builder extends JsonProtocolTestsRequest.Builder, SdkPojo,
*/
Builder undeprecatedMember(String undeprecatedMember);

/**
* Sets the value of the MemberIgnoreDataTypeFailureHandling property for this object.
*
* @param memberIgnoreDataTypeFailureHandling
* The new value for the MemberIgnoreDataTypeFailureHandling property for this object.
* @return Returns a reference to this object so that method calls can be chained together.
*/
Builder memberIgnoreDataTypeFailureHandling(String memberIgnoreDataTypeFailureHandling);

@Override
Builder overrideConfiguration(AwsRequestOverrideConfiguration overrideConfiguration);

Expand All @@ -222,6 +258,8 @@ static final class BuilderImpl extends JsonProtocolTestsRequest.BuilderImpl impl

private String undeprecatedMember;

private String memberIgnoreDataTypeFailureHandling;

private BuilderImpl() {
}

Expand All @@ -230,6 +268,7 @@ private BuilderImpl(OperationWithDeprecatedMemberRequest model) {
memberModeledAsDeprecated(model.memberModeledAsDeprecated);
memberModifiedAsDeprecated(model.memberModifiedAsDeprecated);
undeprecatedMember(model.undeprecatedMember);
memberIgnoreDataTypeFailureHandling(model.memberIgnoreDataTypeFailureHandling);
}

@Deprecated
Expand Down Expand Up @@ -280,6 +319,20 @@ public final Builder undeprecatedMember(String undeprecatedMember) {
return this;
}

public final String getMemberIgnoreDataTypeFailureHandling() {
return memberIgnoreDataTypeFailureHandling;
}

public final void setMemberIgnoreDataTypeFailureHandling(String memberIgnoreDataTypeFailureHandling) {
this.memberIgnoreDataTypeFailureHandling = memberIgnoreDataTypeFailureHandling;
}

@Override
public final Builder memberIgnoreDataTypeFailureHandling(String memberIgnoreDataTypeFailureHandling) {
this.memberIgnoreDataTypeFailureHandling = memberIgnoreDataTypeFailureHandling;
return this;
}

@Override
public Builder overrideConfiguration(AwsRequestOverrideConfiguration overrideConfiguration) {
super.overrideConfiguration(overrideConfiguration);
Expand Down
Expand Up @@ -247,7 +247,8 @@
"deprecatedMessage": "This field is modeled as deprecated."
},
"MemberModifiedAsDeprecated":{"shape": "String"},
"UndeprecatedMember": {"shape": "String"}
"UndeprecatedMember": {"shape": "String"},
"MemberIgnoreDataTypeFailureHandling":{"shape": "String"}
}
},
"OperationWithDeprecatedMemberResponse":{
Expand Down
Expand Up @@ -26,6 +26,7 @@
import software.amazon.awssdk.core.SdkField;
import software.amazon.awssdk.protocols.core.StringToValueConverter;
import software.amazon.awssdk.protocols.query.unmarshall.XmlElement;
import software.amazon.awssdk.utils.Logger;

@SdkInternalApi
public final class HeaderUnmarshaller {
Expand Down Expand Up @@ -60,6 +61,7 @@ private HeaderUnmarshaller() {
}

private static class SimpleHeaderUnmarshaller<T> implements XmlUnmarshaller<T> {
private static final Logger log = Logger.loggerFor(SimpleHeaderUnmarshaller.class);

private final StringToValueConverter.StringToValue<T> stringToValue;

Expand All @@ -69,9 +71,17 @@ private SimpleHeaderUnmarshaller(StringToValueConverter.StringToValue<T> stringT

@Override
public T unmarshall(XmlUnmarshallerContext context, List<XmlElement> content, SdkField<T> field) {
return context.response().firstMatchingHeader(field.locationName())
.map(s -> stringToValue.convert(s, field))
.orElse(null);
try {
return context.response().firstMatchingHeader(field.locationName())
.map(s -> stringToValue.convert(s, field))
.orElse(null);
} catch (RuntimeException e) {
log.warn(() -> "Exception found while parsing response header " , e);
if (field.ignoreDataTypeConversionFailures()) {
return null;
}
throw e;
}
}
}
}
Expand Up @@ -25,6 +25,7 @@
import software.amazon.awssdk.annotations.SdkProtectedApi;
import software.amazon.awssdk.core.protocol.MarshallLocation;
import software.amazon.awssdk.core.protocol.MarshallingType;
import software.amazon.awssdk.core.traits.DataTypeConversionFailureHandlingTrait;
import software.amazon.awssdk.core.traits.DefaultValueTrait;
import software.amazon.awssdk.core.traits.LocationTrait;
import software.amazon.awssdk.core.traits.Trait;
Expand Down Expand Up @@ -86,6 +87,16 @@ public String locationName() {
return locationName;
}

/**
* @return whether data-type conversion errors are to be ignored
*/
public boolean ignoreDataTypeConversionFailures() {
DataTypeConversionFailureHandlingTrait dataTypeConversionFailureHandlingTrait =
getTrait(DataTypeConversionFailureHandlingTrait.class);

return dataTypeConversionFailureHandlingTrait != null;
}

/**
* @return The location name to use when unmarshalling. This is only needed for AWS/Query or EC2 services. All
* other services should use {@link #locationName} for both marshalling and unmarshalling.
Expand Down
@@ -0,0 +1,22 @@
/*
* 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.core.traits;

import software.amazon.awssdk.annotations.SdkProtectedApi;

@SdkProtectedApi
public class DataTypeConversionFailureHandlingTrait implements Trait {
}