You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by bh...@apache.org on 2019/03/08 17:55:37 UTC
[hadoop] branch trunk updated: HDDS-1213. Support plain text S3 MPU
initialization request.
This is an automated email from the ASF dual-hosted git repository.
bharat pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/hadoop.git
The following commit(s) were added to refs/heads/trunk by this push:
new c072458 HDDS-1213. Support plain text S3 MPU initialization request.
c072458 is described below
commit c072458e5d1ec88c8e4d76cd09623083b8ccfc03
Author: Elek, Márton <el...@users.noreply.github.com>
AuthorDate: Fri Mar 8 18:55:31 2019 +0100
HDDS-1213. Support plain text S3 MPU initialization request.
---
.../dist/src/main/smoketest/commonlib.robot | 8 +-
.../src/main/smoketest/s3/MultipartUpload.robot | 135 ++++++++++-----------
.../dist/src/main/smoketest/s3/objectputget.robot | 4 +-
.../endpoint/PlainTextMultipartUploadReader.java | 66 ++++++++++
4 files changed, 139 insertions(+), 74 deletions(-)
diff --git a/hadoop-ozone/dist/src/main/smoketest/commonlib.robot b/hadoop-ozone/dist/src/main/smoketest/commonlib.robot
index eb3a8bb..7f8cd4b 100644
--- a/hadoop-ozone/dist/src/main/smoketest/commonlib.robot
+++ b/hadoop-ozone/dist/src/main/smoketest/commonlib.robot
@@ -28,4 +28,10 @@ Execute and checkrc
${rc} ${output} = Run And Return Rc And Output ${command}
Log ${output}
Should Be Equal As Integers ${rc} ${expected_error_code}
- [return] ${output}
\ No newline at end of file
+ [return] ${output}
+
+Compare files
+ [arguments] ${file1} ${file2}
+ ${checksumbefore} = Execute md5sum ${file1} | awk '{print $1}'
+ ${checksumafter} = Execute md5sum ${file2} | awk '{print $1}'
+ Should Be Equal ${checksumbefore} ${checksumafter}
diff --git a/hadoop-ozone/dist/src/main/smoketest/s3/MultipartUpload.robot b/hadoop-ozone/dist/src/main/smoketest/s3/MultipartUpload.robot
index 1f69c9e..0133d50 100644
--- a/hadoop-ozone/dist/src/main/smoketest/s3/MultipartUpload.robot
+++ b/hadoop-ozone/dist/src/main/smoketest/s3/MultipartUpload.robot
@@ -22,11 +22,9 @@ Resource commonawslib.robot
Test Setup Setup s3 tests
*** Keywords ***
-Create Random file for mac
- Execute dd if=/dev/urandom of=/tmp/part1 bs=1m count=5
-
-Create Random file for linux
- Execute dd if=/dev/urandom of=/tmp/part1 bs=1M count=5
+Create Random file
+ [arguments] ${size_in_megabytes}
+ Execute dd if=/dev/urandom of=/tmp/part1 bs=1048576 count=${size_in_megabytes}
*** Variables ***
@@ -54,16 +52,13 @@ Test Multipart Upload
# upload we get error entity too small. So, considering further complete
# multipart upload, uploading each part as 5MB file, exception is for last part
- ${system} = Evaluate platform.system() platform
- Run Keyword if '${system}' == 'Darwin' Create Random file for mac
- Run Keyword if '${system}' == 'Linux' Create Random file for linux
- ${result} = Execute AWSS3APICli upload-part --bucket ${BUCKET} --key multipartKey --part-number 1 --body /tmp/part1 --upload-id ${nextUploadID}
- Should contain ${result} ETag
+ Run Keyword Create Random file 5
+ ${result} = Execute AWSS3APICli upload-part --bucket ${BUCKET} --key multipartKey --part-number 1 --body /tmp/part1 --upload-id ${nextUploadID}
+ Should contain ${result} ETag
# override part
- Run Keyword if '${system}' == 'Darwin' Create Random file for mac
- Run Keyword if '${system}' == 'Linux' Create Random file for linux
- ${result} = Execute AWSS3APICli upload-part --bucket ${BUCKET} --key multipartKey --part-number 1 --body /tmp/part1 --upload-id ${nextUploadID}
- Should contain ${result} ETag
+ Run Keyword Create Random file 5
+ ${result} = Execute AWSS3APICli upload-part --bucket ${BUCKET} --key multipartKey --part-number 1 --body /tmp/part1 --upload-id ${nextUploadID}
+ Should contain ${result} ETag
Test Multipart Upload Complete
@@ -74,17 +69,15 @@ Test Multipart Upload Complete
Should contain ${result} UploadId
#upload parts
- ${system} = Evaluate platform.system() platform
- Run Keyword if '${system}' == 'Darwin' Create Random file for mac
- Run Keyword if '${system}' == 'Linux' Create Random file for linux
- ${result} = Execute AWSS3APICli upload-part --bucket ${BUCKET} --key multipartKey1 --part-number 1 --body /tmp/part1 --upload-id ${uploadID}
- ${eTag1} = Execute and checkrc echo '${result}' | jq -r '.ETag' 0
- Should contain ${result} ETag
+ Run Keyword Create Random file 5
+ ${result} = Execute AWSS3APICli upload-part --bucket ${BUCKET} --key multipartKey1 --part-number 1 --body /tmp/part1 --upload-id ${uploadID}
+ ${eTag1} = Execute and checkrc echo '${result}' | jq -r '.ETag' 0
+ Should contain ${result} ETag
Execute echo "Part2" > /tmp/part2
- ${result} = Execute AWSS3APICli upload-part --bucket ${BUCKET} --key multipartKey1 --part-number 2 --body /tmp/part2 --upload-id ${uploadID}
- ${eTag2} = Execute and checkrc echo '${result}' | jq -r '.ETag' 0
- Should contain ${result} ETag
+ ${result} = Execute AWSS3APICli upload-part --bucket ${BUCKET} --key multipartKey1 --part-number 2 --body /tmp/part2 --upload-id ${uploadID}
+ ${eTag2} = Execute and checkrc echo '${result}' | jq -r '.ETag' 0
+ Should contain ${result} ETag
#complete multipart upload
${result} = Execute AWSS3APICli complete-multipart-upload --upload-id ${uploadID} --bucket ${BUCKET} --key multipartKey1 --multipart-upload 'Parts=[{ETag=${eTag1},PartNumber=1},{ETag=${eTag2},PartNumber=2}]'
@@ -94,11 +87,8 @@ Test Multipart Upload Complete
#read file and check the key
${result} = Execute AWSS3ApiCli get-object --bucket ${BUCKET} --key multipartKey1 /tmp/multipartKey1.result
- Execute cat /tmp/part1 /tmp/part2 >> /tmp/multipartkey1
- ${checksumbefore} = Execute md5sum /tmp/multipartkey1 | awk '{print $1}'
- ${checksumafter} = Execute md5sum /tmp/multipartKey1.result | awk '{print $1}'
- Should Be Equal ${checksumbefore} ${checksumafter}
-
+ Execute cat /tmp/part1 /tmp/part2 >> /tmp/multipartKey1
+ Compare files /tmp/multipartKey1 /tmp/multipartKey1.result
Test Multipart Upload Complete Entity too small
${result} = Execute AWSS3APICli create-multipart-upload --bucket ${BUCKET} --key multipartKey2
@@ -109,14 +99,14 @@ Test Multipart Upload Complete Entity too small
#upload parts
Execute echo "Part1" > /tmp/part1
- ${result} = Execute AWSS3APICli upload-part --bucket ${BUCKET} --key multipartKey2 --part-number 1 --body /tmp/part1 --upload-id ${uploadID}
- ${eTag1} = Execute and checkrc echo '${result}' | jq -r '.ETag' 0
- Should contain ${result} ETag
+ ${result} = Execute AWSS3APICli upload-part --bucket ${BUCKET} --key multipartKey2 --part-number 1 --body /tmp/part1 --upload-id ${uploadID}
+ ${eTag1} = Execute and checkrc echo '${result}' | jq -r '.ETag' 0
+ Should contain ${result} ETag
Execute echo "Part2" > /tmp/part2
- ${result} = Execute AWSS3APICli upload-part --bucket ${BUCKET} --key multipartKey2 --part-number 2 --body /tmp/part2 --upload-id ${uploadID}
- ${eTag2} = Execute and checkrc echo '${result}' | jq -r '.ETag' 0
- Should contain ${result} ETag
+ ${result} = Execute AWSS3APICli upload-part --bucket ${BUCKET} --key multipartKey2 --part-number 2 --body /tmp/part2 --upload-id ${uploadID}
+ ${eTag2} = Execute and checkrc echo '${result}' | jq -r '.ETag' 0
+ Should contain ${result} ETag
#complete multipart upload
${result} = Execute AWSS3APICli and checkrc complete-multipart-upload --upload-id ${uploadID} --bucket ${BUCKET} --key multipartKey2 --multipart-upload 'Parts=[{ETag=${eTag1},PartNumber=1},{ETag=${eTag2},PartNumber=2}]' 255
@@ -132,14 +122,14 @@ Test Multipart Upload Complete Invalid part
#upload parts
Execute echo "Part1" > /tmp/part1
- ${result} = Execute AWSS3APICli upload-part --bucket ${BUCKET} --key multipartKey3 --part-number 1 --body /tmp/part1 --upload-id ${uploadID}
- ${eTag1} = Execute and checkrc echo '${result}' | jq -r '.ETag' 0
- Should contain ${result} ETag
+ ${result} = Execute AWSS3APICli upload-part --bucket ${BUCKET} --key multipartKey3 --part-number 1 --body /tmp/part1 --upload-id ${uploadID}
+ ${eTag1} = Execute and checkrc echo '${result}' | jq -r '.ETag' 0
+ Should contain ${result} ETag
Execute echo "Part2" > /tmp/part2
- ${result} = Execute AWSS3APICli upload-part --bucket ${BUCKET} --key multipartKey3 --part-number 2 --body /tmp/part2 --upload-id ${uploadID}
- ${eTag2} = Execute and checkrc echo '${result}' | jq -r '.ETag' 0
- Should contain ${result} ETag
+ ${result} = Execute AWSS3APICli upload-part --bucket ${BUCKET} --key multipartKey3 --part-number 2 --body /tmp/part2 --upload-id ${uploadID}
+ ${eTag2} = Execute and checkrc echo '${result}' | jq -r '.ETag' 0
+ Should contain ${result} ETag
#complete multipart upload
${result} = Execute AWSS3APICli and checkrc complete-multipart-upload --upload-id ${uploadID} --bucket ${BUCKET} --key multipartKey3 --multipart-upload 'Parts=[{ETag=etag1,PartNumber=1},{ETag=etag2,PartNumber=2}]' 255
@@ -158,9 +148,9 @@ Test abort Multipart upload with invalid uploadId
${result} = Execute AWSS3APICli and checkrc abort-multipart-upload --bucket ${BUCKET} --key multipartKey5 --upload-id "random" 255
Upload part with Incorrect uploadID
- Execute echo "Multipart upload" > /tmp/testfile
- ${result} = Execute AWSS3APICli and checkrc upload-part --bucket ${BUCKET} --key multipartKey --part-number 1 --body /tmp/testfile --upload-id "random" 255
- Should contain ${result} NoSuchUpload
+ Execute echo "Multipart upload" > /tmp/testfile
+ ${result} = Execute AWSS3APICli and checkrc upload-part --bucket ${BUCKET} --key multipartKey --part-number 1 --body /tmp/testfile --upload-id "random" 255
+ Should contain ${result} NoSuchUpload
Test list parts
#initiate multipart upload
@@ -171,37 +161,42 @@ Test list parts
Should contain ${result} UploadId
#upload parts
- ${system} = Evaluate platform.system() platform
- Run Keyword if '${system}' == 'Darwin' Create Random file for mac
- Run Keyword if '${system}' == 'Linux' Create Random file for linux
- ${result} = Execute AWSS3APICli upload-part --bucket ${BUCKET} --key multipartKey5 --part-number 1 --body /tmp/part1 --upload-id ${uploadID}
- ${eTag1} = Execute and checkrc echo '${result}' | jq -r '.ETag' 0
- Should contain ${result} ETag
-
- Execute echo "Part2" > /tmp/part2
- ${result} = Execute AWSS3APICli upload-part --bucket ${BUCKET} --key multipartKey5 --part-number 2 --body /tmp/part2 --upload-id ${uploadID}
- ${eTag2} = Execute and checkrc echo '${result}' | jq -r '.ETag' 0
- Should contain ${result} ETag
+ Run Keyword Create Random file 5
+ ${result} = Execute AWSS3APICli upload-part --bucket ${BUCKET} --key multipartKey5 --part-number 1 --body /tmp/part1 --upload-id ${uploadID}
+ ${eTag1} = Execute and checkrc echo '${result}' | jq -r '.ETag' 0
+ Should contain ${result} ETag
+
+ Execute echo "Part2" > /tmp/part2
+ ${result} = Execute AWSS3APICli upload-part --bucket ${BUCKET} --key multipartKey5 --part-number 2 --body /tmp/part2 --upload-id ${uploadID}
+ ${eTag2} = Execute and checkrc echo '${result}' | jq -r '.ETag' 0
+ Should contain ${result} ETag
#list parts
- ${result} = Execute AWSS3APICli list-parts --bucket ${BUCKET} --key multipartKey5 --upload-id ${uploadID}
- ${part1} = Execute and checkrc echo '${result}' | jq -r '.Parts[0].ETag' 0
- ${part2} = Execute and checkrc echo '${result}' | jq -r '.Parts[1].ETag' 0
- Should Be equal ${part1} ${eTag1}
- Should contain ${part2} ${eTag2}
- Should contain ${result} STANDARD
+ ${result} = Execute AWSS3APICli list-parts --bucket ${BUCKET} --key multipartKey5 --upload-id ${uploadID}
+ ${part1} = Execute and checkrc echo '${result}' | jq -r '.Parts[0].ETag' 0
+ ${part2} = Execute and checkrc echo '${result}' | jq -r '.Parts[1].ETag' 0
+ Should Be equal ${part1} ${eTag1}
+ Should contain ${part2} ${eTag2}
+ Should contain ${result} STANDARD
#list parts with max-items and next token
- ${result} = Execute AWSS3APICli list-parts --bucket ${BUCKET} --key multipartKey5 --upload-id ${uploadID} --max-items 1
- ${part1} = Execute and checkrc echo '${result}' | jq -r '.Parts[0].ETag' 0
- ${token} = Execute and checkrc echo '${result}' | jq -r '.NextToken' 0
- Should Be equal ${part1} ${eTag1}
- Should contain ${result} STANDARD
+ ${result} = Execute AWSS3APICli list-parts --bucket ${BUCKET} --key multipartKey5 --upload-id ${uploadID} --max-items 1
+ ${part1} = Execute and checkrc echo '${result}' | jq -r '.Parts[0].ETag' 0
+ ${token} = Execute and checkrc echo '${result}' | jq -r '.NextToken' 0
+ Should Be equal ${part1} ${eTag1}
+ Should contain ${result} STANDARD
- ${result} = Execute AWSS3APICli list-parts --bucket ${BUCKET} --key multipartKey5 --upload-id ${uploadID} --max-items 1 --starting-token ${token}
- ${part2} = Execute and checkrc echo '${result}' | jq -r '.Parts[0].ETag' 0
- Should Be equal ${part2} ${eTag2}
- Should contain ${result} STANDARD
+ ${result} = Execute AWSS3APICli list-parts --bucket ${BUCKET} --key multipartKey5 --upload-id ${uploadID} --max-items 1 --starting-token ${token}
+ ${part2} = Execute and checkrc echo '${result}' | jq -r '.Parts[0].ETag' 0
+ Should Be equal ${part2} ${eTag2}
+ Should contain ${result} STANDARD
#finally abort it
- ${result} = Execute AWSS3APICli and checkrc abort-multipart-upload --bucket ${BUCKET} --key multipartKey5 --upload-id ${uploadID} 0
+ ${result} = Execute AWSS3APICli and checkrc abort-multipart-upload --bucket ${BUCKET} --key multipartKey5 --upload-id ${uploadID} 0
+
+Test Multipart Upload with the simplified aws s3 cp API
+ Create Random file 22
+ Execute AWSS3Cli cp /tmp/part1 s3://${BUCKET}/mpyawscli
+ Execute AWSS3Cli cp s3://${BUCKET}/mpyawscli /tmp/part1.result
+ Execute AWSS3Cli rm s3://${BUCKET}/mpyawscli
+ Compare files /tmp/part1 /tmp/part1.result
diff --git a/hadoop-ozone/dist/src/main/smoketest/s3/objectputget.robot b/hadoop-ozone/dist/src/main/smoketest/s3/objectputget.robot
index e42ffaf..1b2a504 100644
--- a/hadoop-ozone/dist/src/main/smoketest/s3/objectputget.robot
+++ b/hadoop-ozone/dist/src/main/smoketest/s3/objectputget.robot
@@ -42,9 +42,7 @@ Put object to s3
#This test depends on the previous test case. Can't be executes alone
Get object from s3
${result} = Execute AWSS3ApiCli get-object --bucket ${BUCKET} --key putobject/f1 /tmp/testfile.result
- ${checksumbefore} = Execute md5sum /tmp/testfile | awk '{print $1}'
- ${checksumafter} = Execute md5sum /tmp/testfile.result | awk '{print $1}'
- Should Be Equal ${checksumbefore} ${checksumafter}
+ Compare files /tmp/testfile /tmp/testfile.result
Get Partial object from s3 with both start and endoffset
${result} = Execute AWSS3ApiCli get-object --bucket ${BUCKET} --key putobject/f1 --range bytes=0-4 /tmp/testfile1.result
diff --git a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/PlainTextMultipartUploadReader.java b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/PlainTextMultipartUploadReader.java
new file mode 100644
index 0000000..599b473
--- /dev/null
+++ b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/PlainTextMultipartUploadReader.java
@@ -0,0 +1,66 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 org.apache.hadoop.ozone.s3.endpoint;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.Provider;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+/**
+ * Body reader to accept plain text MPU.
+ * <p>
+ * Aws s3 api sends a multipartupload request with the content type
+ * 'text/plain' in case of using 'aws s3 cp' (instead of aws s3api).
+ * <p>
+ * Our generic ObjectEndpoint.multipartUpload has a
+ * CompleteMultipartUploadRequest parameter, which is required only for the
+ * completion request.
+ * <p>
+ * But JaxRS tries to parse it from the body for the requests and in case of
+ * text/plain requests this parsing is failed. This simple BodyReader enables
+ * to parse an empty text/plain message and return with an empty completion
+ * request.
+ */
+@Provider
+@Consumes("text/plain")
+public class PlainTextMultipartUploadReader
+ implements MessageBodyReader<CompleteMultipartUploadRequest> {
+
+ @Override
+ public boolean isReadable(Class<?> type, Type genericType,
+ Annotation[] annotations, MediaType mediaType) {
+ return type.equals(CompleteMultipartUploadRequest.class)
+ && mediaType.equals(MediaType.TEXT_PLAIN_TYPE);
+ }
+
+ @Override
+ public CompleteMultipartUploadRequest readFrom(
+ Class<CompleteMultipartUploadRequest> type, Type genericType,
+ Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
+ throws IOException, WebApplicationException {
+ return new CompleteMultipartUploadRequest();
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org
For additional commands, e-mail: common-commits-help@hadoop.apache.org