@Override @Test(groups = {"integration", "live"}) public void testEntrySet() throws IOException, InterruptedException { String bucketName = getContainerName(); try { final BlobMap map = createMap(context, bucketName); putFiveStrings(map); assertConsistencyAwareMapSize(map, 5); Set<Entry<String, Blob>> entries = map.entrySet(); assertEquals(entries.size(), 5); for (Entry<String, Blob> entry : entries) { assertEquals( fiveStrings.get(entry.getKey()), getContentAsStringOrNullAndClose(entry.getValue())); Blob blob = entry.getValue(); blob.setPayload(""); Payloads.calculateMD5(blob); entry.setValue(blob); } assertConsistencyAware( new Runnable() { public void run() { for (Blob blob : map.values()) { try { assertEquals(getContentAsStringOrNullAndClose(blob), ""); } catch (IOException e) { Throwables.propagate(e); } } } }); } finally { returnContainer(bucketName); } }
@Override protected void putStringWithMD5(Map<String, Blob> map, String key, String text) throws IOException { Blob blob = context.getBlobStore().newBlob(key); blob.setPayload(text); Payloads.calculateMD5(blob); map.put(key, blob); }
protected SwiftObject newSwiftObject(String data, String key) throws IOException { SwiftObject object = getApi().newSwiftObject(); object.getInfo().setName(key); object.setPayload(data); Payloads.calculateMD5(object); object.getInfo().setContentType("text/plain"); object.getInfo().getMetadata().put("Metadata", "metadata-value"); return object; }
@Test(groups = {"integration", "live"}) public void testPut() throws IOException, InterruptedException { String bucketName = getContainerName(); try { Map<String, Blob> map = createMap(context, bucketName); Blob blob = context.getBlobStore().newBlob("one"); blob.setPayload(Strings2.toInputStream("apple")); Payloads.calculateMD5(blob); Blob old = map.put(blob.getMetadata().getName(), blob); getOneReturnsAppleAndOldValueIsNull(map, old); blob.setPayload(Strings2.toInputStream("bear")); Payloads.calculateMD5(blob); Blob apple = map.put(blob.getMetadata().getName(), blob); getOneReturnsBearAndOldValueIsApple(map, apple); } finally { returnContainer(bucketName); } }
/** * Calculates the object MD5 and returns it as eTag * * @param object * @return */ private String getEtag(Blob object) { try { Payloads.calculateMD5(object, crypto.md5()); } catch (IOException ex) { logger.error( ex, "An error occurred calculating MD5 for object with name %s.", object.getMetadata().getName()); Throwables.propagate(ex); } String eTag = CryptoStreams.hex(object.getPayload().getContentMetadata().getContentMD5()); return eTag; }
@Test(groups = {"integration", "live"}) public void testContains() throws InterruptedException, ExecutionException, TimeoutException, IOException { String bucketName = getContainerName(); try { Map<String, Blob> map = createMap(context, bucketName); putStringWithMD5(map, "one", "apple"); Blob blob = context.getBlobStore().newBlob("one"); blob.setPayload("apple"); Payloads.calculateMD5(blob); assertConsistencyAwareContainsValue(map, blob); } finally { returnContainer(bucketName); } }
@Test( timeOut = 5 * 60 * 1000, dependsOnMethods = {"testCreateContainer", "testCreatePublicContainer"}) public void testObjectOperations() throws Exception { String data = "Here is my data"; // Test PUT with string data, ETag hash, and a piece of metadata AzureBlob object = client.newBlob(); object.getProperties().setName("object"); object.setPayload(data); Payloads.calculateMD5(object); object.getProperties().getContentMetadata().setContentType("text/plain"); object.getProperties().getMetadata().put("mykey", "metadata-value"); byte[] md5 = object.getProperties().getContentMetadata().getContentMD5(); String newEtag = client.putBlob(privateContainer, object); assertEquals( CryptoStreams.hex(md5), CryptoStreams.hex(object.getProperties().getContentMetadata().getContentMD5())); // Test HEAD of missing object assert client.getBlobProperties(privateContainer, "non-existent-object") == null; // Test HEAD of object BlobProperties metadata = client.getBlobProperties(privateContainer, object.getProperties().getName()); // TODO assertEquals(metadata.getName(), object.getProperties().getName()); // we can't check this while hacking around lack of content-md5, as GET of the first byte will // show incorrect length 1, the returned size, as opposed to the real length. This is an ok // tradeoff, as a container list will contain the correct size of the objects in an // inexpensive fashion // http://code.google.com/p/jclouds/issues/detail?id=92 // assertEquals(metadata.getSize(), data.length()); assertEquals(metadata.getContentMetadata().getContentType(), "text/plain"); // Azure doesn't return the Content-MD5 on head request.. assertEquals( CryptoStreams.hex(md5), CryptoStreams.hex(object.getProperties().getContentMetadata().getContentMD5())); assertEquals(metadata.getETag(), newEtag); assertEquals(metadata.getMetadata().entrySet().size(), 1); assertEquals(metadata.getMetadata().get("mykey"), "metadata-value"); // // Test POST to update object's metadata // Multimap<String, String> userMetadata = LinkedHashMultimap.create(); // userMetadata.put("New-Metadata-1", "value-1"); // userMetadata.put("New-Metadata-2", "value-2"); // assertTrue(client.setBlobProperties(privateContainer, object.getProperties().getName(), // userMetadata)); // Test GET of missing object assert client.getBlob(privateContainer, "non-existent-object") == null; // Test GET of object (including updated metadata) AzureBlob getBlob = client.getBlob(privateContainer, object.getProperties().getName()); assertEquals(Utils.toStringAndClose(getBlob.getPayload().getInput()), data); // TODO assertEquals(getBlob.getName(), object.getProperties().getName()); assertEquals( getBlob.getPayload().getContentMetadata().getContentLength(), new Long(data.length())); assertEquals(getBlob.getProperties().getContentMetadata().getContentType(), "text/plain"); assertEquals( CryptoStreams.hex(md5), CryptoStreams.hex(getBlob.getProperties().getContentMetadata().getContentMD5())); assertEquals(newEtag, getBlob.getProperties().getETag()); // wait until we can update metadata // assertEquals(getBlob.getProperties().getMetadata().entries().size(), 2); // assertEquals( // Iterables.getLast(getBlob.getProperties().getMetadata().get("New-Metadata-1")), // "value-1"); // assertEquals( // Iterables.getLast(getBlob.getProperties().getMetadata().get("New-Metadata-2")), // "value-2"); assertEquals(metadata.getMetadata().entrySet().size(), 1); assertEquals(metadata.getMetadata().get("mykey"), "metadata-value"); // test listing ListBlobsResponse response = client.listBlobs( privateContainer, ListBlobsOptions.Builder.prefix( object .getProperties() .getName() .substring(0, object.getProperties().getName().length() - 1)) .maxResults(1) .includeMetadata()); assertEquals(response.size(), 1); assertEquals(Iterables.getOnlyElement(response).getName(), object.getProperties().getName()); assertEquals( Iterables.getOnlyElement(response).getMetadata(), ImmutableMap.of("mykey", "metadata-value")); // Test PUT with invalid ETag (as if object's data was corrupted in transit) String correctEtag = newEtag; String incorrectEtag = "0" + correctEtag.substring(1); object.getProperties().setETag(incorrectEtag); try { client.putBlob(privateContainer, object); } catch (Throwable e) { assertEquals(e.getCause().getClass(), HttpResponseException.class); assertEquals(((HttpResponseException) e.getCause()).getResponse().getStatusCode(), 422); } ByteArrayInputStream bais = new ByteArrayInputStream(data.getBytes("UTF-8")); object = client.newBlob(); object.getProperties().setName("chunked-object"); object.setPayload(bais); object.getPayload().getContentMetadata().setContentLength(new Long(data.getBytes().length)); newEtag = client.putBlob(privateContainer, object); assertEquals( CryptoStreams.hex(md5), CryptoStreams.hex(getBlob.getProperties().getContentMetadata().getContentMD5())); // Test GET with options // Non-matching ETag try { client.getBlob( privateContainer, object.getProperties().getName(), GetOptions.Builder.ifETagDoesntMatch(newEtag)); } catch (Exception e) { assertEquals(e.getCause().getClass(), HttpResponseException.class); assertEquals(((HttpResponseException) e.getCause()).getResponse().getStatusCode(), 304); } // Matching ETag TODO this shouldn't fail!!! try { getBlob = client.getBlob( privateContainer, object.getProperties().getName(), GetOptions.Builder.ifETagMatches(newEtag)); assertEquals(getBlob.getProperties().getETag(), newEtag); } catch (HttpResponseException e) { assertEquals(e.getResponse().getStatusCode(), 412); } // Range // doesn't work per // http://social.msdn.microsoft.com/Forums/en-US/windowsazure/thread/479fa63f-51df-4b66-96b5-33ae362747b6 // getBlob = client // .getBlob(privateContainer, object.getProperties().getName(), // GetOptions.Builder.startAt(8)).get(120, // TimeUnit.SECONDS); // assertEquals(Utils.toStringAndClose((InputStream) getBlob.getData()), data.substring(8)); client.deleteBlob(privateContainer, "object"); client.deleteBlob(privateContainer, "chunked-object"); }