{"id":10930,"date":"2013-04-06T15:00:26","date_gmt":"2013-04-06T12:00:26","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=10930"},"modified":"2013-05-08T10:20:44","modified_gmt":"2013-05-08T07:20:44","slug":"multipart-upload-on-s3-with-jclouds","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2013\/04\/multipart-upload-on-s3-with-jclouds.html","title":{"rendered":"Multipart Upload on S3 with jclouds"},"content":{"rendered":"<h2>1. Goal<\/h2>\n<p>In <a title=\"Upload on S3 with the jclouds library\" href=\"http:\/\/www.baeldung.com\/2013\/04\/01\/upload-on-s3-with-jclouds\/\">the previous article<\/a>, we looked at how we can use the generic Blob APIs from jclouds to upload content to S3. In this article we will use the <b>S3 specific asynchronous API from jclouds<\/b> to upload content and leverage the multipart upload functionality <a title=\"Amazon S3: Multipart Upload\" href=\"http:\/\/aws.typepad.com\/aws\/2010\/11\/amazon-s3-multipart-upload.html\" target=\"_blank\">provided by S3<\/a>.<\/p>\n<h2>2. Preparation<\/h2>\n<p>&nbsp;<br \/>\n&nbsp;<\/p>\n<h4>2.1. Set up the custom API<\/h4>\n<p>The first part of the upload process is creating the jclouds API \u2013 this is a custom API for Amazon S3:<\/p>\n<pre class=\" brush:java\">public AWSS3AsyncClient s3AsyncClient() {\r\n   String identity = ...\r\n   String credentials = ...\r\n   BlobStoreContext context = ContextBuilder.newBuilder('aws-s3').\r\n      credentials(identity, credentials).buildView(BlobStoreContext.class);\r\n   RestContext&lt;AWSS3Client, AWSS3AsyncClient&gt; providerContext = context.unwrap();\r\n   return providerContext.getAsyncApi();\r\n}<\/pre>\n<h4>2.2. Determining the number of parts for the content<\/h4>\n<p>Amazon S3 has a 5 MB limit for each part to be uploaded. As such, the first thing we need to do is determine the right number of parts that we can split our content into so that we don\u2019t have parts below this 5 MB limit:<\/p>\n<pre class=\" brush:java\">public static int getMaximumNumberOfParts(byte[] byteArray) {\r\n   int numberOfParts= byteArray.length \/ fiveMB; \/\/ 5*1024*1024\r\n   if (numberOfParts== 0) {\r\n      return 1;\r\n   }\r\n   return numberOfParts;\r\n}<\/pre>\n<h4>2.3. Breaking the content into parts<\/h4>\n<p>Were going to break the byte array into a set number of parts:<\/p>\n<pre class=\" brush:java\">public static List&lt;byte[]&gt; breakByteArrayIntoParts(byte[] byteArray, int maxNumberOfParts) {\r\n   List&lt;byte[]&gt; parts = Lists.&lt;byte[]&gt; newArrayListWithCapacity(maxNumberOfParts);\r\n   int fullSize = byteArray.length;\r\n   long dimensionOfPart = fullSize \/ maxNumberOfParts;\r\n   for (int i = 0; i &lt; maxNumberOfParts; i++) {\r\n      int previousSplitPoint = (int) (dimensionOfPart * i);\r\n      int splitPoint = (int) (dimensionOfPart * (i + 1));\r\n      if (i == (maxNumberOfParts - 1)) {\r\n         splitPoint = fullSize;\r\n      }\r\n      byte[] partBytes = Arrays.copyOfRange(byteArray, previousSplitPoint, splitPoint);\r\n      parts.add(partBytes);\r\n   }\r\n   return parts;\r\n}<\/pre>\n<p>We\u2019re going to <b>test<\/b> the logic of breaking the byte array into parts \u2013 we\u2019re going to generate some bytes, split the byte array, recompose it back together using Guava and <b>verify<\/b> that we get back the original:<\/p>\n<pre class=\" brush:java\">@Test\r\npublic void given16MByteArray_whenFileBytesAreSplitInto3_thenTheSplitIsCorrect() {\r\n   byte[] byteArray = randomByteData(16);\r\n   int maximumNumberOfParts = S3Util.getMaximumNumberOfParts(byteArray);\r\n   List&lt;byte[]&gt; fileParts = S3Util.breakByteArrayIntoParts(byteArray, maximumNumberOfParts);\r\n   assertThat(fileParts.get(0).length + fileParts.get(1).length + fileParts.get(2).length,\r\n      equalTo(byteArray.length));\r\n   byte[] unmultiplexed = Bytes.concat(fileParts.get(0), fileParts.get(1), fileParts.get(2));\r\n   assertThat(byteArray, equalTo(unmultiplexed));\r\n}<\/pre>\n<p>To generate the data, we simply use the support from <em>Random<\/em>:<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<pre class=\" brush:java\">byte[] randomByteData(int mb) {\r\n   byte[] randomBytes = new byte[mb * 1024 * 1024];\r\n   new Random().nextBytes(randomBytes);\r\n   return randomBytes;\r\n}<\/pre>\n<h4>2.4. Creating the Payloads<\/h4>\n<p>Now that we have determined the correct number of parts for our content and we managed to break the content into parts, we need to <b>generate the Payload objects<\/b> for the jclouds API:<\/p>\n<pre class=\" brush:java\">public static List&lt;Payload&gt; createPayloadsOutOfParts(Iterable&lt;byte[]&gt; fileParts) {\r\n   List&lt;Payload&gt; payloads = Lists.newArrayList();\r\n   for (byte[] filePart : fileParts) {\r\n      byte[] partMd5Bytes = Hashing.md5().hashBytes(filePart).asBytes();\r\n      Payload partPayload = Payloads.newByteArrayPayload(filePart);\r\n      partPayload.getContentMetadata().setContentLength((long) filePart.length);\r\n      partPayload.getContentMetadata().setContentMD5(partMd5Bytes);\r\n      payloads.add(partPayload);\r\n   }\r\n   return payloads;\r\n}<\/pre>\n<h2>3. Upload<\/h2>\n<p>The upload process is a flexible multi-step process \u2013 this means:<\/p>\n<ul>\n<li>the upload can be started <b>before having all the data<\/b> \u2013 data can be uploaded as it\u2019s coming in<\/li>\n<li>data is uploaded in <b>chunks<\/b> \u2013 if one of these operations fails, it can simply be retrieved<\/li>\n<li>chunks can be uploaded <b>in parallel<\/b> \u2013 this can greatly increase the upload speed, especially in the case of large files<\/li>\n<\/ul>\n<h4>3.1. Initiating the Upload operation<\/h4>\n<p>The first step in the Upload operation is to <b>initiate the process<\/b>. This request to S3 must contain the standard HTTP headers \u2013 the <em>Content<\/em>&#8211;<em>MD5<\/em> header in particular needs to be computed. Were going to use the Guava hash function support here:<\/p>\n<pre class=\" brush:java\">Hashing.md5().hashBytes(byteArray).asBytes();<\/pre>\n<p>This is the <b>md5 hash<\/b> of the entire byte array, not of the parts yet.<\/p>\n<p>To <b>initiate the upload<\/b>, and for all further interactions with S3, we\u2019re going to use the AWSS3AsyncClient \u2013 the asynchronous API we created earlier:<\/p>\n<pre class=\" brush:java\">ObjectMetadata metadata = ObjectMetadataBuilder.create().key(key).contentMD5(md5Bytes).build();\r\nString uploadId = s3AsyncApi.initiateMultipartUpload(container, metadata).get();<\/pre>\n<p>The <em><b>key<\/b><\/em> is the handle assigned to the object \u2013 this needs to be a unique identifier specified by the client.<\/p>\n<p>Also notice that, even though we\u2019re using the async version of the API, <b>we\u2019re blocking<\/b> for the result of this operation \u2013 this is because we will need the result of the initialize to be able to move forward.<\/p>\n<p>The result of the operation is an <b>upload id<\/b> returned by S3 \u2013 this will identify the upload throughout it\u2019s lifecycle and will be present in all subsequent upload operations.<\/p>\n<h4>3.2. Uploading the Parts<\/h4>\n<p>The next step is <b>uploading the parts<\/b>. Our goal here is to send these requests <b>in parallel<\/b>, as the upload parts operation represent the bulk of the upload process:<\/p>\n<pre class=\" brush:java\">List&lt;ListenableFuture&lt;String&gt;&gt; ongoingOperations = Lists.newArrayList();\r\nfor (int partNumber = 0; partNumber &lt; filePartsAsByteArrays.size(); partNumber++) {\r\n   ListenableFuture&lt;String&gt; future = s3AsyncApi.uploadPart(\r\n      container, key, partNumber + 1, uploadId, payloads.get(partNumber));\r\n   ongoingOperations.add(future);\r\n}<\/pre>\n<p>The part numbers need to be continuous but the order in which the requests are send is not relevant.<\/p>\n<p>After all of the upload part requests have been submitted, we need to <b>wait for their responses <\/b>so that we can collect the individual ETag value of each part:<\/p>\n<pre class=\" brush:java\">Function&lt;ListenableFuture&lt;String&gt;, String&gt; getEtagFromOp =\r\n  new Function&lt;ListenableFuture&lt;String&gt;, String&gt;() {\r\n   public String apply(ListenableFuture&lt;String&gt; ongoingOperation) {\r\n      try {\r\n         return ongoingOperation.get();\r\n      } catch (InterruptedException | ExecutionException e) {\r\n         throw new IllegalStateException(e);\r\n      }\r\n   }\r\n};\r\nList&lt;String&gt; etagsOfParts = Lists.transform(ongoingOperations, getEtagFromOp);<\/pre>\n<p>If, for whatever reason, one of the upload part operations fails, <b>the operation can be retried<\/b> until it succeeds. The logic above does not contain the retry mechanism, but building it in should be straightforward enough.<\/p>\n<h4>3.3. Completing the Upload operation<\/h4>\n<p>The final step of the upload process is <b>completing the multipart operation<\/b>. The S3 API requires the responses from the previous parts upload as a <em>Map<\/em>, which we can now easily create from the list of ETags that we obtained above:<\/p>\n<pre class=\" brush:java\">Map&lt;Integer, String&gt; parts = Maps.newHashMap();\r\nfor (int i = 0; i &lt; etagsOfParts.size(); i++) {\r\n   parts.put(i + 1, etagsOfParts.get(i));\r\n}<\/pre>\n<p>And finally, send the complete request:<\/p>\n<pre class=\" brush:java\">s3AsyncApi.completeMultipartUpload(container, key, uploadId, parts).get();<\/pre>\n<p>This will return final ETag of the finished object and will complete the entire upload process.<\/p>\n<h2>4. Conclusion<\/h2>\n<p>In this article we built a multipart enabled, fully parallel upload operation to S3, using the custom S3 jclouds API. This operation is ready to be used as is, but it can be <b>improved<\/b> in a few ways. First, <b>retry logic<\/b> should be added around the upload operations to better deal with failures. Next, for really large files, even though the mechanism is sending all upload multipart requests in parallel, <b>a throttling mechanism<\/b> should still limit the number of parallel requests being sent. This is both to avoid bandwidth becoming a bottleneck as well as to make sure Amazon itself doesn\u2019t flag the upload process as exceeding an allowed limit of requests per second \u2013 the <a title=\"Guava RateLimiter\" href=\"http:\/\/docs.guava-libraries.googlecode.com\/git\/javadoc\/com\/google\/common\/util\/concurrent\/RateLimiter.html\" target=\"_blank\">Guava RateLimiter<\/a> can potentially be very well suited for this.<br \/>\n&nbsp;<\/p>\n<div style=\"border: 1px solid #D8D8D8; background: #FAFAFA; width: 100%; padding-left: 5px;\"><b><i>Reference: <\/i><\/b><a href=\"http:\/\/www.baeldung.com\/2013\/04\/04\/multipart-upload-on-s3-with-jclouds\/\">Multipart Upload on S3 with jclouds<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/jcg\">JCG partner<\/a> Eugen Paraschiv at the <a href=\"http:\/\/www.baeldung.com\/\">baeldung<\/a> blog.<\/div>\n","protected":false},"excerpt":{"rendered":"<p>1. Goal In the previous article, we looked at how we can use the generic Blob APIs from jclouds to upload content to S3. In this article we will use the S3 specific asynchronous API from jclouds to upload content and leverage the multipart upload functionality provided by S3. 2. Preparation &nbsp; &nbsp; 2.1. Set &hellip;<\/p>\n","protected":false},"author":104,"featured_media":112,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[331,210],"class_list":["post-10930","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-amazon-aws","tag-cloud"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Multipart Upload on S3 with jclouds<\/title>\n<meta name=\"description\" content=\"1. Goal In the previous article, we looked at how we can use the generic Blob APIs from jclouds to upload content to S3. In this article we will use the\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2013\/04\/multipart-upload-on-s3-with-jclouds.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Multipart Upload on S3 with jclouds\" \/>\n<meta property=\"og:description\" content=\"1. Goal In the previous article, we looked at how we can use the generic Blob APIs from jclouds to upload content to S3. In this article we will use the\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2013\/04\/multipart-upload-on-s3-with-jclouds.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2013-04-06T12:00:26+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2013-05-08T07:20:44+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Eugen Paraschiv\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@http:\/\/twitter.com\/baeldung\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Eugen Paraschiv\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/04\\\/multipart-upload-on-s3-with-jclouds.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/04\\\/multipart-upload-on-s3-with-jclouds.html\"},\"author\":{\"name\":\"Eugen Paraschiv\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/7a8ad27f4bb34bb3664fda07d3142bc4\"},\"headline\":\"Multipart Upload on S3 with jclouds\",\"datePublished\":\"2013-04-06T12:00:26+00:00\",\"dateModified\":\"2013-05-08T07:20:44+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/04\\\/multipart-upload-on-s3-with-jclouds.html\"},\"wordCount\":809,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/04\\\/multipart-upload-on-s3-with-jclouds.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"keywords\":[\"Amazon AWS\",\"Cloud\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/04\\\/multipart-upload-on-s3-with-jclouds.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/04\\\/multipart-upload-on-s3-with-jclouds.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/04\\\/multipart-upload-on-s3-with-jclouds.html\",\"name\":\"Multipart Upload on S3 with jclouds\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/04\\\/multipart-upload-on-s3-with-jclouds.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/04\\\/multipart-upload-on-s3-with-jclouds.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"datePublished\":\"2013-04-06T12:00:26+00:00\",\"dateModified\":\"2013-05-08T07:20:44+00:00\",\"description\":\"1. Goal In the previous article, we looked at how we can use the generic Blob APIs from jclouds to upload content to S3. In this article we will use the\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/04\\\/multipart-upload-on-s3-with-jclouds.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/04\\\/multipart-upload-on-s3-with-jclouds.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/04\\\/multipart-upload-on-s3-with-jclouds.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"java-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/04\\\/multipart-upload-on-s3-with-jclouds.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Multipart Upload on S3 with jclouds\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/7a8ad27f4bb34bb3664fda07d3142bc4\",\"name\":\"Eugen Paraschiv\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d1e55876feb753ccc6de08d413df2c915e5704dd901010340c1499a7572f8d7a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d1e55876feb753ccc6de08d413df2c915e5704dd901010340c1499a7572f8d7a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d1e55876feb753ccc6de08d413df2c915e5704dd901010340c1499a7572f8d7a?s=96&d=mm&r=g\",\"caption\":\"Eugen Paraschiv\"},\"sameAs\":[\"http:\\\/\\\/www.baeldung.com\\\/\",\"http:\\\/\\\/www.linkedin.com\\\/in\\\/eugenparaschiv\",\"https:\\\/\\\/x.com\\\/http:\\\/\\\/twitter.com\\\/baeldung\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/Eugen-Paraschiv\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Multipart Upload on S3 with jclouds","description":"1. Goal In the previous article, we looked at how we can use the generic Blob APIs from jclouds to upload content to S3. In this article we will use the","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2013\/04\/multipart-upload-on-s3-with-jclouds.html","og_locale":"en_US","og_type":"article","og_title":"Multipart Upload on S3 with jclouds","og_description":"1. Goal In the previous article, we looked at how we can use the generic Blob APIs from jclouds to upload content to S3. In this article we will use the","og_url":"https:\/\/www.javacodegeeks.com\/2013\/04\/multipart-upload-on-s3-with-jclouds.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2013-04-06T12:00:26+00:00","article_modified_time":"2013-05-08T07:20:44+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","type":"image\/jpeg"}],"author":"Eugen Paraschiv","twitter_card":"summary_large_image","twitter_creator":"@http:\/\/twitter.com\/baeldung","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Eugen Paraschiv","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2013\/04\/multipart-upload-on-s3-with-jclouds.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/04\/multipart-upload-on-s3-with-jclouds.html"},"author":{"name":"Eugen Paraschiv","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/7a8ad27f4bb34bb3664fda07d3142bc4"},"headline":"Multipart Upload on S3 with jclouds","datePublished":"2013-04-06T12:00:26+00:00","dateModified":"2013-05-08T07:20:44+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/04\/multipart-upload-on-s3-with-jclouds.html"},"wordCount":809,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/04\/multipart-upload-on-s3-with-jclouds.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","keywords":["Amazon AWS","Cloud"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2013\/04\/multipart-upload-on-s3-with-jclouds.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2013\/04\/multipart-upload-on-s3-with-jclouds.html","url":"https:\/\/www.javacodegeeks.com\/2013\/04\/multipart-upload-on-s3-with-jclouds.html","name":"Multipart Upload on S3 with jclouds","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/04\/multipart-upload-on-s3-with-jclouds.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/04\/multipart-upload-on-s3-with-jclouds.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","datePublished":"2013-04-06T12:00:26+00:00","dateModified":"2013-05-08T07:20:44+00:00","description":"1. Goal In the previous article, we looked at how we can use the generic Blob APIs from jclouds to upload content to S3. In this article we will use the","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/04\/multipart-upload-on-s3-with-jclouds.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2013\/04\/multipart-upload-on-s3-with-jclouds.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2013\/04\/multipart-upload-on-s3-with-jclouds.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","width":150,"height":150,"caption":"java-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2013\/04\/multipart-upload-on-s3-with-jclouds.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Multipart Upload on S3 with jclouds"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/7a8ad27f4bb34bb3664fda07d3142bc4","name":"Eugen Paraschiv","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/d1e55876feb753ccc6de08d413df2c915e5704dd901010340c1499a7572f8d7a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/d1e55876feb753ccc6de08d413df2c915e5704dd901010340c1499a7572f8d7a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d1e55876feb753ccc6de08d413df2c915e5704dd901010340c1499a7572f8d7a?s=96&d=mm&r=g","caption":"Eugen Paraschiv"},"sameAs":["http:\/\/www.baeldung.com\/","http:\/\/www.linkedin.com\/in\/eugenparaschiv","https:\/\/x.com\/http:\/\/twitter.com\/baeldung"],"url":"https:\/\/www.javacodegeeks.com\/author\/Eugen-Paraschiv"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/10930","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/104"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=10930"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/10930\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/112"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=10930"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=10930"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=10930"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}