Repository: getmoto/moto

Issue:
moto_server returning unparsable dates to v2 Java SDK
## Unable to unmarshall response (Text '2020-09-10T21:41:37.256457+00:00' could not be parsed at index 19)

It looks like the v2 AWS SDK is unable to parse the datetime strings being returned by moto_server. The full exception message is 

Unable to unmarshall response (Text '2020-09-10T21:41:37.256457+00:00' could not be parsed at index 19). Response Code: 200, Response Text: OK (Java::SoftwareAmazonAwssdkCoreException::SdkClientException)

This is being called from JRuby, so the stacktrace is going to look a bit odd:

software.amazon.awssdk.core.exception.SdkClientException$BuilderImpl.build(software/amazon/awssdk/core/exception/SdkClientException.java:98)
software.amazon.awssdk.protocols.xml.internal.unmarshall.AwsXmlPredicatedResponseHandler.handleSuccessResponse(software/amazon/awssdk/protocols/xml/internal/unmarshall/AwsXmlPredicatedResponseHandler.java:145)
software.amazon.awssdk.protocols.xml.internal.unmarshall.AwsXmlPredicatedResponseHandler.handleResponse(software/amazon/awssdk/protocols/xml/internal/unmarshall/AwsXmlPredicatedResponseHandler.java:99)
software.amazon.awssdk.protocols.xml.internal.unmarshall.AwsXmlPredicatedResponseHandler.handle(software/amazon/awssdk/protocols/xml/internal/unmarshall/AwsXmlPredicatedResponseHandler.java:84)
software.amazon.awssdk.protocols.xml.internal.unmarshall.AwsXmlPredicatedResponseHandler.handle(software/amazon/awssdk/protocols/xml/internal/unmarshall/AwsXmlPredicatedResponseHandler.java:42)
software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler$Crc32ValidationResponseHandler.handle(software/amazon/awssdk/awscore/client/handler/AwsSyncClientHandler.java:94)
software.amazon.awssdk.core.internal.handler.BaseClientHandler.lambda$successTransformationResponseHandler$5(software/amazon/awssdk/core/internal/handler/BaseClientHandler.java:229)
software.amazon.awssdk.core.internal.http.pipeline.stages.HandleResponseStage.execute(software/amazon/awssdk/core/internal/http/pipeline/stages/HandleResponseStage.java:40)
software.amazon.awssdk.core.internal.http.pipeline.stages.HandleResponseStage.execute(software/amazon/awssdk/core/internal/http/pipeline/stages/HandleResponseStage.java:30)
software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(software/amazon/awssdk/core/internal/http/pipeline/RequestPipelineBuilder.java:206)
software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallAttemptTimeoutTrackingStage.execute(software/amazon/awssdk/core/internal/http/pipeline/stages/ApiCallAttemptTimeoutTrackingStage.java:73)
software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallAttemptTimeoutTrackingStage.execute(software/amazon/awssdk/core/internal/http/pipeline/stages/ApiCallAttemptTimeoutTrackingStage.java:42)
software.amazon.awssdk.core.internal.http.pipeline.stages.TimeoutExceptionHandlingStage.execute(software/amazon/awssdk/core/internal/http/pipeline/stages/TimeoutExceptionHandlingStage.java:77)
software.amazon.awssdk.core.internal.http.pipeline.stages.TimeoutExceptionHandlingStage.execute(software/amazon/awssdk/core/internal/http/pipeline/stages/TimeoutExceptionHandlingStage.java:39)
software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallAttemptMetricCollectionStage.execute(software/amazon/awssdk/core/internal/http/pipeline/stages/ApiCallAttemptMetricCollectionStage.java:50)
software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallAttemptMetricCollectionStage.execute(software/amazon/awssdk/core/internal/http/pipeline/stages/ApiCallAttemptMetricCollectionStage.java:36)
software.amazon.awssdk.core.internal.http.pipeline.stages.RetryableStage.execute(software/amazon/awssdk/core/internal/http/pipeline/stages/RetryableStage.java:64)
software.amazon.awssdk.core.internal.http.pipeline.stages.RetryableStage.execute(software/amazon/awssdk/core/internal/http/pipeline/stages/RetryableStage.java:34)
software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(software/amazon/awssdk/core/internal/http/pipeline/RequestPipelineBuilder.java:206)
software.amazon.awssdk.core.internal.http.StreamManagingStage.execute(software/amazon/awssdk/core/internal/http/StreamManagingStage.java:56)
software.amazon.awssdk.core.internal.http.StreamManagingStage.execute(software/amazon/awssdk/core/internal/http/StreamManagingStage.java:36)
software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallTimeoutTrackingStage.executeWithTimer(software/amazon/awssdk/core/internal/http/pipeline/stages/ApiCallTimeoutTrackingStage.java:80)
software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallTimeoutTrackingStage.execute(software/amazon/awssdk/core/internal/http/pipeline/stages/ApiCallTimeoutTrackingStage.java:60)
software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallTimeoutTrackingStage.execute(software/amazon/awssdk/core/internal/http/pipeline/stages/ApiCallTimeoutTrackingStage.java:42)
software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallMetricCollectionStage.execute(software/amazon/awssdk/core/internal/http/pipeline/stages/ApiCallMetricCollectionStage.java:48)
software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallMetricCollectionStage.execute(software/amazon/awssdk/core/internal/http/pipeline/stages/ApiCallMetricCollectionStage.java:31)
software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(software/amazon/awssdk/core/internal/http/pipeline/RequestPipelineBuilder.java:206)
software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(software/amazon/awssdk/core/internal/http/pipeline/RequestPipelineBuilder.java:206)
software.amazon.awssdk.core.internal.http.pipeline.stages.ExecutionFailureExceptionReportingStage.execute(software/amazon/awssdk/core/internal/http/pipeline/stages/ExecutionFailureExceptionReportingStage.java:37)
software.amazon.awssdk.core.internal.http.pipeline.stages.ExecutionFailureExceptionReportingStage.execute(software/amazon/awssdk/core/internal/http/pipeline/stages/ExecutionFailureExceptionReportingStage.java:26)
software.amazon.awssdk.core.internal.http.AmazonSyncHttpClient$RequestExecutionBuilderImpl.execute(software/amazon/awssdk/core/internal/http/AmazonSyncHttpClient.java:193)
software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.invoke(software/amazon/awssdk/core/internal/handler/BaseSyncClientHandler.java:128)
software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.doExecute(software/amazon/awssdk/core/internal/handler/BaseSyncClientHandler.java:154)
software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.lambda$execute$1(software/amazon/awssdk/core/internal/handler/BaseSyncClientHandler.java:107)
software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.measureApiCallSuccess(software/amazon/awssdk/core/internal/handler/BaseSyncClientHandler.java:162)
software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.execute(software/amazon/awssdk/core/internal/handler/BaseSyncClientHandler.java:91)
software.amazon.awssdk.core.client.handler.SdkSyncClientHandler.execute(software/amazon/awssdk/core/client/handler/SdkSyncClientHandler.java:45)
software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.execute(software/amazon/awssdk/awscore/client/handler/AwsSyncClientHandler.java:55)
software.amazon.awssdk.services.s3.DefaultS3Client.listBuckets(software/amazon/awssdk/services/s3/DefaultS3Client.java:4940)
software.amazon.awssdk.services.s3.S3Client.listBuckets(software/amazon/awssdk/services/s3/S3Client.java:9406)
java.lang.reflect.Method.invoke(java/lang/reflect/Method.java:498)
org.jruby.javasupport.JavaMethod.invokeDirectWithExceptionHandling(org/jruby/javasupport/JavaMethod.java:438)
org.jruby.javasupport.JavaMethod.invokeDirect(org/jruby/javasupport/JavaMethod.java:302)
RUBY.store(/Users/rwygand/source/majority_report_topologies/scripts/functional_tests/s3_helper.rb:31)
RUBY.build_telemetry_from_metron_file(/Users/rwygand/source/majority_report_topologies/scripts/functional_tests/telemetry_builder.rb:118)
RUBY.build(/Users/rwygand/source/majority_report_topologies/scripts/functional_tests/telemetry_builder.rb:37)
RUBY.run(/Users/rwygand/source/majority_report_topologies/scripts/functional_tests/functional_test_case.rb:36)
RUBY.block in run_test_case(/Users/rwygand/source/majority_report_topologies/scripts/functional_tests/functional_test_harness.rb:108)
org.jruby.RubyEnumerable$EachWithIndex.call(org/jruby/RubyEnumerable.java:1003)
org.jruby.RubyArray.each(org/jruby/RubyArray.java:1735)
org.jruby.RubyArray$INVOKER$i$0$0$each.call(org/jruby/RubyArray$INVOKER$i$0$0$each.gen)
org.jruby.RubyClass.finvoke(org/jruby/RubyClass.java:523)
org.jruby.RubyEnumerable.callEach(org/jruby/RubyEnumerable.java:140)
org.jruby.RubyEnumerable.each_with_indexCommon(org/jruby/RubyEnumerable.java:1037)
org.jruby.RubyEnumerable.each_with_index(org/jruby/RubyEnumerable.java:1067)
org.jruby.RubyEnumerable$INVOKER$s$0$0$each_with_index.call(org/jruby/RubyEnumerable$INVOKER$s$0$0$each_with_index.gen)
RUBY.run_test_case(/Users/rwygand/source/majority_report_topologies/scripts/functional_tests/functional_test_harness.rb:95)
RUBY.block in run_test_cases(/Users/rwygand/source/majority_report_topologies/scripts/functional_tests/functional_test_harness.rb:75)
org.jruby.RubyArray.each(org/jruby/RubyArray.java:1735)
org.jruby.RubyArray$INVOKER$i$0$0$each.call(org/jruby/RubyArray$INVOKER$i$0$0$each.gen)
RUBY.run_test_cases(/Users/rwygand/source/majority_report_topologies/scripts/functional_tests/functional_test_harness.rb:71)
RUBY.start(/Users/rwygand/source/majority_report_topologies/scripts/functional_tests/functional_test_harness.rb:60)
$_dot_.scripts.functional_tests.main.invokeOther123:start($_dot_/scripts/functional_tests/./scripts/functional_tests/main.rb:88)
$_dot_.scripts.functional_tests.main.<main>(./scripts/functional_tests/main.rb:88)
java.lang.invoke.MethodHandle.invokeWithArguments(java/lang/invoke/MethodHandle.java:627)
org.jruby.Ruby.runScript(org/jruby/Ruby.java:830)
org.jruby.Ruby.runNormally(org/jruby/Ruby.java:749)
org.jruby.Ruby.runNormally(org/jruby/Ruby.java:767)
org.jruby.Ruby.runFromMain(org/jruby/Ruby.java:580)
org.jruby.Main.doRunFromMain(org/jruby/Main.java:417)
org.jruby.Main.internalRun(org/jruby/Main.java:305)
org.jruby.Main.run(org/jruby/Main.java:232)
org.jruby.Main.main(org/jruby/Main.java:204)

