Skip to content

Commit edd7085

Browse files
elekbharatviswa504
authored andcommitted
HDDS-1948. S3 MPU can't be created with octet-stream content-type (#1266)
1 parent abc8fde commit edd7085

File tree

9 files changed

+63
-49
lines changed

9 files changed

+63
-49
lines changed

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

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,39 +17,60 @@
1717
*/
1818
package org.apache.hadoop.ozone.s3;
1919

20+
import javax.annotation.Priority;
2021
import javax.ws.rs.container.ContainerRequestContext;
2122
import javax.ws.rs.container.ContainerRequestFilter;
2223
import javax.ws.rs.container.PreMatching;
2324
import javax.ws.rs.core.MediaType;
25+
import javax.ws.rs.core.MultivaluedMap;
2426
import javax.ws.rs.ext.Provider;
2527
import java.io.IOException;
2628

2729
/**
2830
* Filter to adjust request headers for compatible reasons.
31+
*
32+
* It should be executed AFTER signature check (VirtualHostStyleFilter) as the
33+
* original Content-Type could be part of the base of the signature.
2934
*/
30-
3135
@Provider
3236
@PreMatching
37+
@Priority(VirtualHostStyleFilter.PRIORITY
38+
+ S3GatewayHttpServer.FILTER_PRIORITY_DO_AFTER)
3339
public class HeaderPreprocessor implements ContainerRequestFilter {
3440

41+
public static final String MULTIPART_UPLOAD_MARKER = "ozone/mpu";
42+
3543
@Override
3644
public void filter(ContainerRequestContext requestContext) throws
3745
IOException {
38-
if (requestContext.getUriInfo().getQueryParameters()
39-
.containsKey("delete")) {
46+
MultivaluedMap<String, String> queryParameters =
47+
requestContext.getUriInfo().getQueryParameters();
48+
49+
if (queryParameters.containsKey("delete")) {
4050
//aws cli doesn't send proper Content-Type and by default POST requests
4151
//processed as form-url-encoded. Here we can fix this.
4252
requestContext.getHeaders()
4353
.putSingle("Content-Type", MediaType.APPLICATION_XML);
4454
}
4555

46-
if (requestContext.getUriInfo().getQueryParameters()
47-
.containsKey("uploadId")) {
56+
if (queryParameters.containsKey("uploadId")) {
4857
//aws cli doesn't send proper Content-Type and by default POST requests
4958
//processed as form-url-encoded. Here we can fix this.
5059
requestContext.getHeaders()
5160
.putSingle("Content-Type", MediaType.APPLICATION_XML);
61+
} else if (queryParameters.containsKey("uploads")) {
62+
// uploads defined but uploadId is not --> this is the creation of the
63+
// multi-part-upload requests.
64+
//
65+
//In AWS SDK for go uses application/octet-stream which also
66+
//should be fixed to route the request to the right jaxrs method.
67+
//
68+
//Should be empty instead of XML as the body is empty which can not be
69+
//serialized as as CompleteMultipartUploadRequest
70+
requestContext.getHeaders()
71+
.putSingle("Content-Type", MULTIPART_UPLOAD_MARKER);
5272
}
73+
5374
}
5475

5576
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@
2727
*/
2828
public class S3GatewayHttpServer extends BaseHttpServer {
2929

30+
/**
31+
* Default offset between two filters.
32+
*/
33+
public static final int FILTER_PRIORITY_DO_AFTER = 50;
34+
3035
public S3GatewayHttpServer(Configuration conf,
3136
String name) throws IOException {
3237
super(conf, name);

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818
package org.apache.hadoop.ozone.s3;
1919

20+
import javax.annotation.Priority;
2021
import javax.inject.Inject;
2122
import javax.ws.rs.container.ContainerRequestContext;
2223
import javax.ws.rs.container.ContainerRequestFilter;
@@ -46,8 +47,11 @@
4647

4748
@Provider
4849
@PreMatching
50+
@Priority(VirtualHostStyleFilter.PRIORITY)
4951
public class VirtualHostStyleFilter implements ContainerRequestFilter {
5052

53+
public static final int PRIORITY = 100;
54+
5155
private static final Logger LOG = LoggerFactory.getLogger(
5256
VirtualHostStyleFilter.class);
5357

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

Lines changed: 20 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818
package org.apache.hadoop.ozone.s3.endpoint;
1919

20+
import javax.ws.rs.Consumes;
2021
import javax.ws.rs.DELETE;
2122
import javax.ws.rs.DefaultValue;
2223
import javax.ws.rs.GET;
@@ -58,6 +59,7 @@
5859
import org.apache.hadoop.ozone.om.helpers.OmMultipartCommitUploadPartInfo;
5960
import org.apache.hadoop.ozone.om.helpers.OmMultipartInfo;
6061
import org.apache.hadoop.ozone.om.helpers.OmMultipartUploadCompleteInfo;
62+
import org.apache.hadoop.ozone.s3.HeaderPreprocessor;
6163
import org.apache.hadoop.ozone.s3.SignedChunksInputStream;
6264
import org.apache.hadoop.ozone.s3.exception.OS3Exception;
6365
import org.apache.hadoop.ozone.s3.exception.S3ErrorTable;
@@ -417,33 +419,19 @@ public Response delete(
417419

418420
}
419421

422+
/**
423+
* Initialize MultiPartUpload request.
424+
* <p>
425+
* Note: the specific content type is set by the HeaderPreprocessor.
426+
*/
420427
@POST
421428
@Produces(MediaType.APPLICATION_XML)
422-
public Response multipartUpload(
429+
@Consumes(HeaderPreprocessor.MULTIPART_UPLOAD_MARKER)
430+
public Response initializeMultipartUpload(
423431
@PathParam("bucket") String bucket,
424-
@PathParam("path") String key,
425-
@QueryParam("uploads") String uploads,
426-
@QueryParam("uploadId") @DefaultValue("") String uploadID,
427-
CompleteMultipartUploadRequest request) throws IOException, OS3Exception {
428-
if (!uploadID.equals("")) {
429-
//Complete Multipart upload request.
430-
return completeMultipartUpload(bucket, key, uploadID, request);
431-
} else {
432-
// Initiate Multipart upload request.
433-
return initiateMultipartUpload(bucket, key);
434-
}
435-
}
436-
437-
/**
438-
* Initiate Multipart upload request.
439-
* @param bucket
440-
* @param key
441-
* @return Response
442-
* @throws IOException
443-
* @throws OS3Exception
444-
*/
445-
private Response initiateMultipartUpload(String bucket, String key) throws
446-
IOException, OS3Exception {
432+
@PathParam("path") String key
433+
)
434+
throws IOException, OS3Exception {
447435
try {
448436
OzoneBucket ozoneBucket = getBucket(bucket);
449437
String storageType = headers.getHeaderString(STORAGE_CLASS_HEADER);
@@ -473,7 +461,6 @@ private Response initiateMultipartUpload(String bucket, String key) throws
473461
multipartUploadInitiateResponse.setKey(key);
474462
multipartUploadInitiateResponse.setUploadID(multipartInfo.getUploadID());
475463

476-
477464
return Response.status(Status.OK).entity(
478465
multipartUploadInitiateResponse).build();
479466
} catch (IOException ex) {
@@ -484,18 +471,15 @@ private Response initiateMultipartUpload(String bucket, String key) throws
484471
}
485472

486473
/**
487-
* Complete Multipart upload request.
488-
* @param bucket
489-
* @param key
490-
* @param uploadID
491-
* @param multipartUploadRequest
492-
* @return Response
493-
* @throws IOException
494-
* @throws OS3Exception
474+
* Complete a multipart upload.
495475
*/
496-
private Response completeMultipartUpload(String bucket, String key, String
497-
uploadID, CompleteMultipartUploadRequest multipartUploadRequest) throws
498-
IOException, OS3Exception {
476+
@POST
477+
@Produces(MediaType.APPLICATION_XML)
478+
public Response completeMultipartUpload(@PathParam("bucket") String bucket,
479+
@PathParam("path") String key,
480+
@QueryParam("uploadId") @DefaultValue("") String uploadID,
481+
CompleteMultipartUploadRequest multipartUploadRequest)
482+
throws IOException, OS3Exception {
499483
OzoneBucket ozoneBucket = getBucket(bucket);
500484
Map<Integer, String> partsMap = new TreeMap<>();
501485
List<CompleteMultipartUploadRequest.Part> partList =

hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestAbortMultipartUpload.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public void testAbortMultipartUpload() throws Exception {
5656
rest.setHeaders(headers);
5757
rest.setClient(client);
5858

59-
Response response = rest.multipartUpload(bucket, key, "", "", null);
59+
Response response = rest.initializeMultipartUpload(bucket, key);
6060

6161
assertEquals(response.getStatus(), 200);
6262
MultipartUploadInitiateResponse multipartUploadInitiateResponse =

hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestInitiateMultipartUpload.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public void testInitiateMultipartUpload() throws Exception {
6060
rest.setHeaders(headers);
6161
rest.setClient(client);
6262

63-
Response response = rest.multipartUpload(bucket, key, "", "", null);
63+
Response response = rest.initializeMultipartUpload(bucket, key);
6464

6565
assertEquals(response.getStatus(), 200);
6666
MultipartUploadInitiateResponse multipartUploadInitiateResponse =
@@ -69,7 +69,7 @@ public void testInitiateMultipartUpload() throws Exception {
6969
String uploadID = multipartUploadInitiateResponse.getUploadID();
7070

7171
// Calling again should return different uploadID.
72-
response = rest.multipartUpload(bucket, key, "", "", null);
72+
response = rest.initializeMultipartUpload(bucket, key);
7373
assertEquals(response.getStatus(), 200);
7474
multipartUploadInitiateResponse =
7575
(MultipartUploadInitiateResponse) response.getEntity();

hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestListParts.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public static void setUp() throws Exception {
6161
REST.setHeaders(headers);
6262
REST.setClient(client);
6363

64-
Response response = REST.multipartUpload(BUCKET, KEY, "", "", null);
64+
Response response = REST.initializeMultipartUpload(BUCKET, KEY);
6565
MultipartUploadInitiateResponse multipartUploadInitiateResponse =
6666
(MultipartUploadInitiateResponse) response.getEntity();
6767
assertNotNull(multipartUploadInitiateResponse.getUploadID());

hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestMultipartUploadComplete.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public static void setUp() throws Exception {
7070

7171
private String initiateMultipartUpload(String key) throws IOException,
7272
OS3Exception {
73-
Response response = REST.multipartUpload(BUCKET, key, "", "", null);
73+
Response response = REST.initializeMultipartUpload(BUCKET, key);
7474
MultipartUploadInitiateResponse multipartUploadInitiateResponse =
7575
(MultipartUploadInitiateResponse) response.getEntity();
7676
assertNotNull(multipartUploadInitiateResponse.getUploadID());
@@ -99,7 +99,7 @@ private Part uploadPart(String key, String uploadID, int partNumber, String
9999
private void completeMultipartUpload(String key,
100100
CompleteMultipartUploadRequest completeMultipartUploadRequest,
101101
String uploadID) throws IOException, OS3Exception {
102-
Response response = REST.multipartUpload(BUCKET, key, "", uploadID,
102+
Response response = REST.completeMultipartUpload(BUCKET, key, uploadID,
103103
completeMultipartUploadRequest);
104104

105105
assertEquals(response.getStatus(), 200);

hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestPartUpload.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public static void setUp() throws Exception {
6767
@Test
6868
public void testPartUpload() throws Exception {
6969

70-
Response response = REST.multipartUpload(BUCKET, KEY, "", "", null);
70+
Response response = REST.initializeMultipartUpload(BUCKET, KEY);
7171
MultipartUploadInitiateResponse multipartUploadInitiateResponse =
7272
(MultipartUploadInitiateResponse) response.getEntity();
7373
assertNotNull(multipartUploadInitiateResponse.getUploadID());
@@ -86,7 +86,7 @@ public void testPartUpload() throws Exception {
8686
@Test
8787
public void testPartUploadWithOverride() throws Exception {
8888

89-
Response response = REST.multipartUpload(BUCKET, KEY, "", "", null);
89+
Response response = REST.initializeMultipartUpload(BUCKET, KEY);
9090
MultipartUploadInitiateResponse multipartUploadInitiateResponse =
9191
(MultipartUploadInitiateResponse) response.getEntity();
9292
assertNotNull(multipartUploadInitiateResponse.getUploadID());

0 commit comments

Comments
 (0)