awsdocs/aws-java-developer-guide-v2

405 error with S3 Multipart upload

sdelamo opened this issue · 1 comments

I am trying to create a tutorial for http://guides.micronaut.io showcasing multipart uploads in a Micronaut app to S3.

I am attempting to get this working with v2 of the SDK with such code:


        Flowable.fromPublisher(file)
                .map(partData -> {
                            InputStream inputStream = partData.getInputStream();

                            RequestBody requestBody = RequestBody.fromInputStream(inputStream, file.getSize());
                            String etag  = s3Client.uploadPart(builder -> builder
                                    .bucket(bucketName)
                                    .key(key)
                                    .uploadId(uploadId)
                                    //.partNumber(1)
                                    , requestBody).eTag();
                            CompletedPart part = CompletedPart.builder()
                                    //.partNumber(1)
                                    .eTag(etag)
                                    .build();
                            return part;
                        })
                .collect(ArrayList<CompletedPart>::new, ArrayList::add)
                .subscribe(completedParts -> {
                            CompletedMultipartUpload completedMultipartUpload = CompletedMultipartUpload.builder().parts(completedParts).build();
                            CompleteMultipartUploadRequest completeMultipartUploadRequest =
                                    CompleteMultipartUploadRequest.builder()
                                            .bucket(bucketName)
                                            .key(key)
                                            .uploadId(uploadId)
                                            .multipartUpload(completedMultipartUpload).build();
                            CompleteMultipartUploadResponse rsp = s3Client.completeMultipartUpload(completeMultipartUploadRequest);
                });

However the s3Client.uploadPart( is throwing this exception:

Caused by: software.amazon.awssdk.services.s3.model.S3Exception: The specified method is not allowed against this resource. (Service: S3Client, Status Code: 405, Request ID: B9F641406FE922E4)
	at software.amazon.awssdk.core.internal.http.pipeline.stages.HandleResponseStage.handleErrorResponse(HandleResponseStage.java:116)
	at software.amazon.awssdk.core.internal.http.pipeline.stages.HandleResponseStage.handleResponse(HandleResponseStage.java:74)
	at software.amazon.awssdk.core.internal.http.pipeline.stages.HandleResponseStage.execute(HandleResponseStage.java:59)
	at software.amazon.awssdk.core.internal.http.pipeline.stages.HandleResponseStage.execute(HandleResponseStage.java:41)
	at software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(RequestPipelineBuilder.java:205)
	at software.amazon.awssdk.core.internal.http.pipeline.stages.RetryableStage$RetryExecutor.doExecute(RetryableStage.java:139)
	at software.amazon.awssdk.core.internal.http.pipeline.stages.RetryableStage$RetryExecutor.execute(RetryableStage.java:109)
	at software.amazon.awssdk.core.internal.http.pipeline.stages.RetryableStage.execute(RetryableStage.java:67)
	at software.amazon.awssdk.core.internal.http.pipeline.stages.RetryableStage.execute(RetryableStage.java:47)
	at software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(RequestPipelineBuilder.java:205)
	at software.amazon.awssdk.core.internal.http.StreamManagingStage.execute(StreamManagingStage.java:56)
	at software.amazon.awssdk.core.internal.http.StreamManagingStage.execute(StreamManagingStage.java:41)
	at software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(RequestPipelineBuilder.java:205)
	at software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(RequestPipelineBuilder.java:205)
	at software.amazon.awssdk.core.internal.http.pipeline.stages.ExecutionFailureExceptionReportingStage.execute(ExecutionFailureExceptionReportingStage.java:37)
	at software.amazon.awssdk.core.internal.http.pipeline.stages.ExecutionFailureExceptionReportingStage.execute(ExecutionFailureExceptionReportingStage.java:25)
	at software.amazon.awssdk.core.internal.http.AmazonSyncHttpClient$RequestExecutionBuilderImpl.execute(AmazonSyncHttpClient.java:272)
	at software.amazon.awssdk.core.client.handler.BaseSyncClientHandler.invoke(BaseSyncClientHandler.java:90)
	at software.amazon.awssdk.core.client.handler.BaseSyncClientHandler.execute(BaseSyncClientHandler.java:102)
	at software.amazon.awssdk.core.client.handler.BaseSyncClientHandler.execute(BaseSyncClientHandler.java:67)
	at software.amazon.awssdk.core.client.handler.SdkSyncClientHandler.execute(SdkSyncClientHandler.java:44)
	at software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.execute(AwsSyncClientHandler.java:53)
	at software.amazon.awssdk.services.s3.DefaultS3Client.uploadPart(DefaultS3Client.java:2856)
	at software.amazon.awssdk.services.s3.S3Client.uploadPart(S3Client.java:4648)```

I have searched online and it seems to be implied that a 405 means that I am missing a bucket policy:

I've even tried with a public policy such as which sets the bucket to public access:

{
    "Version": "2012-10-17",
    "Id": "PolicyXXXXXXXX",
    "Statement": [
        {
            "Sid": "StmtXXXXXX",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::mybucketname"
        }
    ]
}

but I am still getting the exception.

any idea what I am missing?

Thank you for your feedback.

I was unable to reproduce this error.

We've made improvements to the AWS SDK for Java v2 since you posted this. If you continue to have issues, please file a ticket on the Java v2 repository at https://github.com/aws/aws-sdk-java-v2