The output of moto_server:
127.0.0.1 - - [10/Sep/2020 14:41:37] "GET / HTTP/1.1" 200 -


I'm running a standalone moto_server with the following version: moto-1.3.16.
I'm using the AWS SDK for Java v2
I'm just calling S3Client.listBuckets() and the SDK is unable to parse the response, per above.




Discussion:
This bug against the Java SDK v2 illustrates the issue, as well: https://github.com/aws/aws-sdk-java-v2/issues/981
Thanks for raising this @rwygand - marking this as a bug

Resolving patch:
diff --git a/moto/s3/models.py b/moto/s3/models.py
--- a/moto/s3/models.py
+++ b/moto/s3/models.py
@@ -788,6 +788,10 @@ def __init__(self, name, region_name):
     def location(self):
         return self.region_name
 
+    @property
+    def creation_date_ISO8601(self):
+        return iso_8601_datetime_without_milliseconds_s3(self.creation_date)
+
     @property
     def is_versioned(self):
         return self.versioning_status == "Enabled"
diff --git a/moto/s3/responses.py b/moto/s3/responses.py
--- a/moto/s3/responses.py
+++ b/moto/s3/responses.py
@@ -1755,7 +1755,7 @@ def _invalid_headers(self, url, headers):
     {% for bucket in buckets %}
       <Bucket>
         <Name>{{ bucket.name }}</Name>
-        <CreationDate>{{ bucket.creation_date.isoformat() }}</CreationDate>
+        <CreationDate>{{ bucket.creation_date_ISO8601 }}</CreationDate>
       </Bucket>
     {% endfor %}
  </Buckets>


Test patch: