Skip to content

Commit 8ff85f9

Browse files
adoroszlaiivandika3
authored andcommitted
HDDS-11457. Internal error on S3 CompleteMultipartUpload if parts are not specified (apache#7195)
(cherry picked from commit 9f5bf43)
1 parent 95c2502 commit 8ff85f9

7 files changed

Lines changed: 37 additions & 12 deletions

File tree

hadoop-ozone/dist/src/main/smoketest/s3/MultipartUpload.robot

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ Test Multipart Upload Complete
114114
${part2Md5Sum} = Execute md5sum /tmp/part2 | awk '{print $1}'
115115
Should Be Equal As Strings ${eTag2} ${part2Md5Sum}
116116

117+
#complete multipart upload without any parts
118+
${result} = Execute AWSS3APICli and checkrc complete-multipart-upload --upload-id ${uploadID} --bucket ${BUCKET} --key ${PREFIX}/multipartKey1 255
119+
Should contain ${result} InvalidRequest
120+
Should contain ${result} must specify at least one part
121+
117122
#complete multipart upload
118123
${result} = Execute AWSS3APICli complete-multipart-upload --upload-id ${uploadID} --bucket ${BUCKET} --key ${PREFIX}/multipartKey1 --multipart-upload 'Parts=[{ETag=${eTag1},PartNumber=1},{ETag=${eTag2},PartNumber=2}]'
119124
Should contain ${result} ${BUCKET}

hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/AuthorizationFilter.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,9 @@
1919

2020
import javax.annotation.Priority;
2121
import javax.inject.Inject;
22-
import javax.ws.rs.WebApplicationException;
2322
import javax.ws.rs.container.ContainerRequestContext;
2423
import javax.ws.rs.container.ContainerRequestFilter;
2524
import javax.ws.rs.container.PreMatching;
26-
import javax.ws.rs.core.Response;
2725
import javax.ws.rs.ext.Provider;
2826

2927
import com.google.common.annotations.VisibleForTesting;
@@ -41,6 +39,7 @@
4139
import static org.apache.hadoop.ozone.s3.exception.S3ErrorTable.ACCESS_DENIED;
4240
import static org.apache.hadoop.ozone.s3.exception.S3ErrorTable.INTERNAL_ERROR;
4341
import static org.apache.hadoop.ozone.s3.exception.S3ErrorTable.S3_AUTHINFO_CREATION_ERROR;
42+
import static org.apache.hadoop.ozone.s3.util.S3Utils.wrapOS3Exception;
4443

4544
/**
4645
* Filter used to construct string to sign from unfiltered request.
@@ -116,10 +115,4 @@ public SignatureInfo getSignatureInfo() {
116115
return signatureInfo;
117116
}
118117

119-
private WebApplicationException wrapOS3Exception(OS3Exception os3Exception) {
120-
return new WebApplicationException(os3Exception.getErrorMessage(),
121-
os3Exception,
122-
Response.status(os3Exception.getHttpCode())
123-
.entity(os3Exception.toXml()).build());
124-
}
125118
}

hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/CompleteMultipartUploadRequestUnmarshaller.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
import java.lang.reflect.Type;
3535
import javax.ws.rs.ext.Provider;
3636

37+
import static org.apache.hadoop.ozone.s3.exception.S3ErrorTable.INVALID_REQUEST;
3738
import static org.apache.hadoop.ozone.s3.util.S3Consts.S3_XML_NAMESPACE;
39+
import static org.apache.hadoop.ozone.s3.util.S3Utils.wrapOS3Exception;
3840

3941
/**
4042
* Custom unmarshaller to read CompleteMultipartUploadRequest wo namespace.
@@ -69,6 +71,10 @@ public CompleteMultipartUploadRequest readFrom(
6971
MultivaluedMap<String, String> multivaluedMap,
7072
InputStream inputStream) throws IOException, WebApplicationException {
7173
try {
74+
if (inputStream.available() == 0) {
75+
throw wrapOS3Exception(INVALID_REQUEST.withMessage("You must specify at least one part"));
76+
}
77+
7278
XMLReader xmlReader = saxParserFactory.newSAXParser().getXMLReader();
7379
UnmarshallerHandler unmarshallerHandler =
7480
context.createUnmarshaller().getUnmarshallerHandler();
@@ -78,8 +84,11 @@ public CompleteMultipartUploadRequest readFrom(
7884
filter.setParent(xmlReader);
7985
filter.parse(new InputSource(inputStream));
8086
return (CompleteMultipartUploadRequest) unmarshallerHandler.getResult();
87+
} catch (WebApplicationException e) {
88+
throw e;
8189
} catch (Exception e) {
82-
throw new WebApplicationException("Can't parse request body to XML.", e);
90+
throw wrapOS3Exception(INVALID_REQUEST.withMessage(e.getMessage()));
8391
}
8492
}
93+
8594
}

hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/MultiDeleteRequestUnmarshaller.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
package org.apache.hadoop.ozone.s3.endpoint;
1919

2020
import javax.ws.rs.Produces;
21-
import javax.ws.rs.WebApplicationException;
2221
import javax.ws.rs.core.MediaType;
2322
import javax.ws.rs.core.MultivaluedMap;
2423
import javax.ws.rs.ext.MessageBodyReader;
@@ -34,6 +33,9 @@
3433
import org.xml.sax.InputSource;
3534
import org.xml.sax.XMLReader;
3635

36+
import static org.apache.hadoop.ozone.s3.exception.S3ErrorTable.INVALID_REQUEST;
37+
import static org.apache.hadoop.ozone.s3.util.S3Utils.wrapOS3Exception;
38+
3739
/**
3840
* Custom unmarshaller to read MultiDeleteRequest w/wo namespace.
3941
*/
@@ -78,7 +80,7 @@ public MultiDeleteRequest readFrom(Class<MultiDeleteRequest> type,
7880
filter.parse(new InputSource(entityStream));
7981
return (MultiDeleteRequest) unmarshallerHandler.getResult();
8082
} catch (Exception e) {
81-
throw new WebApplicationException("Can't parse request body to XML.", e);
83+
throw wrapOS3Exception(INVALID_REQUEST.withMessage(e.getMessage()));
8284
}
8385
}
8486
}

hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/PutBucketAclRequestUnmarshaller.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
import java.lang.annotation.Annotation;
3535
import java.lang.reflect.Type;
3636

37+
import static org.apache.hadoop.ozone.s3.exception.S3ErrorTable.INVALID_REQUEST;
3738
import static org.apache.hadoop.ozone.s3.util.S3Consts.S3_XML_NAMESPACE;
39+
import static org.apache.hadoop.ozone.s3.util.S3Utils.wrapOS3Exception;
3840

3941
/**
4042
* Custom unmarshaller to read PutBucketAclRequest wo namespace.
@@ -79,7 +81,7 @@ public S3BucketAcl readFrom(
7981
filter.parse(new InputSource(inputStream));
8082
return (S3BucketAcl)(unmarshallerHandler.getResult());
8183
} catch (Exception e) {
82-
throw new WebApplicationException("Can't parse request body to XML.", e);
84+
throw wrapOS3Exception(INVALID_REQUEST.withMessage(e.getMessage()));
8385
}
8486
}
8587
}

hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/exception/OS3Exception.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,4 +158,9 @@ public String toXml() {
158158
this.getErrorMessage(), this.getResource(),
159159
this.getRequestId());
160160
}
161+
162+
/** Create a copy with specific message. */
163+
public OS3Exception withMessage(String message) {
164+
return new OS3Exception(code, message, httpCode);
165+
}
161166
}

hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/util/S3Utils.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
2424
import org.apache.hadoop.ozone.s3.exception.OS3Exception;
2525

26+
import javax.ws.rs.WebApplicationException;
27+
import javax.ws.rs.core.Response;
2628
import java.io.UnsupportedEncodingException;
2729
import java.net.URLDecoder;
2830
import java.net.URLEncoder;
@@ -116,4 +118,11 @@ public static S3StorageType toS3StorageType(String storageType)
116118
throw newError(INVALID_ARGUMENT, storageType, ex);
117119
}
118120
}
121+
122+
public static WebApplicationException wrapOS3Exception(OS3Exception ex) {
123+
return new WebApplicationException(ex.getErrorMessage(), ex,
124+
Response.status(ex.getHttpCode())
125+
.entity(ex.toXml())
126+
.build());
127+
}
119128
}

0 commit comments

Comments
 (0)