diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/BlobContract.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/BlobContract.java index b3dbc962f0f5a..367d3b311d935 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/BlobContract.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/BlobContract.java @@ -24,10 +24,12 @@ import com.microsoft.windowsazure.services.blob.models.CommitBlobBlocksOptions; import com.microsoft.windowsazure.services.blob.models.ContainerACL; import com.microsoft.windowsazure.services.blob.models.CopyBlobOptions; +import com.microsoft.windowsazure.services.blob.models.CopyBlobResult; import com.microsoft.windowsazure.services.blob.models.CreateBlobBlockOptions; import com.microsoft.windowsazure.services.blob.models.CreateBlobOptions; import com.microsoft.windowsazure.services.blob.models.CreateBlobPagesOptions; import com.microsoft.windowsazure.services.blob.models.CreateBlobPagesResult; +import com.microsoft.windowsazure.services.blob.models.CreateBlobResult; import com.microsoft.windowsazure.services.blob.models.CreateBlobSnapshotOptions; import com.microsoft.windowsazure.services.blob.models.CreateBlobSnapshotResult; import com.microsoft.windowsazure.services.blob.models.CreateContainerOptions; @@ -429,7 +431,7 @@ void setContainerMetadata(String container, HashMap metadata, Se * @throws ServiceException * if an error occurs accessing the storage service. */ - void createPageBlob(String container, String blob, long length) throws ServiceException; + CreateBlobResult createPageBlob(String container, String blob, long length) throws ServiceException; /** * Creates a page blob of the specified maximum length, using the specified options. @@ -457,7 +459,8 @@ void setContainerMetadata(String container, HashMap metadata, Se * @throws ServiceException * if an error occurs accessing the storage service. */ - void createPageBlob(String container, String blob, long length, CreateBlobOptions options) throws ServiceException; + CreateBlobResult createPageBlob(String container, String blob, long length, CreateBlobOptions options) + throws ServiceException; /** * Creates a block blob from a content stream. @@ -473,7 +476,7 @@ void setContainerMetadata(String container, HashMap metadata, Se * @throws ServiceException * if an error occurs accessing the storage service. */ - void createBlockBlob(String container, String blob, InputStream contentStream) throws ServiceException; + CreateBlobResult createBlockBlob(String container, String blob, InputStream contentStream) throws ServiceException; /** * Creates a block blob from a content stream, using the specified options. @@ -495,7 +498,7 @@ void setContainerMetadata(String container, HashMap metadata, Se * @throws ServiceException * if an error occurs accessing the storage service. */ - void createBlockBlob(String container, String blob, InputStream contentStream, CreateBlobOptions options) + CreateBlobResult createBlockBlob(String container, String blob, InputStream contentStream, CreateBlobOptions options) throws ServiceException; /** @@ -1214,8 +1217,8 @@ CreateBlobSnapshotResult createBlobSnapshot(String container, String blob, Creat * @throws ServiceException * if an error occurs accessing the storage service. */ - void copyBlob(String destinationContainer, String destinationBlob, String sourceContainer, String sourceBlob) - throws ServiceException; + CopyBlobResult copyBlob(String destinationContainer, String destinationBlob, String sourceContainer, + String sourceBlob) throws ServiceException; /** * Copies a source blob to a destination within the storage account, using the specified options. @@ -1293,8 +1296,8 @@ void copyBlob(String destinationContainer, String destinationBlob, String source * @throws ServiceException * if an error occurs accessing the storage service. */ - void copyBlob(String destinationContainer, String destinationBlob, String sourceContainer, String sourceBlob, - CopyBlobOptions options) throws ServiceException; + CopyBlobResult copyBlob(String destinationContainer, String destinationBlob, String sourceContainer, + String sourceBlob, CopyBlobOptions options) throws ServiceException; /** * Gets a new lease on a blob. diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/implementation/BlobExceptionProcessor.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/implementation/BlobExceptionProcessor.java index fea8798af1097..157dbd9737cb8 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/implementation/BlobExceptionProcessor.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/implementation/BlobExceptionProcessor.java @@ -30,10 +30,12 @@ import com.microsoft.windowsazure.services.blob.models.CommitBlobBlocksOptions; import com.microsoft.windowsazure.services.blob.models.ContainerACL; import com.microsoft.windowsazure.services.blob.models.CopyBlobOptions; +import com.microsoft.windowsazure.services.blob.models.CopyBlobResult; import com.microsoft.windowsazure.services.blob.models.CreateBlobBlockOptions; import com.microsoft.windowsazure.services.blob.models.CreateBlobOptions; import com.microsoft.windowsazure.services.blob.models.CreateBlobPagesOptions; import com.microsoft.windowsazure.services.blob.models.CreateBlobPagesResult; +import com.microsoft.windowsazure.services.blob.models.CreateBlobResult; import com.microsoft.windowsazure.services.blob.models.CreateBlobSnapshotOptions; import com.microsoft.windowsazure.services.blob.models.CreateBlobSnapshotResult; import com.microsoft.windowsazure.services.blob.models.CreateContainerOptions; @@ -383,9 +385,9 @@ public ListBlobsResult listBlobs(String container, ListBlobsOptions options) thr } @Override - public void createPageBlob(String container, String blob, long length) throws ServiceException { + public CreateBlobResult createPageBlob(String container, String blob, long length) throws ServiceException { try { - service.createPageBlob(container, blob, length); + return service.createPageBlob(container, blob, length); } catch (UniformInterfaceException e) { throw processCatch(new ServiceException(e)); @@ -396,10 +398,10 @@ public void createPageBlob(String container, String blob, long length) throws Se } @Override - public void createPageBlob(String container, String blob, long length, CreateBlobOptions options) + public CreateBlobResult createPageBlob(String container, String blob, long length, CreateBlobOptions options) throws ServiceException { try { - service.createPageBlob(container, blob, length, options); + return service.createPageBlob(container, blob, length, options); } catch (UniformInterfaceException e) { throw processCatch(new ServiceException(e)); @@ -410,9 +412,10 @@ public void createPageBlob(String container, String blob, long length, CreateBlo } @Override - public void createBlockBlob(String container, String blob, InputStream contentStream) throws ServiceException { + public CreateBlobResult createBlockBlob(String container, String blob, InputStream contentStream) + throws ServiceException { try { - service.createBlockBlob(container, blob, contentStream); + return service.createBlockBlob(container, blob, contentStream); } catch (UniformInterfaceException e) { throw processCatch(new ServiceException(e)); @@ -423,10 +426,10 @@ public void createBlockBlob(String container, String blob, InputStream contentSt } @Override - public void createBlockBlob(String container, String blob, InputStream contentStream, CreateBlobOptions options) - throws ServiceException { + public CreateBlobResult createBlockBlob(String container, String blob, InputStream contentStream, + CreateBlobOptions options) throws ServiceException { try { - service.createBlockBlob(container, blob, contentStream, options); + return service.createBlockBlob(container, blob, contentStream, options); } catch (UniformInterfaceException e) { throw processCatch(new ServiceException(e)); @@ -776,10 +779,10 @@ public CreateBlobSnapshotResult createBlobSnapshot(String container, String blob } @Override - public void copyBlob(String destinationContainer, String destinationBlob, String sourceContainer, String sourceBlob) - throws ServiceException { + public CopyBlobResult copyBlob(String destinationContainer, String destinationBlob, String sourceContainer, + String sourceBlob) throws ServiceException { try { - service.copyBlob(destinationContainer, destinationBlob, sourceContainer, sourceBlob); + return service.copyBlob(destinationContainer, destinationBlob, sourceContainer, sourceBlob); } catch (UniformInterfaceException e) { throw processCatch(new ServiceException(e)); @@ -790,10 +793,10 @@ public void copyBlob(String destinationContainer, String destinationBlob, String } @Override - public void copyBlob(String destinationContainer, String destinationBlob, String sourceContainer, + public CopyBlobResult copyBlob(String destinationContainer, String destinationBlob, String sourceContainer, String sourceBlob, CopyBlobOptions options) throws ServiceException { try { - service.copyBlob(destinationContainer, destinationBlob, sourceContainer, sourceBlob, options); + return service.copyBlob(destinationContainer, destinationBlob, sourceContainer, sourceBlob, options); } catch (UniformInterfaceException e) { throw processCatch(new ServiceException(e)); diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/implementation/BlobRestProxy.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/implementation/BlobRestProxy.java index acfd07282a96d..1366704cf2d81 100644 --- a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/implementation/BlobRestProxy.java +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/implementation/BlobRestProxy.java @@ -34,10 +34,12 @@ import com.microsoft.windowsazure.services.blob.models.ContainerACL; import com.microsoft.windowsazure.services.blob.models.ContainerACL.PublicAccessType; import com.microsoft.windowsazure.services.blob.models.CopyBlobOptions; +import com.microsoft.windowsazure.services.blob.models.CopyBlobResult; import com.microsoft.windowsazure.services.blob.models.CreateBlobBlockOptions; import com.microsoft.windowsazure.services.blob.models.CreateBlobOptions; import com.microsoft.windowsazure.services.blob.models.CreateBlobPagesOptions; import com.microsoft.windowsazure.services.blob.models.CreateBlobPagesResult; +import com.microsoft.windowsazure.services.blob.models.CreateBlobResult; import com.microsoft.windowsazure.services.blob.models.CreateBlobSnapshotOptions; import com.microsoft.windowsazure.services.blob.models.CreateBlobSnapshotResult; import com.microsoft.windowsazure.services.blob.models.CreateContainerOptions; @@ -488,12 +490,12 @@ public ListBlobsResult listBlobs(String container, ListBlobsOptions options) thr } @Override - public void createPageBlob(String container, String blob, long length) throws ServiceException { - createPageBlob(container, blob, length, new CreateBlobOptions()); + public CreateBlobResult createPageBlob(String container, String blob, long length) throws ServiceException { + return createPageBlob(container, blob, length, new CreateBlobOptions()); } @Override - public void createPageBlob(String container, String blob, long length, CreateBlobOptions options) + public CreateBlobResult createPageBlob(String container, String blob, long length, CreateBlobOptions options) throws ServiceException { String path = createPathFromContainer(container); WebResource webResource = getResource(options).path(path).path(blob); @@ -505,17 +507,25 @@ public void createPageBlob(String container, String blob, long length, CreateBlo builder = addOptionalHeader(builder, "x-ms-blob-sequence-number", options.getSequenceNumber()); builder = addPutBlobHeaders(options, builder); - builder.put(); + ClientResponse clientResponse = builder.put(ClientResponse.class); + ThrowIfError(clientResponse); + + CreateBlobResult createBlobResult = new CreateBlobResult(); + createBlobResult.setEtag(clientResponse.getHeaders().getFirst("ETag")); + createBlobResult.setLastModified(dateMapper.parse(clientResponse.getHeaders().getFirst("Last-Modified"))); + + return createBlobResult; } @Override - public void createBlockBlob(String container, String blob, InputStream contentStream) throws ServiceException { - createBlockBlob(container, blob, contentStream, new CreateBlobOptions()); + public CreateBlobResult createBlockBlob(String container, String blob, InputStream contentStream) + throws ServiceException { + return createBlockBlob(container, blob, contentStream, new CreateBlobOptions()); } @Override - public void createBlockBlob(String container, String blob, InputStream contentStream, CreateBlobOptions options) - throws ServiceException { + public CreateBlobResult createBlockBlob(String container, String blob, InputStream contentStream, + CreateBlobOptions options) throws ServiceException { String path = createPathFromContainer(container); System.out.println(path); WebResource webResource = getResource(options).path(path).path(blob); @@ -526,7 +536,14 @@ public void createBlockBlob(String container, String blob, InputStream contentSt builder = addPutBlobHeaders(options, builder); Object contentObject = (contentStream == null ? new byte[0] : contentStream); - builder.put(contentObject); + ClientResponse clientResponse = builder.put(ClientResponse.class, contentObject); + ThrowIfError(clientResponse); + + CreateBlobResult createBlobResult = new CreateBlobResult(); + createBlobResult.setEtag(clientResponse.getHeaders().getFirst("ETag")); + createBlobResult.setLastModified(dateMapper.parse(clientResponse.getHeaders().getFirst("Last-Modified"))); + + return createBlobResult; } @Override @@ -651,6 +668,9 @@ public GetBlobResult getBlob(String container, String blob, GetBlobOptions optio builder = addOptionalHeader(builder, "x-ms-lease-id", options.getLeaseId()); builder = addOptionalRangeHeader(builder, options.getRangeStart(), options.getRangeEnd()); builder = addOptionalAccessConditionHeader(builder, options.getAccessCondition()); + if (options.isComputeRangeMD5()) { + builder = addOptionalHeader(builder, "x-ms-range-get-content-md5", "true"); + } ClientResponse response = builder.get(ClientResponse.class); ThrowIfNotSuccess(response); @@ -713,13 +733,13 @@ public CreateBlobSnapshotResult createBlobSnapshot(String container, String blob } @Override - public void copyBlob(String destinationContainer, String destinationBlob, String sourceContainer, String sourceBlob) - throws ServiceException { - copyBlob(destinationContainer, destinationBlob, sourceContainer, sourceBlob, new CopyBlobOptions()); + public CopyBlobResult copyBlob(String destinationContainer, String destinationBlob, String sourceContainer, + String sourceBlob) throws ServiceException { + return copyBlob(destinationContainer, destinationBlob, sourceContainer, sourceBlob, new CopyBlobOptions()); } @Override - public void copyBlob(String destinationContainer, String destinationBlob, String sourceContainer, + public CopyBlobResult copyBlob(String destinationContainer, String destinationBlob, String sourceContainer, String sourceBlob, CopyBlobOptions options) { String path = createPathFromContainer(destinationContainer); WebResource webResource = getResource(options).path(path).path(destinationBlob); @@ -733,7 +753,14 @@ public void copyBlob(String destinationContainer, String destinationBlob, String builder = addOptionalAccessConditionHeader(builder, options.getAccessCondition()); builder = addOptionalSourceAccessConditionHeader(builder, options.getSourceAccessCondition()); - builder.put(); + ClientResponse clientResponse = builder.put(ClientResponse.class); + ThrowIfError(clientResponse); + + CopyBlobResult copyBlobResult = new CopyBlobResult(); + copyBlobResult.setEtag(clientResponse.getHeaders().getFirst("ETag")); + copyBlobResult.setLastModified(dateMapper.parse(clientResponse.getHeaders().getFirst("Last-Modified"))); + + return copyBlobResult; } @Override diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/CopyBlobResult.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/CopyBlobResult.java new file mode 100644 index 0000000000000..d8dd1b665847d --- /dev/null +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/CopyBlobResult.java @@ -0,0 +1,80 @@ +/** + * Copyright 2011 Microsoft Corporation + * + * Licensed 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 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 com.microsoft.windowsazure.services.blob.models; + +import java.util.Date; + +import com.microsoft.windowsazure.services.blob.BlobContract; + +/** + * A wrapper class for the response returned from a Blob Service REST API Copy Blob operation. This is returned by calls + * to implementations of {@link BlobContract#copyBlob(String, String, String, String, CopyBlobOptions)}. + *

+ * See the Copy Blob documentation on + * MSDN for details of the underlying Blob Service REST API operation. + */ +public class CopyBlobResult { + private String etag; + private Date lastModified; + + /** + * Gets the ETag of the blob. + * + * @return + * A {@link String} containing the server-assigned ETag value for the copy blob. + */ + public String getEtag() { + return etag; + } + + /** + * Sets the ETag of the blob from the ETag header returned in the + * response. + *

+ * This method is invoked by the API to set the value from the Blob Service REST API operation response returned by + * the server. + * + * @param etag + * A {@link String} containing the server-assigned ETag value for the blob. + */ + public void setEtag(String etag) { + this.etag = etag; + } + + /** + * Gets the last modified time of the blob. + *

+ * + * @return + * A {@link java.util.Date} containing the last modified time of the blob. + */ + public Date getLastModified() { + return lastModified; + } + + /** + * Sets the last modified time of the blob from the Last-Modified header + * returned in the response. + *

+ * This method is invoked by the API to set the value from the Blob Service REST API operation response returned by + * the server. + * + * @param lastModified + * A {@link java.util.Date} containing the last modified time of the blob. + */ + public void setLastModified(Date lastModified) { + this.lastModified = lastModified; + } +} diff --git a/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/CreateBlobResult.java b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/CreateBlobResult.java new file mode 100644 index 0000000000000..4ab963e269006 --- /dev/null +++ b/microsoft-azure-api/src/main/java/com/microsoft/windowsazure/services/blob/models/CreateBlobResult.java @@ -0,0 +1,80 @@ +/** + * Copyright 2011 Microsoft Corporation + * + * Licensed 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 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 com.microsoft.windowsazure.services.blob.models; + +import java.util.Date; + +import com.microsoft.windowsazure.services.blob.BlobContract; + +/** + * A wrapper class for the response returned from a Blob Service REST API Create Blob operation. This is returned by + * calls to implementations of {@link BlobContract#createPageBlob(String, String, long, CreateBlobOptions)} and + * {@link BlobContract#createBlockBlob(String, String, long, CreateBlobOptions)}. + *

+ * See the Put Blob documentation on + * MSDN for details of the underlying Blob Service REST API operation. + */ +public class CreateBlobResult { + private String etag; + private Date lastModified; + + /** + * Gets the ETag of the blob. + * + * @return + * A {@link String} containing the server-assigned ETag value for the snapshot. + */ + public String getEtag() { + return etag; + } + + /** + * Sets the ETag of the snapshot from the ETag header returned in the + * response. + *

+ * This method is invoked by the API to set the value from the Blob Service REST API operation response returned by + * the server. + * + * @param etag + * A {@link String} containing the server-assigned ETag value for the blob. + */ + public void setEtag(String etag) { + this.etag = etag; + } + + /** + * Gets the last modified time of the snapshot. + * + * @return + * A {@link java.util.Date} containing the last modified time of the blob. + */ + public Date getLastModified() { + return lastModified; + } + + /** + * Reserved for internal use. Sets the last modified time of the snapshot from the Last-Modified header + * returned in the response. + *

+ * This method is invoked by the API to set the value from the Blob Service REST API operation response returned by + * the server. + * + * @param lastModified + * A {@link java.util.Date} containing the last modified time of the snapshot. + */ + public void setLastModified(Date lastModified) { + this.lastModified = lastModified; + } +} diff --git a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/BlobServiceIntegrationTest.java b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/BlobServiceIntegrationTest.java index a72111d7853b6..28e5d990ec7ce 100644 --- a/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/BlobServiceIntegrationTest.java +++ b/microsoft-azure-api/src/test/java/com/microsoft/windowsazure/services/blob/BlobServiceIntegrationTest.java @@ -44,8 +44,10 @@ import com.microsoft.windowsazure.services.blob.models.BlockList; import com.microsoft.windowsazure.services.blob.models.ContainerACL; import com.microsoft.windowsazure.services.blob.models.ContainerACL.PublicAccessType; +import com.microsoft.windowsazure.services.blob.models.CopyBlobResult; import com.microsoft.windowsazure.services.blob.models.CreateBlobOptions; import com.microsoft.windowsazure.services.blob.models.CreateBlobPagesResult; +import com.microsoft.windowsazure.services.blob.models.CreateBlobResult; import com.microsoft.windowsazure.services.blob.models.CreateBlobSnapshotOptions; import com.microsoft.windowsazure.services.blob.models.CreateBlobSnapshotResult; import com.microsoft.windowsazure.services.blob.models.CreateContainerOptions; @@ -660,6 +662,20 @@ public void createPageBlobWorks() throws Exception { // Assert } + @Test + public void createPageBlobWithETagSuccess() throws Exception { + // Arrange + Configuration config = createConfiguration(); + BlobContract service = BlobService.create(config); + + // Act + CreateBlobResult createBlobResult = service.createPageBlob(TEST_CONTAINER_FOR_BLOBS, "test", 512); + + // Assert + assertNotNull(createBlobResult); + assertNotNull(createBlobResult.getEtag()); + } + @Test public void createPageBlobWithOptionsWorks() throws Exception { // Arrange @@ -971,6 +987,21 @@ public void createBlockBlobWorks() throws Exception { // Assert } + @Test + public void createBlockBlobWithValidEtag() throws Exception { + // Arrange + Configuration config = createConfiguration(); + BlobContract service = BlobService.create(config); + + // Act + CreateBlobResult createBlobResult = service.createBlockBlob(TEST_CONTAINER_FOR_BLOBS, "test2", + new ByteArrayInputStream("some content".getBytes())); + + // Assert + assertNotNull(createBlobResult); + assertNotNull(createBlobResult.getEtag()); + } + @Test public void createBlockBlobWithOptionsWorks() throws Exception { // Arrange @@ -1226,6 +1257,32 @@ public void getBlobWithIfNotModifiedSinceAccessConditionWorks() throws Exception // Assert } + @Test + public void getBlobWithMD5Range() throws Exception { + // Arrange + Configuration config = createConfiguration(); + BlobContract service = BlobService.create(config); + String expectedMd5 = "+zxkkqBt6HehE3r5suhS1w=="; + + // Act + String container = TEST_CONTAINER_FOR_BLOBS; + String blob = "test"; + service.createPageBlob(container, blob, 4096); + + GetBlobOptions options = new GetBlobOptions(); + options = options.setRangeStart(50L); + options = options.setRangeEnd(200L); + options = options.setComputeRangeMD5(true); + GetBlobResult getBlobResult = service.getBlob(container, blob, options); + + // Assert + assertNotNull(getBlobResult); + BlobProperties blobProperties = getBlobResult.getProperties(); + String actualMd5 = blobProperties.getContentMD5(); + assertEquals(expectedMd5, actualMd5); + + } + @Test public void getBlobPropertiesWorks() throws Exception { // Arrange @@ -1445,6 +1502,29 @@ public void copyBlobWorks() throws Exception { assertEquals(content, inputStreamToString(result.getContentStream(), "UTF-8")); } + @Test + public void copyBlobGetEtagSuccess() throws Exception { + // Arrange + Configuration config = createConfiguration(); + BlobContract service = BlobService.create(config); + String sourceBlobName = "copyblobgetetagsuccesssource"; + String targetBlobName = "copyblobgetetagsuccesstarget"; + + //Act + String content = "some content2"; + service.createBlockBlob(TEST_CONTAINER_FOR_BLOBS, sourceBlobName, + new ByteArrayInputStream(content.getBytes("UTF-8"))); + CopyBlobResult copyBlobResult = service.copyBlob(TEST_CONTAINER_FOR_BLOBS_2, targetBlobName, + TEST_CONTAINER_FOR_BLOBS, sourceBlobName); + + GetBlobResult result = service.getBlob(TEST_CONTAINER_FOR_BLOBS_2, targetBlobName); + + // Assert + assertNotNull(result); + assertEquals(copyBlobResult.getEtag(), result.getProperties().getEtag()); + + } + @Test public void acquireLeaseWorks() throws Exception { // Arrange