From 2501c578ad55512fa8b4a9ee608d8bd99523d6e2 Mon Sep 17 00:00:00 2001
From: Krishnan
Date: Thu, 14 Mar 2024 10:01:06 -0700
Subject: [PATCH 01/18] Add Warnings in the async client interface and
CrtClient against passing in Runnable::run
---
.../awssdk/codegen/poet/client/AsyncClientInterface.java | 5 ++++-
.../poet/client/test-json-async-client-interface.java | 3 ++-
.../awssdk/services/s3/S3CrtAsyncClientBuilder.java | 8 +++++---
3 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientInterface.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientInterface.java
index 04f64c1b128c..1dd583eb3353 100644
--- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientInterface.java
+++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientInterface.java
@@ -169,7 +169,10 @@ public ClassName className() {
private String getJavadoc() {
return "Service client for accessing " + model.getMetadata().getDescriptiveServiceName() + " asynchronously. This can be "
- + "created using the static {@link #builder()} method.\n\n" + model.getMetadata().getDocumentation();
+ + "created using the static {@link #builder()} method.\nWe strongly discourage "
+ + "configuring main I/O threads to run future-completion objects. This could "
+ + "lead to deadlock as the SDK may perform blocking calls in some cases."
+ + "\n\n" + model.getMetadata().getDocumentation();
}
private MethodSpec create() {
diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-interface.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-interface.java
index ec3f92e7a92d..a376eb7447bf 100644
--- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-interface.java
+++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-interface.java
@@ -53,7 +53,8 @@
/**
* Service client for accessing Json Service asynchronously. This can be created using the static {@link #builder()}
- * method.
+ * method. We strongly discourage configuring main I/O threads to run future-completion objects. This could lead to
+ * deadlock as the SDK may perform blocking calls in some cases.
*
* A service that is implemented using the query protocol
*/
diff --git a/services/s3/src/main/java/software/amazon/awssdk/services/s3/S3CrtAsyncClientBuilder.java b/services/s3/src/main/java/software/amazon/awssdk/services/s3/S3CrtAsyncClientBuilder.java
index 23dc6ad7ce51..8005ccd909df 100644
--- a/services/s3/src/main/java/software/amazon/awssdk/services/s3/S3CrtAsyncClientBuilder.java
+++ b/services/s3/src/main/java/software/amazon/awssdk/services/s3/S3CrtAsyncClientBuilder.java
@@ -322,11 +322,13 @@ default S3CrtAsyncClientBuilder retryConfiguration(ConsumerYou want more fine-grained control over the {@link ThreadPoolExecutor} used, such as configuring the pool size
* or sharing a single pool between multiple clients.
* You want to add instrumentation (i.e., metrics) around how the {@link Executor} is used.
- * You know, for certain, that all of your {@link CompletableFuture} usage is strictly non-blocking, and you wish to
- * remove the minor overhead incurred by using a separate thread. In this case, you can use
- * {@code Runnable::run} to execute the future-completion directly from within the I/O thread.
*
*
+ * WARNING
+ * We strongly discourage using {@code Runnable::run}, which executes the future-completion directly from
+ * within the I/O thread because it may block the I/O thread and cause deadlock, especially if you are sending
+ * another SDK request in the {@link CompletableFuture} chain since the SDK may perform blocking calls in some cases.
+ *
* @param futureCompletionExecutor the executor
* @return an instance of this builder.
*/
From 273ce0fa52bf7a134b425576fe45b335fd3c712c Mon Sep 17 00:00:00 2001
From: Krishnan
Date: Thu, 14 Mar 2024 11:17:18 -0700
Subject: [PATCH 02/18] Update warning message
---
.../poet/client/test-json-async-client-interface.java | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-interface.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-interface.java
index a376eb7447bf..c8c8d794e53b 100644
--- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-interface.java
+++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-interface.java
@@ -53,8 +53,9 @@
/**
* Service client for accessing Json Service asynchronously. This can be created using the static {@link #builder()}
- * method. We strongly discourage configuring main I/O threads to run future-completion objects. This could lead to
- * deadlock as the SDK may perform blocking calls in some cases.
+ * method. The asynchronous client performs non-blocking I/O when configured with any {@link SdkAsyncHttpClient}
+ * supported in the SDK. However, full non-blocking is not guaranteed as the async client may perform
+ * blocking calls in some cases such as credentials retreival and endpoint discovery as part of the async API call.
*
* A service that is implemented using the query protocol
*/
From 5c22f5cb156941bb142b92ab8e90ccc337acab49 Mon Sep 17 00:00:00 2001
From: Krishnan
Date: Thu, 14 Mar 2024 11:31:17 -0700
Subject: [PATCH 03/18] Updated warning message
---
.../awssdk/codegen/poet/client/AsyncClientInterface.java | 9 ++++++---
.../poet/client/test-json-async-client-interface.java | 6 +++---
2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientInterface.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientInterface.java
index 1dd583eb3353..c9f6b1fc6edd 100644
--- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientInterface.java
+++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientInterface.java
@@ -169,9 +169,12 @@ public ClassName className() {
private String getJavadoc() {
return "Service client for accessing " + model.getMetadata().getDescriptiveServiceName() + " asynchronously. This can be "
- + "created using the static {@link #builder()} method.\nWe strongly discourage "
- + "configuring main I/O threads to run future-completion objects. This could "
- + "lead to deadlock as the SDK may perform blocking calls in some cases."
+ + "created using the static {@link #builder()} method."
+ + "The asynchronous client performs non-blocking I/O when configured "
+ + "with any {@link SdkAsyncHttpClient} supported in the SDK. "
+ + "However, full non-blocking is not guaranteed as the async client may perform "
+ + "blocking calls in some cases such as credentials retrieval and "
+ + "endpoint discovery as part of the async API call."
+ "\n\n" + model.getMetadata().getDocumentation();
}
diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-interface.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-interface.java
index c8c8d794e53b..6508fa3bc790 100644
--- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-interface.java
+++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-json-async-client-interface.java
@@ -53,9 +53,9 @@
/**
* Service client for accessing Json Service asynchronously. This can be created using the static {@link #builder()}
- * method. The asynchronous client performs non-blocking I/O when configured with any {@link SdkAsyncHttpClient}
- * supported in the SDK. However, full non-blocking is not guaranteed as the async client may perform
- * blocking calls in some cases such as credentials retreival and endpoint discovery as part of the async API call.
+ * method.The asynchronous client performs non-blocking I/O when configured with any {@link SdkAsyncHttpClient}
+ * supported in the SDK. However, full non-blocking is not guaranteed as the async client may perform blocking calls in
+ * some cases such as credentials retrieval and endpoint discovery as part of the async API call.
*
* A service that is implemented using the query protocol
*/
From 10ae28e467e2bad22d76aa0a3592778b1e7abab8 Mon Sep 17 00:00:00 2001
From: Krishnan
Date: Mon, 25 Mar 2024 10:39:48 -0700
Subject: [PATCH 04/18] Added paragraph notation
---
.../amazon/awssdk/services/s3/S3CrtAsyncClientBuilder.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/services/s3/src/main/java/software/amazon/awssdk/services/s3/S3CrtAsyncClientBuilder.java b/services/s3/src/main/java/software/amazon/awssdk/services/s3/S3CrtAsyncClientBuilder.java
index 8005ccd909df..6a726506308b 100644
--- a/services/s3/src/main/java/software/amazon/awssdk/services/s3/S3CrtAsyncClientBuilder.java
+++ b/services/s3/src/main/java/software/amazon/awssdk/services/s3/S3CrtAsyncClientBuilder.java
@@ -323,12 +323,12 @@ default S3CrtAsyncClientBuilder retryConfiguration(ConsumerYou want to add instrumentation (i.e., metrics) around how the {@link Executor} is used.
*
- *
+ *
* WARNING
* We strongly discourage using {@code Runnable::run}, which executes the future-completion directly from
* within the I/O thread because it may block the I/O thread and cause deadlock, especially if you are sending
* another SDK request in the {@link CompletableFuture} chain since the SDK may perform blocking calls in some cases.
- *
+ *
* @param futureCompletionExecutor the executor
* @return an instance of this builder.
*/
From 5ab3decc82e903792f45fd071bb70a6e380f52c6 Mon Sep 17 00:00:00 2001
From: Krishnan
Date: Mon, 25 Mar 2024 10:49:02 -0700
Subject: [PATCH 05/18] Add a paragraph notation
---
.../amazon/awssdk/services/s3/S3CrtAsyncClientBuilder.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/services/s3/src/main/java/software/amazon/awssdk/services/s3/S3CrtAsyncClientBuilder.java b/services/s3/src/main/java/software/amazon/awssdk/services/s3/S3CrtAsyncClientBuilder.java
index 6a726506308b..cd5cf77554cb 100644
--- a/services/s3/src/main/java/software/amazon/awssdk/services/s3/S3CrtAsyncClientBuilder.java
+++ b/services/s3/src/main/java/software/amazon/awssdk/services/s3/S3CrtAsyncClientBuilder.java
@@ -328,7 +328,7 @@ default S3CrtAsyncClientBuilder retryConfiguration(Consumerdiscourage using {@code Runnable::run}, which executes the future-completion directly from
* within the I/O thread because it may block the I/O thread and cause deadlock, especially if you are sending
* another SDK request in the {@link CompletableFuture} chain since the SDK may perform blocking calls in some cases.
- *
+ *
* @param futureCompletionExecutor the executor
* @return an instance of this builder.
*/
From 512dee955e4de3026cbcc921078f2b0e76affd3e Mon Sep 17 00:00:00 2001
From: Krishnan
Date: Fri, 29 Mar 2024 10:00:09 -0700
Subject: [PATCH 06/18] Modify S3 expires field to not fail on parsing errors
and instead, log warnings. Also modified the Expires field to be a timestamp
---
.../unmarshall/XmlProtocolUnmarshaller.java | 12 +++-
.../codegen-resources/customization.config | 72 +++++++++++++++++++
2 files changed, 82 insertions(+), 2 deletions(-)
diff --git a/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/XmlProtocolUnmarshaller.java b/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/XmlProtocolUnmarshaller.java
index 56d950f917eb..a6a8e4cf3373 100644
--- a/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/XmlProtocolUnmarshaller.java
+++ b/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/XmlProtocolUnmarshaller.java
@@ -20,10 +20,13 @@
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.time.Instant;
+import java.time.format.DateTimeParseException;
import java.util.Collections;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.core.SdkField;
@@ -44,6 +47,7 @@
@SdkInternalApi
public final class XmlProtocolUnmarshaller implements XmlErrorUnmarshaller {
+ private static final Logger log = LoggerFactory.getLogger(XmlProtocolUnmarshaller.class);
public static final StringToValueConverter.StringToValue INSTANT_STRING_TO_VALUE
= StringToInstant.create(getDefaultTimestampFormats());
@@ -82,8 +86,12 @@ SdkPojo unmarshall(XmlUnmarshallerContext context, SdkPojo sdkPojo, XmlElement r
XmlUnmarshaller unmarshaller = REGISTRY.getUnmarshaller(field.location(), field.marshallingType());
if (field.location() != MarshallLocation.PAYLOAD) {
- Object unmarshalled = unmarshaller.unmarshall(context, null, (SdkField) field);
- field.set(sdkPojo, unmarshalled);
+ try {
+ Object unmarshalled = unmarshaller.unmarshall(context, null, (SdkField) field);
+ field.set(sdkPojo, unmarshalled);
+ } catch (DateTimeParseException e) {
+ log.warn("Invalid datetime format provided in the Expires field {}", e.getParsedString());
+ }
continue;
}
diff --git a/services/s3/src/main/resources/codegen-resources/customization.config b/services/s3/src/main/resources/codegen-resources/customization.config
index 0f06cc755691..fd808f4d3fed 100644
--- a/services/s3/src/main/resources/codegen-resources/customization.config
+++ b/services/s3/src/main/resources/codegen-resources/customization.config
@@ -27,6 +27,78 @@
}
]
},
+ "PutObjectRequest": {
+ "modify": [
+ {
+ "Expires": {
+ "emitAsType": "timestamp"
+ }
+ }
+ ]
+ },
+ "WriteGetObjectResponseRequest": {
+ "modify": [
+ {
+ "Expires": {
+ "emitAsType": "timestamp"
+ }
+ }
+ ]
+ },
+ "GetObjectOutput": {
+ "modify": [
+ {
+ "Expires": {
+ "emitAsType": "timestamp"
+ }
+ }
+ ]
+ },
+ "WriteGetObjectResponseRequest": {
+ "modify": [
+ {
+ "Expires": {
+ "emitAsType": "timestamp"
+ }
+ }
+ ]
+ },
+ "CopyObjectRequest": {
+ "modify": [
+ {
+ "Expires": {
+ "emitAsType": "timestamp"
+ }
+ }
+ ]
+ },
+ "HeadObjectOutput": {
+ "modify": [
+ {
+ "Expires": {
+ "emitAsType": "timestamp"
+ }
+ }
+ ]
+ },
+ "WriteGetObjectResponseRequest": {
+ "modify": [
+ {
+ "Expires": {
+ "emitAsType": "timestamp"
+ }
+ }
+ ]
+ },
+ "CreateMultipartUploadRequest": {
+ "modify": [
+ {
+ "Expires": {
+ "emitAsType": "timestamp"
+ }
+ }
+ ]
+ },
"UploadPartRequest": {
"inject": [
{
From 138afae36e596c8f22f8f98d1cd1da48addd9637 Mon Sep 17 00:00:00 2001
From: Krishnan
Date: Fri, 29 Mar 2024 13:57:22 -0700
Subject: [PATCH 07/18] Fix checkstyle issues
---
.../xml/internal/unmarshall/XmlProtocolUnmarshaller.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/XmlProtocolUnmarshaller.java b/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/XmlProtocolUnmarshaller.java
index a6a8e4cf3373..18f21c0efd96 100644
--- a/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/XmlProtocolUnmarshaller.java
+++ b/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/XmlProtocolUnmarshaller.java
@@ -47,11 +47,11 @@
@SdkInternalApi
public final class XmlProtocolUnmarshaller implements XmlErrorUnmarshaller {
- private static final Logger log = LoggerFactory.getLogger(XmlProtocolUnmarshaller.class);
public static final StringToValueConverter.StringToValue INSTANT_STRING_TO_VALUE
= StringToInstant.create(getDefaultTimestampFormats());
private static final XmlUnmarshallerRegistry REGISTRY = createUnmarshallerRegistry();
+ private static final Logger log = LoggerFactory.getLogger(XmlProtocolUnmarshaller.class);
private XmlProtocolUnmarshaller() {
}
From a5d94d523d29a4961fd6f37823f6f5f17512a3bc Mon Sep 17 00:00:00 2001
From: Krishnan
Date: Fri, 29 Mar 2024 14:36:49 -0700
Subject: [PATCH 08/18] Fixed duplicates in customization.config definition
---
.../codegen-resources/customization.config | 18 ------------------
1 file changed, 18 deletions(-)
diff --git a/services/s3/src/main/resources/codegen-resources/customization.config b/services/s3/src/main/resources/codegen-resources/customization.config
index fd808f4d3fed..a6785f69e9a2 100644
--- a/services/s3/src/main/resources/codegen-resources/customization.config
+++ b/services/s3/src/main/resources/codegen-resources/customization.config
@@ -54,15 +54,6 @@
}
]
},
- "WriteGetObjectResponseRequest": {
- "modify": [
- {
- "Expires": {
- "emitAsType": "timestamp"
- }
- }
- ]
- },
"CopyObjectRequest": {
"modify": [
{
@@ -81,15 +72,6 @@
}
]
},
- "WriteGetObjectResponseRequest": {
- "modify": [
- {
- "Expires": {
- "emitAsType": "timestamp"
- }
- }
- ]
- },
"CreateMultipartUploadRequest": {
"modify": [
{
From 9142048e9982f10f303fabd1a4d7ee72a784e373 Mon Sep 17 00:00:00 2001
From: Krishnan
Date: Sat, 30 Mar 2024 21:11:10 -0700
Subject: [PATCH 09/18] Remove duplicate definitions
---
.../codegen-resources/customization.config | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/services/s3/src/main/resources/codegen-resources/customization.config b/services/s3/src/main/resources/codegen-resources/customization.config
index a6785f69e9a2..20edfb26976e 100644
--- a/services/s3/src/main/resources/codegen-resources/customization.config
+++ b/services/s3/src/main/resources/codegen-resources/customization.config
@@ -54,15 +54,6 @@
}
]
},
- "CopyObjectRequest": {
- "modify": [
- {
- "Expires": {
- "emitAsType": "timestamp"
- }
- }
- ]
- },
"HeadObjectOutput": {
"modify": [
{
@@ -121,7 +112,11 @@
"Key": {
"emitPropertyName": "DestinationKey",
"existingNameDeprecated": true
+ },
+ "Expires": {
+ "emitAsType": "timestamp"
}
+
}
]
},
From a57a37849ea65ea58080ef0dde4604c91a9b26e9 Mon Sep 17 00:00:00 2001
From: Krishnan
Date: Thu, 25 Apr 2024 02:45:04 -0700
Subject: [PATCH 10/18] Facilitate custom handling of data type conversion
errors
---
.../processors/ShapeModifiersProcessor.java | 5 ++
.../ModifyModelShapeModifier.java | 13 +++++
.../model/intermediate/MemberModel.java | 10 ++++
.../codegen/poet/model/ShapeModelSpec.java | 11 ++++
.../unmarshall/HeaderUnmarshaller.java | 18 +++++-
.../unmarshall/XmlProtocolUnmarshaller.java | 12 +---
.../software/amazon/awssdk/core/SdkField.java | 11 ++++
.../metrics/BytesReadTrackingPublisher.java | 1 +
...ataTypeConversionFailureHandlingTrait.java | 22 ++++++++
.../codegen-resources/customization.config | 30 +++++++++-
.../services/s3/ExpiresHeaderParsingTest.java | 56 +++++++++++++++++++
11 files changed, 174 insertions(+), 15 deletions(-)
create mode 100644 core/sdk-core/src/main/java/software/amazon/awssdk/core/traits/DataTypeConversionFailureHandlingTrait.java
create mode 100644 services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderParsingTest.java
diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/ShapeModifiersProcessor.java b/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/ShapeModifiersProcessor.java
index d4e1b02d5639..a1b03a6b60d8 100644
--- a/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/ShapeModifiersProcessor.java
+++ b/codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/ShapeModifiersProcessor.java
@@ -160,6 +160,11 @@ private void postprocessModifyMemberProperty(ShapeModel shapeModel, String membe
.getUnmarshallLocationName());
}
+ if (modifyModel.isIgnoreDataTypeConversionFailures()) {
+ MemberModel memberModel = shapeModel.findMemberModelByC2jName(memberName);
+ memberModel.ignoreDataTypeConversionFailures(true);
+ }
+
}
/**
diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/ModifyModelShapeModifier.java b/codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/ModifyModelShapeModifier.java
index dffaf7d0d40b..468ec7154fa3 100644
--- a/codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/ModifyModelShapeModifier.java
+++ b/codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/ModifyModelShapeModifier.java
@@ -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;
}
@@ -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;
+ }
}
diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/model/intermediate/MemberModel.java b/codegen/src/main/java/software/amazon/awssdk/codegen/model/intermediate/MemberModel.java
index f6a870409ebd..fddf93d4d72d 100644
--- a/codegen/src/main/java/software/amazon/awssdk/codegen/model/intermediate/MemberModel.java
+++ b/codegen/src/main/java/software/amazon/awssdk/codegen/model/intermediate/MemberModel.java
@@ -115,6 +115,8 @@ public class MemberModel extends DocumentationModel {
private ContextParam contextParam;
+ private boolean ignoreDataTypeConversionFailures;
+
public String getName() {
return name;
}
@@ -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;
+ }
}
diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/ShapeModelSpec.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/ShapeModelSpec.java
index 8d79d83928ae..d10ab65a8a27 100644
--- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/ShapeModelSpec.java
+++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/ShapeModelSpec.java
@@ -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;
@@ -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());
}
@@ -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);
diff --git a/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/HeaderUnmarshaller.java b/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/HeaderUnmarshaller.java
index fe541ad104a8..811ec10b997b 100644
--- a/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/HeaderUnmarshaller.java
+++ b/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/HeaderUnmarshaller.java
@@ -22,6 +22,8 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.core.SdkField;
import software.amazon.awssdk.protocols.core.StringToValueConverter;
@@ -61,6 +63,8 @@ private HeaderUnmarshaller() {
private static class SimpleHeaderUnmarshaller implements XmlUnmarshaller {
+ private static final Logger log = LoggerFactory.getLogger(SimpleHeaderUnmarshaller.class);
+
private final StringToValueConverter.StringToValue stringToValue;
private SimpleHeaderUnmarshaller(StringToValueConverter.StringToValue stringToValue) {
@@ -69,9 +73,17 @@ private SimpleHeaderUnmarshaller(StringToValueConverter.StringToValue stringT
@Override
public T unmarshall(XmlUnmarshallerContext context, List content, SdkField 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.getMessage());
+ if(field.ignoreDataTypeConversionFailures()) {
+ return null;
+ }
+ throw e;
+ }
}
}
}
diff --git a/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/XmlProtocolUnmarshaller.java b/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/XmlProtocolUnmarshaller.java
index 18f21c0efd96..56d950f917eb 100644
--- a/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/XmlProtocolUnmarshaller.java
+++ b/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/XmlProtocolUnmarshaller.java
@@ -20,13 +20,10 @@
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.time.Instant;
-import java.time.format.DateTimeParseException;
import java.util.Collections;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.core.SdkField;
@@ -51,7 +48,6 @@ public final class XmlProtocolUnmarshaller implements XmlErrorUnmarshaller {
public static final StringToValueConverter.StringToValue INSTANT_STRING_TO_VALUE
= StringToInstant.create(getDefaultTimestampFormats());
private static final XmlUnmarshallerRegistry REGISTRY = createUnmarshallerRegistry();
- private static final Logger log = LoggerFactory.getLogger(XmlProtocolUnmarshaller.class);
private XmlProtocolUnmarshaller() {
}
@@ -86,12 +82,8 @@ SdkPojo unmarshall(XmlUnmarshallerContext context, SdkPojo sdkPojo, XmlElement r
XmlUnmarshaller unmarshaller = REGISTRY.getUnmarshaller(field.location(), field.marshallingType());
if (field.location() != MarshallLocation.PAYLOAD) {
- try {
- Object unmarshalled = unmarshaller.unmarshall(context, null, (SdkField) field);
- field.set(sdkPojo, unmarshalled);
- } catch (DateTimeParseException e) {
- log.warn("Invalid datetime format provided in the Expires field {}", e.getParsedString());
- }
+ Object unmarshalled = unmarshaller.unmarshall(context, null, (SdkField) field);
+ field.set(sdkPojo, unmarshalled);
continue;
}
diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/SdkField.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/SdkField.java
index 161754efa1f7..063ef85f2cd6 100644
--- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/SdkField.java
+++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/SdkField.java
@@ -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;
@@ -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.
diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/metrics/BytesReadTrackingPublisher.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/metrics/BytesReadTrackingPublisher.java
index dd8ef03b7312..6ee52d37ac6d 100644
--- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/metrics/BytesReadTrackingPublisher.java
+++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/metrics/BytesReadTrackingPublisher.java
@@ -55,6 +55,7 @@ private BytesReadTracker(Subscriber super ByteBuffer> downstream, AtomicLong b
@Override
public void onSubscribe(Subscription subscription) {
+ //resetBytesSent/Received
downstream.onSubscribe(subscription);
}
diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/traits/DataTypeConversionFailureHandlingTrait.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/traits/DataTypeConversionFailureHandlingTrait.java
new file mode 100644
index 000000000000..243ff2dac30b
--- /dev/null
+++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/traits/DataTypeConversionFailureHandlingTrait.java
@@ -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 {
+}
diff --git a/services/s3/src/main/resources/codegen-resources/customization.config b/services/s3/src/main/resources/codegen-resources/customization.config
index 20edfb26976e..0e573b1c8612 100644
--- a/services/s3/src/main/resources/codegen-resources/customization.config
+++ b/services/s3/src/main/resources/codegen-resources/customization.config
@@ -49,7 +49,20 @@
"modify": [
{
"Expires": {
- "emitAsType": "timestamp"
+ "emitAsType": "timestamp",
+ "deprecated": "true",
+ "deprecatedMessage": "Usage of the Expires field is deprecated in favor of the more flexible and less error prone ExpiresString",
+ "ignoreDataTypeConversionFailures": "true"
+ }
+ }
+ ],
+ "inject": [
+ {
+ "ExpiresString": {
+ "shape": "Expiration",
+ "documentation":"The date and time at which the object is no longer cacheable
",
+ "location":"header",
+ "locationName":"Expires"
}
}
]
@@ -58,7 +71,20 @@
"modify": [
{
"Expires": {
- "emitAsType": "timestamp"
+ "emitAsType": "timestamp",
+ "deprecated": "true",
+ "deprecatedMessage": "Usage of the Expires field is deprecated in favor of the more flexible and less error prone ExpiresString",
+ "ignoreDataTypeConversionFailures": "true"
+ }
+ }
+ ],
+ "inject": [
+ {
+ "ExpiresString": {
+ "shape": "Expiration",
+ "documentation":"The date and time at which the object is no longer cacheable
",
+ "location":"header",
+ "locationName":"Expires"
}
}
]
diff --git a/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderParsingTest.java b/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderParsingTest.java
new file mode 100644
index 000000000000..8693cf9ad4b1
--- /dev/null
+++ b/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderParsingTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.s3;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.IOException;
+import java.util.List;
+import org.apache.logging.log4j.core.LogEvent;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.Test;
+import software.amazon.awssdk.services.s3.model.HeadObjectRequest;
+import software.amazon.awssdk.testutils.LogCaptor;
+
+public class ExpiresHeaderParsingTest {
+
+ @Test
+ void test() throws IOException {
+
+ String bucketName = "anirudkr-bucket-2";
+ String key = "key1.txt";
+
+ //File file = new RandomTempFile(10_000);
+ S3Client client = S3Client.builder().build();
+
+ //PutObjectRequest put = PutObjectRequest.builder().bucket(bucketName).key(key).expires(Instant.now()).build();
+ //client.putObject(put, file.toPath());
+
+ LogCaptor logCaptor = LogCaptor.create();
+
+ HeadObjectRequest request = HeadObjectRequest.builder().bucket(bucketName).key(key).build();
+ Assertions.assertThatCode(() -> client.headObject(request))
+ .doesNotThrowAnyException();
+ assertTrue(client.headObject(request).expires() == null);
+ assertTrue(client.headObject(request).expiresString() != null);
+ //assertEquals(client.headObject(request).expires().toString(), client.headObject(request).expiresString());
+
+ List events = logCaptor.loggedEvents();
+ //assertLogged(events, Level.WARN, "Invalid datetime format provided in the Expires field 2034-01-01T00:00:00Z");
+ String expected = "Invalid datetime format provided in the Expires field 2034-01-01T00:00:00Z";
+ //assertTrue(events.stream().filter(s -> s.getMessage().getFormattedMessage().equals(expected)).collect(Collectors.toList()).isEmpty());
+ }
+}
From af0aa2df44f87db0223386367bf0348d681535d8 Mon Sep 17 00:00:00 2001
From: Krishnan
Date: Thu, 25 Apr 2024 02:48:47 -0700
Subject: [PATCH 11/18] Removed test class
---
.../services/s3/ExpiresHeaderParsingTest.java | 56 -------------------
1 file changed, 56 deletions(-)
delete mode 100644 services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderParsingTest.java
diff --git a/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderParsingTest.java b/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderParsingTest.java
deleted file mode 100644
index 8693cf9ad4b1..000000000000
--- a/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderParsingTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.s3;
-
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import java.io.IOException;
-import java.util.List;
-import org.apache.logging.log4j.core.LogEvent;
-import org.assertj.core.api.Assertions;
-import org.junit.jupiter.api.Test;
-import software.amazon.awssdk.services.s3.model.HeadObjectRequest;
-import software.amazon.awssdk.testutils.LogCaptor;
-
-public class ExpiresHeaderParsingTest {
-
- @Test
- void test() throws IOException {
-
- String bucketName = "anirudkr-bucket-2";
- String key = "key1.txt";
-
- //File file = new RandomTempFile(10_000);
- S3Client client = S3Client.builder().build();
-
- //PutObjectRequest put = PutObjectRequest.builder().bucket(bucketName).key(key).expires(Instant.now()).build();
- //client.putObject(put, file.toPath());
-
- LogCaptor logCaptor = LogCaptor.create();
-
- HeadObjectRequest request = HeadObjectRequest.builder().bucket(bucketName).key(key).build();
- Assertions.assertThatCode(() -> client.headObject(request))
- .doesNotThrowAnyException();
- assertTrue(client.headObject(request).expires() == null);
- assertTrue(client.headObject(request).expiresString() != null);
- //assertEquals(client.headObject(request).expires().toString(), client.headObject(request).expiresString());
-
- List events = logCaptor.loggedEvents();
- //assertLogged(events, Level.WARN, "Invalid datetime format provided in the Expires field 2034-01-01T00:00:00Z");
- String expected = "Invalid datetime format provided in the Expires field 2034-01-01T00:00:00Z";
- //assertTrue(events.stream().filter(s -> s.getMessage().getFormattedMessage().equals(expected)).collect(Collectors.toList()).isEmpty());
- }
-}
From 4dc79bfb18d33f2e9cdaf017f88b65805224cc61 Mon Sep 17 00:00:00 2001
From: Krishnan
Date: Thu, 25 Apr 2024 02:51:13 -0700
Subject: [PATCH 12/18] Remove incorrectly added statements
---
.../awssdk/core/internal/metrics/BytesReadTrackingPublisher.java | 1 -
1 file changed, 1 deletion(-)
diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/metrics/BytesReadTrackingPublisher.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/metrics/BytesReadTrackingPublisher.java
index 6ee52d37ac6d..dd8ef03b7312 100644
--- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/metrics/BytesReadTrackingPublisher.java
+++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/metrics/BytesReadTrackingPublisher.java
@@ -55,7 +55,6 @@ private BytesReadTracker(Subscriber super ByteBuffer> downstream, AtomicLong b
@Override
public void onSubscribe(Subscription subscription) {
- //resetBytesSent/Received
downstream.onSubscribe(subscription);
}
From a6824f3c72472c84ad055e95337cb7f726168991 Mon Sep 17 00:00:00 2001
From: Krishnan
Date: Mon, 29 Apr 2024 04:02:12 -0700
Subject: [PATCH 13/18] Added Unit tests
---
.../codegen/poet/model/customization.config | 5 +
.../operationwithdeprecatedmemberrequest.java | 59 +++++++++++-
.../awssdk/codegen/poet/model/service-2.json | 3 +-
.../unmarshall/HeaderUnmarshaller.java | 13 ++-
.../s3/ExpiresHeaderDataTypeErrorTest.java | 96 +++++++++++++++++++
5 files changed, 165 insertions(+), 11 deletions(-)
create mode 100644 services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderDataTypeErrorTest.java
diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/customization.config b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/customization.config
index 213183ce5a87..0375c733e912 100644
--- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/customization.config
+++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/customization.config
@@ -26,6 +26,11 @@
"deprecated": true,
"deprecatedMessage": "This field is modified as deprecated."
}
+ },
+ {
+ "MemberIgnoreDataTypeFailureHandling": {
+ "ignoreDataTypeConversionFailures": "true"
+ }
}
]
},
diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/operationwithdeprecatedmemberrequest.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/operationwithdeprecatedmemberrequest.java
index 05cf3b39317c..c14ae6ee3ede 100644
--- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/operationwithdeprecatedmemberrequest.java
+++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/operationwithdeprecatedmemberrequest.java
@@ -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;
@@ -45,8 +46,18 @@ public final class OperationWithDeprecatedMemberRequest extends JsonProtocolTest
.traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("UndeprecatedMember").build())
.build();
+ private static final SdkField MEMBER_IGNORE_DATA_TYPE_FAILURE_HANDLING_FIELD = SdkField
+ . 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> 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;
@@ -54,11 +65,14 @@ public final class OperationWithDeprecatedMemberRequest extends JsonProtocolTest
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;
}
/**
@@ -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);
@@ -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;
}
@@ -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());
}
/**
@@ -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 Optional getValueForField(String fieldName, Class clazz) {
@@ -157,6 +182,8 @@ public final Optional getValueForField(String fieldName, Class 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();
}
@@ -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);
@@ -222,6 +258,8 @@ static final class BuilderImpl extends JsonProtocolTestsRequest.BuilderImpl impl
private String undeprecatedMember;
+ private String memberIgnoreDataTypeFailureHandling;
+
private BuilderImpl() {
}
@@ -230,6 +268,7 @@ private BuilderImpl(OperationWithDeprecatedMemberRequest model) {
memberModeledAsDeprecated(model.memberModeledAsDeprecated);
memberModifiedAsDeprecated(model.memberModifiedAsDeprecated);
undeprecatedMember(model.undeprecatedMember);
+ memberIgnoreDataTypeFailureHandling(model.memberIgnoreDataTypeFailureHandling);
}
@Deprecated
@@ -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);
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 fb3e0a548d9e..e846f69f04ed 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
@@ -247,7 +247,8 @@
"deprecatedMessage": "This field is modeled as deprecated."
},
"MemberModifiedAsDeprecated":{"shape": "String"},
- "UndeprecatedMember": {"shape": "String"}
+ "UndeprecatedMember": {"shape": "String"},
+ "MemberIgnoreDataTypeFailureHandling":{"shape": "String"}
}
},
"OperationWithDeprecatedMemberResponse":{
diff --git a/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/HeaderUnmarshaller.java b/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/HeaderUnmarshaller.java
index 811ec10b997b..edea73b82a4e 100644
--- a/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/HeaderUnmarshaller.java
+++ b/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/HeaderUnmarshaller.java
@@ -22,12 +22,11 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import software.amazon.awssdk.annotations.SdkInternalApi;
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 {
@@ -61,13 +60,13 @@ public final class HeaderUnmarshaller {
private HeaderUnmarshaller() {
}
- private static class SimpleHeaderUnmarshaller implements XmlUnmarshaller {
+ private static class SimpleHeaderUnmarshaller implements XmlUnmarshaller {
- private static final Logger log = LoggerFactory.getLogger(SimpleHeaderUnmarshaller.class);
+ private static final Logger log = Logger.loggerFor(SimpleHeaderUnmarshaller.class);
private final StringToValueConverter.StringToValue stringToValue;
- private SimpleHeaderUnmarshaller(StringToValueConverter.StringToValue stringToValue) {
+ private SimpleHeaderUnmarshaller(StringToValueConverter.StringToValue stringToValue) {
this.stringToValue = stringToValue;
}
@@ -78,8 +77,8 @@ public T unmarshall(XmlUnmarshallerContext context, List content, Sd
.map(s -> stringToValue.convert(s, field))
.orElse(null);
} catch (RuntimeException e) {
- log.warn("Exception found while parsing response header {}", e.getMessage());
- if(field.ignoreDataTypeConversionFailures()) {
+ log.warn(() -> (String.format("Exception found while parsing response header {}", e.getMessage())));
+ if (field.ignoreDataTypeConversionFailures()) {
return null;
}
throw e;
diff --git a/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderDataTypeErrorTest.java b/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderDataTypeErrorTest.java
new file mode 100644
index 000000000000..e1c85aafdab7
--- /dev/null
+++ b/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderDataTypeErrorTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.s3;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.any;
+import static com.github.tomakehurst.wiremock.client.WireMock.anyUrl;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import com.github.tomakehurst.wiremock.junit.WireMockRule;
+import java.io.IOException;
+import java.net.URI;
+import java.util.List;
+import org.apache.logging.log4j.core.LogEvent;
+import org.assertj.core.api.Assertions;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import software.amazon.awssdk.auth.credentials.AnonymousCredentialsProvider;
+import software.amazon.awssdk.testutils.LogCaptor;
+
+public class ExpiresHeaderDataTypeErrorTest {
+
+ @Rule
+ public WireMockRule wireMock = new WireMockRule();
+
+ private S3Client s3Client;
+
+ private final String TEST_DATE = "2034-02-01T00:00:00Z";
+ @Before
+ public void setup() {
+ s3Client = S3Client.builder().endpointOverride(URI.create("http://localhost:" + wireMock.port()))
+ .credentialsProvider(AnonymousCredentialsProvider.create())
+ .build();
+ }
+
+ @Test
+ public void headObjectRequestWithInvalidDate_doesNotThrowException() throws IOException {
+
+ stubFor(any(anyUrl())
+ .willReturn(aResponse()
+ .withHeader("Expires", TEST_DATE)
+ .withBody("Hello world!")));
+
+ Assertions.assertThatCode(() -> s3Client.headObject(r -> {
+ r.bucket("s3_expires_test_dummy_bucket")
+ .key("s3_expires_test_dummy_key");
+ }))
+ .doesNotThrowAnyException();
+
+ assertTrue(s3Client.headObject(r -> {r.bucket("s3_expires_test_dummy_bucket")
+ .key("s3_expires_test_dummy_key");}).expires() == null);
+
+ assertEquals(s3Client.headObject(r -> {r.bucket("s3_expires_test_dummy_bucket")
+ .key("s3_expires_test_dummy_key");}).expiresString(), TEST_DATE);
+
+ }
+
+ @Test
+ public void getObjectRequestWithInvalidDate_doesNotThrowException() throws IOException {
+
+ stubFor(any(anyUrl())
+ .willReturn(aResponse()
+ .withHeader("Expires", TEST_DATE)
+ .withBody("Hello world!")));
+
+ Assertions.assertThatCode(() -> s3Client.headObject(r -> {
+ r.bucket("s3_expires_test_dummy_bucket")
+ .key("s3_expires_test_dummy_key");
+ }))
+ .doesNotThrowAnyException();
+
+ assertTrue(s3Client.getObject(r -> {r.bucket("s3_expires_test_dummy_bucket")
+ .key("s3_expires_test_dummy_key");}).response().expires() == null);
+
+ assertEquals(s3Client.getObject(r -> {r.bucket("s3_expires_test_dummy_bucket")
+ .key("s3_expires_test_dummy_key");}).response().expiresString(), TEST_DATE);
+
+ }
+}
From fb9d2998946d77d8886cde6aa94d76dab0bca5f1 Mon Sep 17 00:00:00 2001
From: Krishnan
Date: Mon, 29 Apr 2024 09:29:08 -0700
Subject: [PATCH 14/18] Changed to Junit5
---
.../s3/ExpiresHeaderDataTypeErrorTest.java | 31 ++++++++-----------
1 file changed, 13 insertions(+), 18 deletions(-)
diff --git a/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderDataTypeErrorTest.java b/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderDataTypeErrorTest.java
index e1c85aafdab7..4bd9e8e0f312 100644
--- a/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderDataTypeErrorTest.java
+++ b/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderDataTypeErrorTest.java
@@ -19,45 +19,38 @@
import static com.github.tomakehurst.wiremock.client.WireMock.any;
import static com.github.tomakehurst.wiremock.client.WireMock.anyUrl;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
-import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import com.github.tomakehurst.wiremock.junit.WireMockRule;
+import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
+import com.github.tomakehurst.wiremock.junit5.WireMockTest;
import java.io.IOException;
import java.net.URI;
-import java.util.List;
-import org.apache.logging.log4j.core.LogEvent;
import org.assertj.core.api.Assertions;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import software.amazon.awssdk.auth.credentials.AnonymousCredentialsProvider;
-import software.amazon.awssdk.testutils.LogCaptor;
+@WireMockTest
public class ExpiresHeaderDataTypeErrorTest {
- @Rule
- public WireMockRule wireMock = new WireMockRule();
-
- private S3Client s3Client;
-
private final String TEST_DATE = "2034-02-01T00:00:00Z";
- @Before
- public void setup() {
- s3Client = S3Client.builder().endpointOverride(URI.create("http://localhost:" + wireMock.port()))
+
+ public S3Client getS3Client(WireMockRuntimeInfo wm) {
+ return S3Client.builder().endpointOverride(URI.create(wm.getHttpBaseUrl()))
.credentialsProvider(AnonymousCredentialsProvider.create())
.build();
}
@Test
- public void headObjectRequestWithInvalidDate_doesNotThrowException() throws IOException {
+ public void headObjectRequestWithInvalidDate_doesNotThrowException(WireMockRuntimeInfo wm) throws IOException {
stubFor(any(anyUrl())
.willReturn(aResponse()
.withHeader("Expires", TEST_DATE)
.withBody("Hello world!")));
+ S3Client s3Client = getS3Client(wm);
+
Assertions.assertThatCode(() -> s3Client.headObject(r -> {
r.bucket("s3_expires_test_dummy_bucket")
.key("s3_expires_test_dummy_key");
@@ -73,13 +66,15 @@ public void headObjectRequestWithInvalidDate_doesNotThrowException() throws IOEx
}
@Test
- public void getObjectRequestWithInvalidDate_doesNotThrowException() throws IOException {
+ public void getObjectRequestWithInvalidDate_doesNotThrowException(WireMockRuntimeInfo wm) throws IOException {
stubFor(any(anyUrl())
.willReturn(aResponse()
.withHeader("Expires", TEST_DATE)
.withBody("Hello world!")));
+ S3Client s3Client = getS3Client(wm);
+
Assertions.assertThatCode(() -> s3Client.headObject(r -> {
r.bucket("s3_expires_test_dummy_bucket")
.key("s3_expires_test_dummy_key");
From e2e52e132f29ddd9fecfb7115215577f87af9ca4 Mon Sep 17 00:00:00 2001
From: Krishnan
Date: Mon, 29 Apr 2024 10:06:15 -0700
Subject: [PATCH 15/18] Fixed checkstyle issues
---
.../xml/internal/unmarshall/HeaderUnmarshaller.java | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/HeaderUnmarshaller.java b/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/HeaderUnmarshaller.java
index edea73b82a4e..9e7259cfdd64 100644
--- a/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/HeaderUnmarshaller.java
+++ b/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/HeaderUnmarshaller.java
@@ -60,13 +60,12 @@ public final class HeaderUnmarshaller {
private HeaderUnmarshaller() {
}
- private static class SimpleHeaderUnmarshaller implements XmlUnmarshaller {
-
+ private static class SimpleHeaderUnmarshaller implements XmlUnmarshaller {
private static final Logger log = Logger.loggerFor(SimpleHeaderUnmarshaller.class);
private final StringToValueConverter.StringToValue stringToValue;
- private SimpleHeaderUnmarshaller(StringToValueConverter.StringToValue stringToValue) {
+ private SimpleHeaderUnmarshaller(StringToValueConverter.StringToValue stringToValue) {
this.stringToValue = stringToValue;
}
From db0952d51854cacba91eb9f265b93147512022d7 Mon Sep 17 00:00:00 2001
From: Krishnan
Date: Mon, 29 Apr 2024 11:11:20 -0700
Subject: [PATCH 16/18] Added wiremock
---
.../s3/ExpiresHeaderDataTypeErrorTest.java | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderDataTypeErrorTest.java b/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderDataTypeErrorTest.java
index 4bd9e8e0f312..508b34b0737a 100644
--- a/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderDataTypeErrorTest.java
+++ b/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderDataTypeErrorTest.java
@@ -27,30 +27,32 @@
import java.io.IOException;
import java.net.URI;
import org.assertj.core.api.Assertions;
+import org.junit.Before;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import software.amazon.awssdk.auth.credentials.AnonymousCredentialsProvider;
@WireMockTest
public class ExpiresHeaderDataTypeErrorTest {
+ S3Client s3Client;
private final String TEST_DATE = "2034-02-01T00:00:00Z";
- public S3Client getS3Client(WireMockRuntimeInfo wm) {
- return S3Client.builder().endpointOverride(URI.create(wm.getHttpBaseUrl()))
- .credentialsProvider(AnonymousCredentialsProvider.create())
- .build();
+ @BeforeEach
+ public void initWireMock(WireMockRuntimeInfo wm) {
+ s3Client = S3Client.builder().endpointOverride(URI.create(wm.getHttpBaseUrl()))
+ .credentialsProvider(AnonymousCredentialsProvider.create())
+ .build();
}
@Test
- public void headObjectRequestWithInvalidDate_doesNotThrowException(WireMockRuntimeInfo wm) throws IOException {
+ public void headObjectRequestWithInvalidDate_doesNotThrowException() throws IOException {
stubFor(any(anyUrl())
.willReturn(aResponse()
.withHeader("Expires", TEST_DATE)
.withBody("Hello world!")));
- S3Client s3Client = getS3Client(wm);
-
Assertions.assertThatCode(() -> s3Client.headObject(r -> {
r.bucket("s3_expires_test_dummy_bucket")
.key("s3_expires_test_dummy_key");
@@ -66,15 +68,13 @@ public void headObjectRequestWithInvalidDate_doesNotThrowException(WireMockRunti
}
@Test
- public void getObjectRequestWithInvalidDate_doesNotThrowException(WireMockRuntimeInfo wm) throws IOException {
+ public void getObjectRequestWithInvalidDate_doesNotThrowException() throws IOException {
stubFor(any(anyUrl())
.willReturn(aResponse()
.withHeader("Expires", TEST_DATE)
.withBody("Hello world!")));
- S3Client s3Client = getS3Client(wm);
-
Assertions.assertThatCode(() -> s3Client.headObject(r -> {
r.bucket("s3_expires_test_dummy_bucket")
.key("s3_expires_test_dummy_key");
From b032c93a91d4565906dac980236b75108b8aa25b Mon Sep 17 00:00:00 2001
From: Krishnan
Date: Mon, 29 Apr 2024 11:57:10 -0700
Subject: [PATCH 17/18] assertThat instead of assertTrue and logged the entire
exception stack
---
.../unmarshall/HeaderUnmarshaller.java | 2 +-
.../s3/ExpiresHeaderDataTypeErrorTest.java | 23 +++++++++----------
2 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/HeaderUnmarshaller.java b/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/HeaderUnmarshaller.java
index 9e7259cfdd64..c160d3c6bb35 100644
--- a/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/HeaderUnmarshaller.java
+++ b/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/HeaderUnmarshaller.java
@@ -76,7 +76,7 @@ public T unmarshall(XmlUnmarshallerContext context, List content, Sd
.map(s -> stringToValue.convert(s, field))
.orElse(null);
} catch (RuntimeException e) {
- log.warn(() -> (String.format("Exception found while parsing response header {}", e.getMessage())));
+ log.warn(() -> (String.format("Exception found while parsing response header {} ", e)));
if (field.ignoreDataTypeConversionFailures()) {
return null;
}
diff --git a/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderDataTypeErrorTest.java b/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderDataTypeErrorTest.java
index 508b34b0737a..457d0388a48c 100644
--- a/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderDataTypeErrorTest.java
+++ b/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExpiresHeaderDataTypeErrorTest.java
@@ -19,15 +19,14 @@
import static com.github.tomakehurst.wiremock.client.WireMock.any;
import static com.github.tomakehurst.wiremock.client.WireMock.anyUrl;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode;
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
import com.github.tomakehurst.wiremock.junit5.WireMockTest;
import java.io.IOException;
import java.net.URI;
import org.assertj.core.api.Assertions;
-import org.junit.Before;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import software.amazon.awssdk.auth.credentials.AnonymousCredentialsProvider;
@@ -53,17 +52,17 @@ public void headObjectRequestWithInvalidDate_doesNotThrowException() throws IOEx
.withHeader("Expires", TEST_DATE)
.withBody("Hello world!")));
- Assertions.assertThatCode(() -> s3Client.headObject(r -> {
+ assertThatCode(() -> s3Client.headObject(r -> {
r.bucket("s3_expires_test_dummy_bucket")
.key("s3_expires_test_dummy_key");
}))
.doesNotThrowAnyException();
- assertTrue(s3Client.headObject(r -> {r.bucket("s3_expires_test_dummy_bucket")
- .key("s3_expires_test_dummy_key");}).expires() == null);
+ assertThat(s3Client.headObject(r -> {r.bucket("s3_expires_test_dummy_bucket")
+ .key("s3_expires_test_dummy_key");}).expires()).isNull();
- assertEquals(s3Client.headObject(r -> {r.bucket("s3_expires_test_dummy_bucket")
- .key("s3_expires_test_dummy_key");}).expiresString(), TEST_DATE);
+ assertThat(s3Client.headObject(r -> {r.bucket("s3_expires_test_dummy_bucket")
+ .key("s3_expires_test_dummy_key");}).expiresString()).isEqualTo(TEST_DATE);
}
@@ -81,11 +80,11 @@ public void getObjectRequestWithInvalidDate_doesNotThrowException() throws IOExc
}))
.doesNotThrowAnyException();
- assertTrue(s3Client.getObject(r -> {r.bucket("s3_expires_test_dummy_bucket")
- .key("s3_expires_test_dummy_key");}).response().expires() == null);
+ assertThat(s3Client.getObject(r -> {r.bucket("s3_expires_test_dummy_bucket")
+ .key("s3_expires_test_dummy_key");}).response().expires()).isNull();
- assertEquals(s3Client.getObject(r -> {r.bucket("s3_expires_test_dummy_bucket")
- .key("s3_expires_test_dummy_key");}).response().expiresString(), TEST_DATE);
+ assertThat(s3Client.getObject(r -> {r.bucket("s3_expires_test_dummy_bucket")
+ .key("s3_expires_test_dummy_key");}).response().expiresString()).isEqualTo(TEST_DATE);
}
}
From b0c759aeb4dd58b5aede4744dbac1b9da80cad7f Mon Sep 17 00:00:00 2001
From: Krishnan
Date: Mon, 29 Apr 2024 12:21:09 -0700
Subject: [PATCH 18/18] modified error message
---
.../protocols/xml/internal/unmarshall/HeaderUnmarshaller.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/HeaderUnmarshaller.java b/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/HeaderUnmarshaller.java
index c160d3c6bb35..4f1121da3dcc 100644
--- a/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/HeaderUnmarshaller.java
+++ b/core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/HeaderUnmarshaller.java
@@ -76,7 +76,7 @@ public T unmarshall(XmlUnmarshallerContext context, List content, Sd
.map(s -> stringToValue.convert(s, field))
.orElse(null);
} catch (RuntimeException e) {
- log.warn(() -> (String.format("Exception found while parsing response header {} ", e)));
+ log.warn(() -> "Exception found while parsing response header " , e);
if (field.ignoreDataTypeConversionFailures()) {
return null;
}