PageRenderTime 1ms CodeModel.GetById 19ms app.highlight 19ms RepoModel.GetById 0ms app.codeStats 0ms

/apis/s3/src/test/java/org/jclouds/s3/S3ClientLiveTest.java

https://github.com/regularfry/jclouds
Java | 501 lines | 384 code | 78 blank | 39 comment | 8 complexity | 4970533158065089ad0339b7a52803d2 MD5 | raw file
  1/**
  2 * Licensed to jclouds, Inc. (jclouds) under one or more
  3 * contributor license agreements.  See the NOTICE file
  4 * distributed with this work for additional information
  5 * regarding copyright ownership.  jclouds licenses this file
  6 * to you under the Apache License, Version 2.0 (the
  7 * "License"); you may not use this file except in compliance
  8 * with the License.  You may obtain a copy of the License at
  9 *
 10 *   http://www.apache.org/licenses/LICENSE-2.0
 11 *
 12 * Unless required by applicable law or agreed to in writing,
 13 * software distributed under the License is distributed on an
 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15 * KIND, either express or implied.  See the License for the
 16 * specific language governing permissions and limitations
 17 * under the License.
 18 */
 19package org.jclouds.s3;
 20
 21import static org.jclouds.s3.internal.StubS3AsyncClient.TEST_ACL_EMAIL;
 22import static org.jclouds.s3.internal.StubS3AsyncClient.TEST_ACL_ID;
 23import static org.jclouds.s3.options.CopyObjectOptions.Builder.ifSourceETagDoesntMatch;
 24import static org.jclouds.s3.options.CopyObjectOptions.Builder.ifSourceETagMatches;
 25import static org.jclouds.s3.options.CopyObjectOptions.Builder.ifSourceModifiedSince;
 26import static org.jclouds.s3.options.CopyObjectOptions.Builder.ifSourceUnmodifiedSince;
 27import static org.jclouds.s3.options.CopyObjectOptions.Builder.overrideAcl;
 28import static org.jclouds.s3.options.CopyObjectOptions.Builder.overrideMetadataWith;
 29import static org.jclouds.s3.options.PutObjectOptions.Builder.withAcl;
 30import static org.testng.Assert.assertEquals;
 31import static org.testng.Assert.assertFalse;
 32import static org.testng.Assert.assertTrue;
 33
 34import java.io.IOException;
 35import java.net.URL;
 36import java.util.Date;
 37import java.util.Map;
 38import java.util.concurrent.ExecutionException;
 39import java.util.concurrent.TimeoutException;
 40
 41import org.jclouds.s3.domain.AccessControlList;
 42import org.jclouds.s3.domain.CannedAccessPolicy;
 43import org.jclouds.s3.domain.ObjectMetadata;
 44import org.jclouds.s3.domain.S3Object;
 45import org.jclouds.s3.domain.AccessControlList.CanonicalUserGrantee;
 46import org.jclouds.s3.domain.AccessControlList.EmailAddressGrantee;
 47import org.jclouds.s3.domain.AccessControlList.GroupGranteeURI;
 48import org.jclouds.s3.domain.AccessControlList.Permission;
 49import org.jclouds.s3.options.PutObjectOptions;
 50import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
 51import org.jclouds.http.HttpResponseException;
 52import org.jclouds.util.Strings2;
 53import org.testng.annotations.Test;
 54
 55import com.google.common.base.Throwables;
 56import com.google.common.collect.Maps;
 57
 58/**
 59 * 
 60 * @author James Murty
 61 * @author Adrian Cole
 62 */
 63@Test(groups = { "integration", "live" })
 64public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest {
 65   public S3Client getApi() {
 66      return (S3Client) context.getProviderSpecificContext().getApi();
 67   }
 68
 69   /**
 70    * this method overrides containerName to ensure it isn't found
 71    */
 72   @Test(groups = { "integration", "live" })
 73   public void deleteContainerIfEmptyNotFound() throws Exception {
 74      assert getApi().deleteBucketIfEmpty("dbienf");
 75   }
 76
 77   @Test(groups = { "integration", "live" })
 78   public void deleteContainerIfEmptyButHasContents() throws Exception {
 79      String containerName = getContainerName();
 80      try {
 81         addBlobToContainer(containerName, "test");
 82         assert !getApi().deleteBucketIfEmpty(containerName);
 83      } finally {
 84         returnContainer(containerName);
 85      }
 86   }
 87
 88   protected URL getObjectURL(String containerName, String key) throws Exception {
 89      URL url = new URL(String.format("http://%s.%s/%s", containerName, context.getProviderSpecificContext()
 90               .getEndpoint().getHost(), key));
 91      return url;
 92   }
 93
 94   public void testPutCannedAccessPolicyPublic() throws Exception {
 95      String containerName = getContainerName();
 96      try {
 97         String key = "hello";
 98         S3Object object = getApi().newS3Object();
 99         object.getMetadata().setKey(key);
100         object.setPayload(TEST_STRING);
101         getApi().putObject(containerName, object,
102
103         withAcl(CannedAccessPolicy.PUBLIC_READ));
104
105         URL url = this.getObjectURL(containerName, key);
106         Strings2.toStringAndClose(url.openStream());
107      } finally {
108         returnContainer(containerName);
109      }
110
111   }
112
113   public void testCopyCannedAccessPolicyPublic() throws Exception {
114      String containerName = getContainerName();
115      String destinationContainer = getContainerName();
116      try {
117         addBlobToContainer(containerName, sourceKey);
118         validateContent(containerName, sourceKey);
119
120         getApi().copyObject(containerName, sourceKey, destinationContainer, destinationKey,
121                  overrideAcl(CannedAccessPolicy.PUBLIC_READ));
122
123         validateContent(destinationContainer, destinationKey);
124
125         URL url = getObjectURL(destinationContainer, destinationKey);
126         Strings2.toStringAndClose(url.openStream());
127
128      } finally {
129         returnContainer(containerName);
130         returnContainer(destinationContainer);
131      }
132   }
133
134   String sourceKey = "apples";
135   String destinationKey = "pears";
136
137   public void testPublicWriteOnObject() throws InterruptedException, ExecutionException, TimeoutException, IOException {
138      final String publicReadWriteObjectKey = "public-read-write-acl";
139      final String containerName = getContainerName();
140      try {
141         S3Object object = getApi().newS3Object();
142         object.getMetadata().setKey(publicReadWriteObjectKey);
143         object.setPayload("");
144         // Public Read-Write object
145         getApi()
146                  .putObject(containerName, object,
147                           new PutObjectOptions().withAcl(CannedAccessPolicy.PUBLIC_READ_WRITE));
148
149         assertConsistencyAware(new Runnable() {
150            public void run() {
151               try {
152                  AccessControlList acl = getApi().getObjectACL(containerName, publicReadWriteObjectKey);
153                  assertEquals(acl.getGrants().size(), 3);
154                  assertEquals(acl.getPermissions(GroupGranteeURI.ALL_USERS).size(), 2);
155                  assertTrue(acl.getOwner() != null);
156                  String ownerId = acl.getOwner().getId();
157                  assertTrue(acl.hasPermission(ownerId, Permission.FULL_CONTROL));
158                  assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ));
159                  assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.WRITE));
160                  assertFalse(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ_ACP));
161                  assertFalse(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.WRITE_ACP));
162                  assertFalse(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.FULL_CONTROL));
163               } catch (Exception e) {
164                  Throwables.propagateIfPossible(e);
165               }
166            }
167         });
168      } finally {
169         returnContainer(containerName);
170      }
171
172   }
173
174   public void testUpdateObjectACL() throws InterruptedException, ExecutionException, TimeoutException, IOException {
175      String containerName = getContainerName();
176      try {
177         String objectKey = "private-acl";
178
179         // Private object
180         addBlobToContainer(containerName, objectKey);
181         AccessControlList acl = getApi().getObjectACL(containerName, objectKey);
182         String ownerId = acl.getOwner().getId();
183
184         assertEquals(acl.getGrants().size(), 1);
185         assertTrue(acl.hasPermission(ownerId, Permission.FULL_CONTROL));
186
187         addGrantsToACL(acl);
188         assertEquals(acl.getGrants().size(), 4);
189         assertTrue(getApi().putObjectACL(containerName, objectKey, acl));
190
191         // Confirm that the updated ACL has stuck.
192         acl = getApi().getObjectACL(containerName, objectKey);
193         checkGrants(acl);
194
195         /*
196          * Revoke all of owner's permissions!
197          */
198         acl.revokeAllPermissions(new CanonicalUserGrantee(ownerId));
199         if (!ownerId.equals(TEST_ACL_ID))
200            acl.revokeAllPermissions(new CanonicalUserGrantee(TEST_ACL_ID));
201         assertEquals(acl.getGrants().size(), 1);
202         // Only public read permission should remain...
203         assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ));
204
205         // Update the object's ACL settings
206         assertTrue(getApi().putObjectACL(containerName, objectKey, acl));
207
208         // Confirm that the updated ACL has stuck
209         acl = getApi().getObjectACL(containerName, objectKey);
210         assertEquals(acl.getGrants().size(), 1);
211         assertEquals(acl.getPermissions(ownerId).size(), 0);
212         assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ), acl.toString());
213      } finally {
214         returnContainer(containerName);
215      }
216
217   }
218
219   public void testPrivateAclIsDefaultForObject() throws InterruptedException, ExecutionException, TimeoutException,
220            IOException {
221      String privateObjectKey = "private-acl";
222      String containerName = getContainerName();
223      try {
224         // Private object
225         addBlobToContainer(containerName, privateObjectKey);
226         AccessControlList acl = getApi().getObjectACL(containerName, privateObjectKey);
227
228         assertEquals(acl.getGrants().size(), 1);
229         assertTrue(acl.getOwner() != null);
230         String ownerId = acl.getOwner().getId();
231         assertTrue(acl.hasPermission(ownerId, Permission.FULL_CONTROL));
232      } finally {
233         returnContainer(containerName);
234      }
235
236   }
237
238   public void testPublicReadOnObject() throws InterruptedException, ExecutionException, TimeoutException, IOException {
239      final String publicReadObjectKey = "public-read-acl";
240      final String containerName = getContainerName();
241      try {
242         S3Object object = getApi().newS3Object();
243         object.getMetadata().setKey(publicReadObjectKey);
244         object.setPayload("");
245         getApi().putObject(containerName, object, new PutObjectOptions().withAcl(CannedAccessPolicy.PUBLIC_READ));
246
247         assertConsistencyAware(new Runnable() {
248            public void run() {
249               try {
250                  AccessControlList acl = getApi().getObjectACL(containerName, publicReadObjectKey);
251
252                  assertEquals(acl.getGrants().size(), 2);
253                  assertEquals(acl.getPermissions(GroupGranteeURI.ALL_USERS).size(), 1);
254                  assertTrue(acl.getOwner() != null);
255                  String ownerId = acl.getOwner().getId();
256                  assertTrue(acl.hasPermission(ownerId, Permission.FULL_CONTROL));
257                  assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ));
258               } catch (Exception e) {
259                  Throwables.propagateIfPossible(e);
260               }
261            }
262         });
263
264      } finally {
265         returnContainer(containerName);
266      }
267
268   }
269
270   protected String addBlobToContainer(String sourceContainer, String key) {
271      S3Object sourceObject = getApi().newS3Object();
272      sourceObject.getMetadata().setKey(key);
273      sourceObject.getMetadata().getContentMetadata().setContentType("text/xml");
274      sourceObject.setPayload(TEST_STRING);
275      return getApi().putObject(sourceContainer, sourceObject);
276   }
277
278   protected S3Object validateObject(String sourceContainer, String key) throws InterruptedException,
279            ExecutionException, TimeoutException, IOException {
280      assertConsistencyAwareContainerSize(sourceContainer, 1);
281      S3Object newObject = getApi().getObject(sourceContainer, key);
282      assert newObject != null;
283      assertEquals(Strings2.toStringAndClose(newObject.getPayload().getInput()), TEST_STRING);
284      return newObject;
285   }
286
287   public void testMetadataWithCacheControlAndContentDisposition() throws Exception {
288      String key = "hello";
289
290      S3Object object = getApi().newS3Object();
291      object.getMetadata().setKey(key);
292      object.setPayload(TEST_STRING);
293      object.getMetadata().setCacheControl("no-cache");
294      object.getMetadata().getContentMetadata().setContentDisposition("attachment; filename=hello.txt");
295      String containerName = getContainerName();
296      try {
297         getApi().putObject(containerName, object);
298
299         S3Object newObject = validateObject(containerName, key);
300         assertCacheControl(newObject, "no-cache");
301         assertEquals(newObject.getMetadata().getContentMetadata().getContentDisposition(),
302                  "attachment; filename=hello.txt");
303      } finally {
304         returnContainer(containerName);
305      }
306   }
307
308   protected void assertCacheControl(S3Object newObject, String string) {
309      assert (newObject.getMetadata().getCacheControl().indexOf(string) != -1) : newObject.getMetadata()
310               .getCacheControl();
311   }
312
313   protected void assertContentEncoding(S3Object newObject, String string) {
314      assert (newObject.getPayload().getContentMetadata().getContentEncoding().indexOf(string) != -1) : newObject
315               .getPayload().getContentMetadata().getContentEncoding();
316      assert (newObject.getMetadata().getContentMetadata().getContentEncoding().indexOf(string) != -1) : newObject
317               .getMetadata().getContentMetadata().getContentEncoding();
318   }
319
320   @Test(groups = { "integration", "live" })
321   public void testMetadataContentEncoding() throws Exception {
322      String key = "hello";
323
324      S3Object object = getApi().newS3Object();
325      object.getMetadata().setKey(key);
326      object.setPayload(TEST_STRING);
327      object.getMetadata().getContentMetadata().setContentEncoding("x-compress");
328      String containerName = getContainerName();
329      try {
330         getApi().putObject(containerName, object);
331         S3Object newObject = validateObject(containerName, key);
332         assertContentEncoding(newObject, "x-compress");
333      } finally {
334         returnContainer(containerName);
335      }
336   }
337
338   public void testCopyObject() throws Exception {
339      String containerName = getContainerName();
340      String destinationContainer = getContainerName();
341
342      try {
343         addToContainerAndValidate(containerName, sourceKey);
344
345         getApi().copyObject(containerName, sourceKey, destinationContainer, destinationKey);
346
347         validateContent(destinationContainer, destinationKey);
348      } finally {
349         returnContainer(containerName);
350         returnContainer(destinationContainer);
351
352      }
353   }
354
355   protected String addToContainerAndValidate(String containerName, String sourceKey) throws InterruptedException,
356            ExecutionException, TimeoutException, IOException {
357      String etag = addBlobToContainer(containerName, sourceKey);
358      validateContent(containerName, sourceKey);
359      return etag;
360   }
361
362   // TODO: fails on linux and windows
363   public void testCopyIfModifiedSince() throws InterruptedException, ExecutionException, TimeoutException, IOException {
364      String containerName = getContainerName();
365      String destinationContainer = getContainerName();
366      try {
367         Date before = new Date();
368         addToContainerAndValidate(containerName, sourceKey + "mod");
369         Date after = new Date(System.currentTimeMillis() + 1000);
370
371         getApi().copyObject(containerName, sourceKey + "mod", destinationContainer, destinationKey,
372                  ifSourceModifiedSince(before));
373         validateContent(destinationContainer, destinationKey);
374
375         try {
376            getApi().copyObject(containerName, sourceKey + "mod", destinationContainer, destinationKey,
377                     ifSourceModifiedSince(after));
378         } catch (HttpResponseException ex) {
379            assertEquals(ex.getResponse().getStatusCode(), 412);
380         }
381      } finally {
382         returnContainer(containerName);
383         returnContainer(destinationContainer);
384
385      }
386   }
387
388   // TODO: fails on linux and windows
389   public void testCopyIfUnmodifiedSince() throws InterruptedException, ExecutionException, TimeoutException,
390            IOException {
391      String containerName = getContainerName();
392      String destinationContainer = getContainerName();
393      try {
394         Date before = new Date();
395         addToContainerAndValidate(containerName, sourceKey + "un");
396         Date after = new Date(System.currentTimeMillis() + 1000);
397
398         getApi().copyObject(containerName, sourceKey + "un", destinationContainer, destinationKey,
399                  ifSourceUnmodifiedSince(after));
400         validateContent(destinationContainer, destinationKey);
401
402         try {
403            getApi().copyObject(containerName, sourceKey + "un", destinationContainer, destinationKey,
404                     ifSourceModifiedSince(before));
405         } catch (HttpResponseException ex) {
406            assertEquals(ex.getResponse().getStatusCode(), 412);
407         }
408      } finally {
409         returnContainer(containerName);
410         returnContainer(destinationContainer);
411      }
412   }
413
414   public void testCopyIfMatch() throws InterruptedException, ExecutionException, TimeoutException, IOException {
415      String containerName = getContainerName();
416      String destinationContainer = getContainerName();
417      try {
418         String goodETag = addToContainerAndValidate(containerName, sourceKey);
419
420         getApi().copyObject(containerName, sourceKey, destinationContainer, destinationKey,
421                  ifSourceETagMatches(goodETag));
422         validateContent(destinationContainer, destinationKey);
423
424         try {
425            getApi().copyObject(containerName, sourceKey, destinationContainer, destinationKey,
426                     ifSourceETagMatches("setsds"));
427         } catch (HttpResponseException ex) {
428            assertEquals(ex.getResponse().getStatusCode(), 412);
429         }
430      } finally {
431         returnContainer(containerName);
432         returnContainer(destinationContainer);
433      }
434   }
435
436   public void testCopyIfNoneMatch() throws IOException, InterruptedException, ExecutionException, TimeoutException {
437      String containerName = getContainerName();
438      String destinationContainer = getContainerName();
439      try {
440         String goodETag = addToContainerAndValidate(containerName, sourceKey);
441
442         getApi().copyObject(containerName, sourceKey, destinationContainer, destinationKey,
443                  ifSourceETagDoesntMatch("asfasdf"));
444         validateContent(destinationContainer, destinationKey);
445
446         try {
447            getApi().copyObject(containerName, sourceKey, destinationContainer, destinationKey,
448                     ifSourceETagDoesntMatch(goodETag));
449         } catch (HttpResponseException ex) {
450            assertEquals(ex.getResponse().getStatusCode(), 412);
451         }
452      } finally {
453         returnContainer(containerName);
454         returnContainer(destinationContainer);
455      }
456   }
457
458   public void testCopyWithMetadata() throws InterruptedException, ExecutionException, TimeoutException, IOException {
459      String containerName = getContainerName();
460      String destinationContainer = getContainerName();
461      try {
462         addToContainerAndValidate(containerName, sourceKey);
463
464         Map<String, String> metadata = Maps.newHashMap();
465         metadata.put("adrian", "cole");
466
467         getApi().copyObject(containerName, sourceKey, destinationContainer, destinationKey,
468                  overrideMetadataWith(metadata));
469
470         validateContent(destinationContainer, destinationKey);
471
472         ObjectMetadata objectMeta = getApi().headObject(destinationContainer, destinationKey);
473
474         assertEquals(objectMeta.getUserMetadata(), metadata);
475      } finally {
476         returnContainer(containerName);
477         returnContainer(destinationContainer);
478
479      }
480   }
481
482   private void checkGrants(AccessControlList acl) {
483      String ownerId = acl.getOwner().getId();
484
485      assertEquals(acl.getGrants().size(), 4, acl.toString());
486
487      assertTrue(acl.hasPermission(ownerId, Permission.FULL_CONTROL), acl.toString());
488      assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ), acl.toString());
489      assertTrue(acl.hasPermission(ownerId, Permission.WRITE_ACP), acl.toString());
490      // EmailAddressGrantee is replaced by a CanonicalUserGrantee, so we cannot test by email addr
491      assertTrue(acl.hasPermission(TEST_ACL_ID, Permission.READ_ACP), acl.toString());
492   }
493
494   private void addGrantsToACL(AccessControlList acl) {
495      String ownerId = acl.getOwner().getId();
496      acl.addPermission(GroupGranteeURI.ALL_USERS, Permission.READ);
497      acl.addPermission(new EmailAddressGrantee(TEST_ACL_EMAIL), Permission.READ_ACP);
498      acl.addPermission(new CanonicalUserGrantee(ownerId), Permission.WRITE_ACP);
499   }
500
501}