diff --git a/ChangeLog.txt b/ChangeLog.txt index 2f2e5ff..2798859 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,7 @@ +2017.08.30 Version 1.2.0 + * Fixed a bug when using a SAS token where the token was being omitted from calls to delete a directory in the file service. + * For Standard Storage Accounts only, added the ability to set the tier of individual block blobs. The tier can currently only be set through uploadTier(). + 2017.07.31 Version 1.1.0 * Support for 2017-04-17 REST version. Please see our REST API documentation and blogs for information about the related added features. * For Premium Accounts only, added support for getting and setting the tier on a page blob. The tier can also be set when creating or copying from an existing page blob. diff --git a/README.md b/README.md index 28dc243..8a0cf4b 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ First, add mavenCentral to your repositories by adding the following to your gra Then, add a dependency by adding the following to your gradle build file: dependencies { - compile 'com.microsoft.azure.android:azure-storage-android:1.1.0@aar' + compile 'com.microsoft.azure.android:azure-storage-android:1.2.0@aar' } ### Option 4: aar via Maven @@ -57,7 +57,7 @@ To get the binaries of this library as distributed by Microsoft, ready for use w com.microsoft.azure.android azure-storage-android - 1.1.0 + 1.2.0 aar ``` diff --git a/microsoft-azure-storage-samples/AndroidManifest.xml b/microsoft-azure-storage-samples/AndroidManifest.xml index a902139..7d9e580 100644 --- a/microsoft-azure-storage-samples/AndroidManifest.xml +++ b/microsoft-azure-storage-samples/AndroidManifest.xml @@ -2,7 +2,7 @@ + android:versionName="1.2.0" > + android:versionName="1.2.0" > () { + try { + OperationContext.getGlobalErrorReceivingResponseEventHandler().addListener(new StorageEvent() { - @Override - public void eventOccurred(ErrorReceivingResponseEvent eventArg) { - fail("This event should not trigger"); - } - }); + @Override + public void eventOccurred(ErrorReceivingResponseEvent eventArg) { + fail("This event should not trigger"); + } + }); - assertEquals(0, callList.size()); - assertEquals(0, globalCallList.size()); + assertEquals(0, callList.size()); + assertEquals(0, globalCallList.size()); - CloudBlobClient blobClient = TestHelper.createCloudBlobClient(); - CloudBlobContainer container = blobClient.getContainerReference("container1"); + CloudBlobClient blobClient = TestHelper.createCloudBlobClient(); + CloudBlobContainer container = blobClient.getContainerReference("container1"); - // make sure both update - container.exists(null, null, eventContext); - assertEquals(1, callList.size()); - assertEquals(1, globalCallList.size()); + // make sure both update + container.exists(null, null, eventContext); + assertEquals(1, callList.size()); + assertEquals(1, globalCallList.size()); - // make sure only global updates - container.exists(); - assertEquals(1, callList.size()); - assertEquals(2, globalCallList.size()); + // make sure only global updates + container.exists(); + assertEquals(1, callList.size()); + assertEquals(2, globalCallList.size()); - OperationContext - .setGlobalResponseReceivedEventHandler(new StorageEventMultiCaster>()); - eventContext - .setResponseReceivedEventHandler(new StorageEventMultiCaster>()); + OperationContext + .setGlobalResponseReceivedEventHandler(new StorageEventMultiCaster>()); + eventContext + .setResponseReceivedEventHandler(new StorageEventMultiCaster>()); - // make sure neither update - container.exists(null, null, eventContext); - assertEquals(1, callList.size()); - assertEquals(2, globalCallList.size()); + // make sure neither update + container.exists(null, null, eventContext); + assertEquals(1, callList.size()); + assertEquals(2, globalCallList.size()); + } + finally { + // reset event handler to prevent future tests from failing + OperationContext.setGlobalErrorReceivingResponseEventHandler(new StorageEventMultiCaster>()); + } } @Test diff --git a/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlockBlobTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlockBlobTests.java index b4dd807..1559f76 100644 --- a/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlockBlobTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlockBlobTests.java @@ -53,15 +53,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.security.InvalidKeyException; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.EnumSet; -import java.util.GregorianCalendar; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.TimeZone; +import java.util.*; import static org.junit.Assert.*; @@ -1733,4 +1725,82 @@ private void doCloudBlockBlobCopy(boolean sourceIsSas, boolean destinationIsSas) destination.delete(); source.delete(); } + + @Test + @Category({ DevFabricTests.class, DevStoreTests.class }) + public void testCloudBlockBlobUploadStandardTier() throws StorageException, IOException, URISyntaxException { + for (StandardBlobTier standardBlobTier : StandardBlobTier.values()) { + if (standardBlobTier == StandardBlobTier.UNKNOWN) { + continue; + } + + final String blobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlob"); + final CloudBlockBlob blob = this.container.getBlockBlobReference(blobName); + blob.uploadText("text"); + + blob.uploadStandardBlobTier(standardBlobTier); + assertEquals(standardBlobTier, blob.getProperties().getStandardBlobTier()); + assertNull(blob.getProperties().getPremiumPageBlobTier()); + assertNull(blob.getProperties().getRehydrationStatus()); + + CloudBlockBlob blob2 = this.container.getBlockBlobReference(blobName); + blob2.downloadAttributes(); + assertEquals(standardBlobTier, blob2.getProperties().getStandardBlobTier()); + assertNull(blob2.getProperties().getPremiumPageBlobTier()); + assertNull(blob2.getProperties().getRehydrationStatus()); + + CloudBlockBlob blob3 = (CloudBlockBlob)this.container.listBlobs().iterator().next(); + assertEquals(standardBlobTier, blob3.getProperties().getStandardBlobTier()); + assertNull(blob3.getProperties().getPremiumPageBlobTier()); + assertNull(blob3.getProperties().getRehydrationStatus()); + + blob.deleteIfExists(); + } + } + + @Test + @Category({ DevFabricTests.class, DevStoreTests.class }) + public void testCloudBlockBlobRehydrateBlob() throws StorageException, IOException, URISyntaxException { + final String blobName1 = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlob1"); + final String blobName2 = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlob2"); + final CloudBlockBlob blob = this.container.getBlockBlobReference(blobName1); + blob.uploadText("text"); + blob.uploadStandardBlobTier(StandardBlobTier.ARCHIVE); + final CloudBlockBlob blob2 = this.container.getBlockBlobReference(blobName2); + blob2.uploadText("text"); + blob2.uploadStandardBlobTier(StandardBlobTier.ARCHIVE); + + CloudBlockBlob blobRef1 = this.container.getBlockBlobReference(blobName1); + blobRef1.uploadStandardBlobTier(StandardBlobTier.COOL); + assertNull(blobRef1.getProperties().getRehydrationStatus()); + assertEquals(StandardBlobTier.ARCHIVE, blobRef1.getProperties().getStandardBlobTier()); + assertNull(blobRef1.getProperties().getPremiumPageBlobTier()); + + blob.downloadAttributes(); + assertEquals(RehydrationStatus.PENDING_TO_COOL, blob.getProperties().getRehydrationStatus()); + assertEquals(StandardBlobTier.ARCHIVE, blob.getProperties().getStandardBlobTier()); + assertNull(blob.getProperties().getPremiumPageBlobTier()); + + CloudBlockBlob blobRef2 = this.container.getBlockBlobReference(blobName2); + blobRef2.uploadStandardBlobTier(StandardBlobTier.HOT); + assertNull(blobRef2.getProperties().getRehydrationStatus()); + assertEquals(StandardBlobTier.ARCHIVE, blobRef2.getProperties().getStandardBlobTier()); + assertNull(blobRef2.getProperties().getPremiumPageBlobTier()); + + blob2.downloadAttributes(); + assertEquals(RehydrationStatus.PENDING_TO_HOT, blob2.getProperties().getRehydrationStatus()); + assertEquals(StandardBlobTier.ARCHIVE, blob2.getProperties().getStandardBlobTier()); + assertNull(blob2.getProperties().getPremiumPageBlobTier()); + + Iterator it = this.container.listBlobs().iterator(); + CloudBlockBlob listBlob = (CloudBlockBlob)it.next(); + assertEquals(RehydrationStatus.PENDING_TO_COOL, listBlob.getProperties().getRehydrationStatus()); + assertEquals(StandardBlobTier.ARCHIVE, listBlob.getProperties().getStandardBlobTier()); + assertNull(listBlob.getProperties().getPremiumPageBlobTier()); + + CloudBlockBlob listBlob2 = (CloudBlockBlob)it.next(); + assertEquals(RehydrationStatus.PENDING_TO_HOT, listBlob2.getProperties().getRehydrationStatus()); + assertEquals(StandardBlobTier.ARCHIVE, listBlob2.getProperties().getStandardBlobTier()); + assertNull(listBlob2.getProperties().getPremiumPageBlobTier()); + } } diff --git a/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudPageBlobTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudPageBlobTests.java index 57d4511..aea816b 100644 --- a/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudPageBlobTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudPageBlobTests.java @@ -1242,39 +1242,47 @@ public void testCloudPageBlobSetPremiumBlobTierOnCreate() throws URISyntaxExcept // Test create API CloudPageBlob blob = container.getPageBlobReference(blobName); - assertNull(blob.getProperties().getInferredBlobTier()); + assertNull(blob.getProperties().isBlobTierInferred()); blob.create(1024, PremiumPageBlobTier.P4, null, null, null); assertEquals(PremiumPageBlobTier.P4, blob.getProperties().getPremiumPageBlobTier()); - assertFalse(blob.getProperties().getInferredBlobTier()); + assertFalse(blob.getProperties().isBlobTierInferred()); + assertNull(blob.getProperties().getStandardBlobTier()); + assertNull(blob.getProperties().getRehydrationStatus()); CloudPageBlob blob2 = container.getPageBlobReference(blobName); blob2.downloadAttributes(); assertEquals(PremiumPageBlobTier.P4, blob2.getProperties().getPremiumPageBlobTier()); - assertNull(blob2.getProperties().getInferredBlobTier()); + assertNull(blob2.getProperties().isBlobTierInferred()); + assertNull(blob2.getProperties().getStandardBlobTier()); + assertNull(blob2.getProperties().getRehydrationStatus()); // Test upload from byte array API byte[] buffer = BlobTestHelper.getRandomBuffer(1024); CloudPageBlob blob3 = container.getPageBlobReference("blob3"); blob3.uploadFromByteArray(buffer, 0, 1024, PremiumPageBlobTier.P6, null, null, null); assertEquals(PremiumPageBlobTier.P6, blob3.getProperties().getPremiumPageBlobTier()); - assertFalse(blob3.getProperties().getInferredBlobTier()); + assertFalse(blob3.getProperties().isBlobTierInferred()); + assertNull(blob3.getProperties().getStandardBlobTier()); + assertNull(blob3.getProperties().getRehydrationStatus()); CloudPageBlob blob3Ref = container.getPageBlobReference("blob3"); blob3Ref.downloadAttributes(); assertEquals(PremiumPageBlobTier.P6, blob3Ref.getProperties().getPremiumPageBlobTier()); - assertNull(blob3Ref.getProperties().getInferredBlobTier()); + assertNull(blob3Ref.getProperties().isBlobTierInferred()); // Test upload from stream API ByteArrayInputStream srcStream = new ByteArrayInputStream(buffer); CloudPageBlob blob4 = container.getPageBlobReference("blob4"); blob4.upload(srcStream, 1024, PremiumPageBlobTier.P10, null, null, null); assertEquals(PremiumPageBlobTier.P10, blob4.getProperties().getPremiumPageBlobTier()); - assertFalse(blob4.getProperties().getInferredBlobTier()); + assertFalse(blob4.getProperties().isBlobTierInferred()); + assertNull(blob4.getProperties().getStandardBlobTier()); + assertNull(blob4.getProperties().getRehydrationStatus()); CloudPageBlob blob4Ref = container.getPageBlobReference("blob4"); blob4Ref.downloadAttributes(); assertEquals(PremiumPageBlobTier.P10, blob4Ref.getProperties().getPremiumPageBlobTier()); - assertNull(blob4Ref.getProperties().getInferredBlobTier()); + assertNull(blob4Ref.getProperties().isBlobTierInferred()); // Test upload from file API File sourceFile = File.createTempFile("sourceFile", ".tmp"); @@ -1286,12 +1294,14 @@ public void testCloudPageBlobSetPremiumBlobTierOnCreate() throws URISyntaxExcept CloudPageBlob blob5 = container.getPageBlobReference("blob5"); blob5.uploadFromFile(sourceFile.getAbsolutePath(), PremiumPageBlobTier.P20, null, null, null); assertEquals(PremiumPageBlobTier.P20, blob5.getProperties().getPremiumPageBlobTier()); - assertFalse(blob5.getProperties().getInferredBlobTier()); + assertFalse(blob5.getProperties().isBlobTierInferred()); + assertNull(blob5.getProperties().getStandardBlobTier()); + assertNull(blob5.getProperties().getRehydrationStatus()); CloudPageBlob blob5Ref = container.getPageBlobReference("blob5"); blob5Ref.downloadAttributes(); assertEquals(PremiumPageBlobTier.P20, blob5Ref.getProperties().getPremiumPageBlobTier()); - assertNull(blob5Ref.getProperties().getInferredBlobTier()); + assertNull(blob5Ref.getProperties().isBlobTierInferred()); } finally { container.deleteIfExists(); @@ -1307,19 +1317,21 @@ public void testCloudPageBlobSetBlobTier() throws URISyntaxException, StorageExc String blobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testblob"); CloudPageBlob blob = container.getPageBlobReference(blobName); blob.create(1024); - assertNull(blob.getProperties().getInferredBlobTier()); + assertNull(blob.getProperties().isBlobTierInferred()); blob.downloadAttributes(); - assertTrue(blob.getProperties().getInferredBlobTier()); + assertTrue(blob.getProperties().isBlobTierInferred()); assertEquals(PremiumPageBlobTier.P10, blob.getProperties().getPremiumPageBlobTier()); blob.uploadPremiumPageBlobTier(PremiumPageBlobTier.P40); assertEquals(PremiumPageBlobTier.P40, blob.properties.getPremiumPageBlobTier()); - assertFalse(blob.getProperties().getInferredBlobTier()); + assertFalse(blob.getProperties().isBlobTierInferred()); + assertNull(blob.getProperties().getStandardBlobTier()); + assertNull(blob.getProperties().getRehydrationStatus()); CloudPageBlob blob2 = container.getPageBlobReference(blobName); blob2.downloadAttributes(); assertEquals(PremiumPageBlobTier.P40, blob2.properties.getPremiumPageBlobTier()); - assertNull(blob2.getProperties().getInferredBlobTier()); + assertNull(blob2.getProperties().isBlobTierInferred()); boolean pageBlobWithTierFound = false; for (ListBlobItem blobItem : container.listBlobs()) { @@ -1328,7 +1340,9 @@ public void testCloudPageBlobSetBlobTier() throws URISyntaxException, StorageExc if (blob.getName().equals(blobName) && !pageBlobWithTierFound) { // Check that the blob is found exactly once assertEquals(PremiumPageBlobTier.P40, blob3.properties.getPremiumPageBlobTier()); - assertFalse(blob3.getProperties().getInferredBlobTier()); + assertNull(blob3.getProperties().isBlobTierInferred()); + assertNull(blob3.getProperties().getStandardBlobTier()); + assertNull(blob3.getProperties().getRehydrationStatus()); pageBlobWithTierFound = true; } else if (blob.getName().equals(blobName)) { fail("Page blob found twice"); @@ -1379,14 +1393,18 @@ public void testCloudPageBlobSetBlobTierOnCopy() throws URISyntaxException, Stor assertEquals(BlobType.PAGE_BLOB, copy.getProperties().getBlobType()); assertEquals(PremiumPageBlobTier.P30, copy.getProperties().getPremiumPageBlobTier()); assertEquals(PremiumPageBlobTier.P10, source.getProperties().getPremiumPageBlobTier()); - assertFalse(source.getProperties().getInferredBlobTier()); - assertFalse(copy.getProperties().getInferredBlobTier()); + assertFalse(source.getProperties().isBlobTierInferred()); + assertFalse(copy.getProperties().isBlobTierInferred()); + assertNull(source.getProperties().getStandardBlobTier()); + assertNull(source.getProperties().getRehydrationStatus()); + assertNull(copy.getProperties().getStandardBlobTier()); + assertNull(copy.getProperties().getRehydrationStatus()); BlobTestHelper.waitForCopy(copy); CloudPageBlob copyRef = container.getPageBlobReference("copy"); copyRef.downloadAttributes(); assertEquals(PremiumPageBlobTier.P30, copyRef.getProperties().getPremiumPageBlobTier()); - assertNull(copyRef.getProperties().getInferredBlobTier()); + assertNull(copyRef.getProperties().isBlobTierInferred()); // copy where source does not have a tier CloudPageBlob source2 = container.getPageBlobReference("source2"); @@ -1397,8 +1415,12 @@ public void testCloudPageBlobSetBlobTierOnCopy() throws URISyntaxException, Stor assertEquals(BlobType.PAGE_BLOB, copy3.getProperties().getBlobType()); assertEquals(PremiumPageBlobTier.P60, copy3.getProperties().getPremiumPageBlobTier()); assertNull(source2.getProperties().getPremiumPageBlobTier()); - assertNull(source2.getProperties().getInferredBlobTier()); - assertFalse(copy3.getProperties().getInferredBlobTier()); + assertNull(source2.getProperties().isBlobTierInferred()); + assertFalse(copy3.getProperties().isBlobTierInferred()); + assertNull(source2.getProperties().getStandardBlobTier()); + assertNull(source2.getProperties().getRehydrationStatus()); + assertNull(copy3.getProperties().getStandardBlobTier()); + assertNull(copy3.getProperties().getRehydrationStatus()); } finally { container.deleteIfExists(); diff --git a/microsoft-azure-storage-test/src/com/microsoft/azure/storage/file/FileSasTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/file/FileSasTests.java index aefc5a9..346cc66 100644 --- a/microsoft-azure-storage-test/src/com/microsoft/azure/storage/file/FileSasTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/file/FileSasTests.java @@ -131,7 +131,7 @@ public void testDirectorySas() throws InvalidKeyException, IllegalArgumentExcept file.create(512); SharedAccessFilePolicy policy = createSharedAccessPolicy( - EnumSet.of(SharedAccessFilePermissions.READ, SharedAccessFilePermissions.LIST), 300); + EnumSet.of(SharedAccessFilePermissions.READ, SharedAccessFilePermissions.LIST, SharedAccessFilePermissions.DELETE), 300); // Test directory SAS with a file SAS token from an identically named file String sas = file.generateSharedAccessSignature(policy, null); @@ -148,6 +148,10 @@ public void testDirectorySas() throws InvalidKeyException, IllegalArgumentExcept sas = this.share.generateSharedAccessSignature(policy, null); sasDir = new CloudFileDirectory(new URI(dir.getUri().toString() + "?" + sas)); sasDir.downloadAttributes(); + + // Test deleting a directory using a SAS token. The directory must be empty for this request to succeed. + file.delete(); + sasDir.delete(); } @Test diff --git a/microsoft-azure-storage/AndroidManifest.xml b/microsoft-azure-storage/AndroidManifest.xml index f1b9fe5..8b9f543 100644 --- a/microsoft-azure-storage/AndroidManifest.xml +++ b/microsoft-azure-storage/AndroidManifest.xml @@ -11,7 +11,7 @@ diff --git a/microsoft-azure-storage/pom.xml b/microsoft-azure-storage/pom.xml index 5a5cc45..9f225d6 100644 --- a/microsoft-azure-storage/pom.xml +++ b/microsoft-azure-storage/pom.xml @@ -10,7 +10,7 @@ 4.0.0 com.microsoft.azure.android azure-storage-android - 1.1.0 + 1.2.0 aar Microsoft Azure Storage Android Client SDK diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/Constants.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/Constants.java index ffbcfb4..db0d8c0 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/Constants.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/Constants.java @@ -595,7 +595,7 @@ public static class HeaderConstants { /** * Specifies the value to use for UserAgent header. */ - public static final String USER_AGENT_VERSION = "1.1.0"; + public static final String USER_AGENT_VERSION = "1.2.0"; /** * The default type for content-type and accept @@ -828,6 +828,11 @@ public static class QueryConstants { */ public static final String ACCESS_TIER = "AccessTier"; + /** + * XML element for the archive status. + */ + public static final String ARCHIVE_STATUS = "ArchiveStatus"; + /** * Buffer width used to copy data to output streams. */ diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/ServicePropertiesHandler.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/ServicePropertiesHandler.java index ecb9d92..44ce349 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/ServicePropertiesHandler.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/ServicePropertiesHandler.java @@ -58,6 +58,10 @@ public static ServiceProperties readServicePropertiesFromStream(final InputStrea IOException, ParserConfigurationException { SAXParser saxParser = Utility.getSAXParser(); ServicePropertiesHandler handler = new ServicePropertiesHandler(); + handler.props.setCors(null); + handler.props.setHourMetrics(null); + handler.props.setMinuteMetrics(null); + handler.props.setCors(null); saxParser.parse(stream, handler); return handler.props; @@ -70,6 +74,18 @@ public void startElement(String uri, String localName, String qName, Attributes if (Constants.AnalyticsConstants.CORS_RULE_ELEMENT.equals(localName)) { this.rule = new CorsRule(); } + else if (Constants.AnalyticsConstants.LOGGING_ELEMENT.equals(localName)) { + this.props.setLogging(new LoggingProperties()); + } + else if (Constants.AnalyticsConstants.HOUR_METRICS_ELEMENT.equals(localName)) { + this.props.setHourMetrics(new MetricsProperties()); + } + else if (Constants.AnalyticsConstants.MINUTE_METRICS_ELEMENT.equals(localName)) { + this.props.setMinuteMetrics(new MetricsProperties()); + } + else if (Constants.AnalyticsConstants.CORS_ELEMENT.equals(localName)) { + this.props.setCors(new CorsProperties()); + } } @Override diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobConstants.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobConstants.java index f0ca820..e05e221 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobConstants.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobConstants.java @@ -30,11 +30,17 @@ final class BlobConstants { * The header that specifies if the access tier is inferred. */ public static final String ACCESS_TIER_INFERRED_HEADER = Constants.PREFIX_FOR_STORAGE_HEADER + "access-tier-inferred"; + /** * Specifies the append blob type. */ public static final String APPEND_BLOB = "AppendBlob"; + /** + * The header that specifies the archive status. + */ + public static final String ARCHIVE_STATUS_HEADER = Constants.PREFIX_FOR_STORAGE_HEADER + "archive-status"; + /** * XML element for authentication error details. */ diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobListHandler.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobListHandler.java index 1898af4..5fe51e3 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobListHandler.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobListHandler.java @@ -325,9 +325,31 @@ else if (Constants.COPY_DESTINATION_SNAPSHOT_ID_ELEMENT.equals(currentNode)) { this.copyState.setCopyDestinationSnapshotID(value); } else if (Constants.ACCESS_TIER.equals(currentNode)) { - PremiumPageBlobTier premiumPageBlobTier = PremiumPageBlobTier.parse(value); - this.properties.setPremiumPageBlobTier(premiumPageBlobTier); - this.properties.setBlobTierInferredTier(false); + if (properties.getBlobType().equals(BlobType.PAGE_BLOB)) { + PremiumPageBlobTier premiumPageBlobTier = PremiumPageBlobTier.parse(value); + this.properties.setPremiumPageBlobTier(premiumPageBlobTier); + } + else if (properties.getBlobType().equals(BlobType.BLOCK_BLOB)) { + StandardBlobTier standardBlobTier = StandardBlobTier.parse(value); + this.properties.setStandardBlobTier(standardBlobTier); + } + else if (properties.getBlobType().equals(BlobType.UNSPECIFIED)) { + PremiumPageBlobTier premiumPageBlobTier = PremiumPageBlobTier.parse(value); + StandardBlobTier standardBlobTier = StandardBlobTier.parse(value); + if (!premiumPageBlobTier.equals(PremiumPageBlobTier.UNKNOWN)) { + properties.setPremiumPageBlobTier(premiumPageBlobTier); + } + else if (!standardBlobTier.equals(StandardBlobTier.UNKNOWN)) { + properties.setStandardBlobTier(standardBlobTier); + } + else { + properties.setPremiumPageBlobTier(PremiumPageBlobTier.UNKNOWN); + properties.setStandardBlobTier(StandardBlobTier.UNKNOWN); + } + } + } + else if (Constants.ARCHIVE_STATUS.equals(currentNode)) { + this.properties.setRehydrationStatus(RehydrationStatus.parse(value)); } } } \ No newline at end of file diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobProperties.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobProperties.java index 0c227c4..3c645e3 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobProperties.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobProperties.java @@ -122,11 +122,21 @@ public final class BlobProperties { */ private PremiumPageBlobTier premiumPageBlobTier; + /** + * Represents the tier on a blob on a standard storage account. + */ + private StandardBlobTier standardBlobTier; + /** * Represents whether or not the blob tier is inferred. */ private Boolean isBlobTierInferredTier; - + + /** + * Represents the rehydration status if the blob is being rehydrated. + */ + private RehydrationStatus rehydrationStatus; + /** * Creates an instance of the BlobProperties class. */ @@ -152,16 +162,18 @@ public BlobProperties(final BlobProperties other) { this.contentType = other.contentType; this.copyState = other.copyState; this.etag = other.etag; + this.isBlobTierInferredTier = other.isBlobTierInferredTier; + this.isIncrementalCopy = other.isIncrementalCopy; this.leaseStatus = other.leaseStatus; this.leaseState = other.leaseState; this.leaseDuration = other.leaseDuration; this.length = other.length; this.lastModified = other.lastModified; this.pageBlobSequenceNumber = other.pageBlobSequenceNumber; - this.serverEncrypted = other.serverEncrypted; - this.isIncrementalCopy = other.isIncrementalCopy; this.premiumPageBlobTier = other.premiumPageBlobTier; - this.isBlobTierInferredTier = other.isBlobTierInferredTier; + this.serverEncrypted = other.serverEncrypted; + this.standardBlobTier = other.standardBlobTier; + this.rehydrationStatus = other.rehydrationStatus; } /** @@ -288,7 +300,7 @@ public Date getLastModified() { * * @return A {@Link java.lang.Boolean} object which represents if the blob tier was inferred. */ - public Boolean getInferredBlobTier() { return this.isBlobTierInferredTier; } + public Boolean isBlobTierInferred() { return this.isBlobTierInferredTier; } /** * Gets the lease status for the blob. @@ -344,6 +356,22 @@ public PremiumPageBlobTier getPremiumPageBlobTier() { return this.premiumPageBlobTier; } + /** + * If using a standard account and the blob is a block blob, gets the tier of the blob. + * @return A {@link StandardBlobTier} object which represents the tier of the blob + * or null if the tier has not been set. + */ + public StandardBlobTier getStandardBlobTier() { + return this.standardBlobTier; + } + + /** + * The rehydration status if the blob is being rehydrated + * and the tier of the blob once the rehydration from archive has completed. + * @return + */ + public RehydrationStatus getRehydrationStatus() { return this.rehydrationStatus; } + /** * Gets the blob's server-side encryption status; * @@ -550,12 +578,30 @@ protected void setPremiumPageBlobTier(PremiumPageBlobTier premiumPageBlobTier) { this.premiumPageBlobTier = premiumPageBlobTier; } + /** + * Sets the tier of the block blob. This is only supported for standard storage accounts. + * @param standardBlobTier + * A {@link StandardBlobTier} object which represents the tier of the blob. + */ + protected void setStandardBlobTier(StandardBlobTier standardBlobTier) { + this.standardBlobTier = standardBlobTier; + } + /** * Sets whether the blob tier is inferred. * @param isBlobTierInferredTier * A {@Link java.lang.Boolean} which specifies if the blob tier is inferred. */ - protected void setBlobTierInferredTier(Boolean isBlobTierInferredTier) { + protected void setBlobTierInferred(Boolean isBlobTierInferredTier) { this.isBlobTierInferredTier = isBlobTierInferredTier; } + + /** + * Sets the rehydration status of the blob. + * @param rehydrationStatus + * A {@Link RehydrationStatus} which specifies the rehydration status of the blob. + */ + protected void setRehydrationStatus(RehydrationStatus rehydrationStatus) { + this.rehydrationStatus = rehydrationStatus; + } } \ No newline at end of file diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobResponse.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobResponse.java index 0e26efa..70b38e6 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobResponse.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobResponse.java @@ -125,23 +125,43 @@ else if (!Utility.isNullOrEmpty(xContentLengthHeader)) { } // Get the tier of the blob - final String premiumBlobTierString = request.getHeaderField(BlobConstants.ACCESS_TIER_HEADER); + final String blobTierString = request.getHeaderField(BlobConstants.ACCESS_TIER_HEADER); - if (properties.getBlobType().equals(BlobType.PAGE_BLOB)) - { - PremiumPageBlobTier premiumPageBlobTier = PremiumPageBlobTier.parse(premiumBlobTierString); + if (!Utility.isNullOrEmpty(blobTierString) && properties.getBlobType().equals(BlobType.PAGE_BLOB)) { + PremiumPageBlobTier premiumPageBlobTier = PremiumPageBlobTier.parse(blobTierString); properties.setPremiumPageBlobTier(premiumPageBlobTier); } - else if (properties.getBlobType().equals(BlobType.UNSPECIFIED)) { - PremiumPageBlobTier premiumPageBlobTier = PremiumPageBlobTier.parse(premiumBlobTierString); + else if (!Utility.isNullOrEmpty(blobTierString) && properties.getBlobType().equals(BlobType.BLOCK_BLOB)) { + StandardBlobTier standardBlobTier = StandardBlobTier.parse(blobTierString); + properties.setStandardBlobTier(standardBlobTier); + } + else if (!Utility.isNullOrEmpty(blobTierString) && properties.getBlobType().equals(BlobType.UNSPECIFIED)) { + PremiumPageBlobTier premiumPageBlobTier = PremiumPageBlobTier.parse(blobTierString); + StandardBlobTier standardBlobTier = StandardBlobTier.parse(blobTierString); if (!premiumPageBlobTier.equals(PremiumPageBlobTier.UNKNOWN)) { properties.setPremiumPageBlobTier(premiumPageBlobTier); } + else if (!standardBlobTier.equals(StandardBlobTier.UNKNOWN)) { + properties.setStandardBlobTier(standardBlobTier); + } + else { + properties.setPremiumPageBlobTier(PremiumPageBlobTier.UNKNOWN); + properties.setStandardBlobTier(StandardBlobTier.UNKNOWN); + } } final String tierInferredString = request.getHeaderField(BlobConstants.ACCESS_TIER_INFERRED_HEADER); if (!Utility.isNullOrEmpty(tierInferredString)) { - properties.setBlobTierInferredTier(Boolean.parseBoolean(tierInferredString)); + properties.setBlobTierInferred(Boolean.parseBoolean(tierInferredString)); + } + + final String rehydrationStatusString = request.getHeaderField(BlobConstants.ARCHIVE_STATUS_HEADER); + if (!Utility.isNullOrEmpty(rehydrationStatusString)) { + RehydrationStatus rehydrationStatus = RehydrationStatus.parse(rehydrationStatusString); + properties.setRehydrationStatus(rehydrationStatus); + } + else { + properties.setRehydrationStatus(null); } final String incrementalCopyHeaderString = diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlob.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlob.java index e8d0605..3d3b932 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlob.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlob.java @@ -772,7 +772,7 @@ public String preProcessResponse(CloudBlob blob, CloudBlobClient client, Operati blob.properties.setCopyState(BlobResponse.getCopyState(this.getConnection())); blob.properties.setPremiumPageBlobTier(premiumPageBlobTier); if (premiumPageBlobTier != null) { - blob.properties.setBlobTierInferredTier(false); + blob.properties.setBlobTierInferred(false); } return blob.properties.getCopyState().getCopyId(); @@ -2539,6 +2539,56 @@ public Void preProcessResponse(CloudBlob blob, CloudBlobClient client, Operation return putRequest; } + protected StorageRequest uploadBlobTierImpl(final String blobTierString, final BlobRequestOptions options) { + final StorageRequest setTierRequest = new StorageRequest( + options, this.getStorageUri()) { + + @Override + public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, OperationContext context) + throws Exception { + return BlobRequest.setBlobTier(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), options, context, blobTierString); + } + + @Override + public void signRequest(HttpURLConnection connection, CloudBlobClient client, OperationContext context) + throws Exception { + StorageRequest.signBlobQueueAndFileRequest(connection, client, 0L, context); + } + + @Override + public Void preProcessResponse(CloudBlob blob, CloudBlobClient client, OperationContext context) + throws Exception { + if (this.getResult().getStatusCode() != HttpURLConnection.HTTP_OK && this.getResult().getStatusCode() != HttpURLConnection.HTTP_ACCEPTED) { + this.setNonExceptionedRetryableFailure(true); + return null; + } + + blob.updateEtagAndLastModifiedFromResponse(this.getConnection()); + this.getResult().setRequestServiceEncrypted(BaseResponse.isServerRequestEncrypted(this.getConnection())); + blob.getProperties().setBlobTierInferred(false); + if (blob.getProperties().getBlobType() == BlobType.BLOCK_BLOB) { + // For standard accounts when rehydrating a blob from archive, the status code will be 202 instead of 200. + StandardBlobTier standardBlobTier = StandardBlobTier.parse(blobTierString); + blob.getProperties().setRehydrationStatus(null); + if (this.getResult().getStatusCode() == HttpURLConnection.HTTP_OK) { + blob.getProperties().setStandardBlobTier(standardBlobTier); + } + else if (standardBlobTier.equals(StandardBlobTier.COOL)) { + blob.getProperties().setStandardBlobTier(StandardBlobTier.ARCHIVE); + } + else if (standardBlobTier.equals(StandardBlobTier.HOT)) { + blob.getProperties().setStandardBlobTier(StandardBlobTier.ARCHIVE); + } + } + + return null; + } + + }; + + return setTierRequest; + } + /** * Sets the container for the blob. * diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlockBlob.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlockBlob.java index 396765a..da2e04b 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlockBlob.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlockBlob.java @@ -1077,4 +1077,47 @@ public void setStreamWriteSizeInBytes(final int streamWriteSizeInBytes) { this.streamWriteSizeInBytes = streamWriteSizeInBytes; } + + /** + * Sets the blob tier on a block blob on a standard storage account. + * @param standardBlobTier + * A {@link StandardBlobTier} object which represents the tier of the blob. + * @throws StorageException + * If a storage service error occurred. + */ + @DoesServiceRequest + public void uploadStandardBlobTier(final StandardBlobTier standardBlobTier) throws StorageException { + this.uploadStandardBlobTier(standardBlobTier, null /* options */, null /* opContext */); + } + + /** + * Sets the tier on a block blob on a standard storage account. + * @param standardBlobTier + * A {@link StandardBlobTier} object which represents the tier of the blob. + * @param options + * A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying + * null will use the default request options from the associated service client ( + * {@link CloudBlobClient}). + * @param opContext + * An {@link OperationContext} object which represents the context for the current operation. This object + * is used to track requests to the storage service, and to provide additional runtime information about + * the operation. + * @throws StorageException + * If a storage service error occurred. + */ + @DoesServiceRequest + public void uploadStandardBlobTier(final StandardBlobTier standardBlobTier, BlobRequestOptions options, + OperationContext opContext) throws StorageException { + assertNoWriteOperationForSnapshot(); + Utility.assertNotNull("standardBlobTier", standardBlobTier); + + if (opContext == null) { + opContext = new OperationContext(); + } + + options = BlobRequestOptions.populateAndApplyDefaults(options, BlobType.BLOCK_BLOB, this.blobServiceClient); + + ExecutionEngine.executeWithRetry(this.blobServiceClient, this, + this.uploadBlobTierImpl(standardBlobTier.toString(), options), options.getRetryPolicyFactory(), opContext); + } } \ No newline at end of file diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudPageBlob.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudPageBlob.java index fa0f102..b8c030a 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudPageBlob.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudPageBlob.java @@ -574,7 +574,7 @@ public Void preProcessResponse(CloudBlob blob, CloudBlobClient client, Operation blob.getProperties().setLength(length); blob.getProperties().setPremiumPageBlobTier(premiumBlobTier); if (premiumBlobTier != null) { - blob.getProperties().setBlobTierInferredTier(false); + blob.getProperties().setBlobTierInferred(false); } return null; @@ -1586,43 +1586,8 @@ public void uploadPremiumPageBlobTier(final PremiumPageBlobTier premiumBlobTier, options = BlobRequestOptions.populateAndApplyDefaults(options, BlobType.PAGE_BLOB, this.blobServiceClient); ExecutionEngine.executeWithRetry(this.blobServiceClient, this, - this.uploadPremiumPageBlobTierImpl(premiumBlobTier, options), options.getRetryPolicyFactory(), opContext); - } - - private StorageRequest uploadPremiumPageBlobTierImpl(final PremiumPageBlobTier premiumBlobTier, - final BlobRequestOptions options) { - final StorageRequest setTierRequest = new StorageRequest( - options, this.getStorageUri()) { - - @Override - public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, OperationContext context) - throws Exception { - return BlobRequest.setBlobTier(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), options, context, premiumBlobTier.toString()); - } - - @Override - public void signRequest(HttpURLConnection connection, CloudBlobClient client, OperationContext context) - throws Exception { - StorageRequest.signBlobQueueAndFileRequest(connection, client, 0L, context); - } - - @Override - public Void preProcessResponse(CloudBlob blob, CloudBlobClient client, OperationContext context) - throws Exception { - if (this.getResult().getStatusCode() != HttpURLConnection.HTTP_OK) { - this.setNonExceptionedRetryableFailure(true); - return null; - } - - blob.updateEtagAndLastModifiedFromResponse(this.getConnection()); - blob.properties.setPremiumPageBlobTier(premiumBlobTier); - blob.properties.setBlobTierInferredTier(false); - - return null; - } - - }; - - return setTierRequest; + this.uploadBlobTierImpl(premiumBlobTier.toString(), options), options.getRetryPolicyFactory(), opContext); + this.properties.setPremiumPageBlobTier(premiumBlobTier); + this.properties.setBlobTierInferred(false); } } \ No newline at end of file diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/PremiumPageBlobTier.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/PremiumPageBlobTier.java index 590a66c..ffcc516 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/PremiumPageBlobTier.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/PremiumPageBlobTier.java @@ -77,32 +77,35 @@ public enum PremiumPageBlobTier { * * @return A PremiumPageBlobTier value that represents the premium page blob tier. */ - protected static PremiumPageBlobTier parse(final String premiumBlobTierString) { + protected static PremiumPageBlobTier parse(String premiumBlobTierString) { + if (Utility.isNullOrEmpty(premiumBlobTierString)) { return UNKNOWN; } - else if ("p4".equals(premiumBlobTierString.toLowerCase(Locale.US))) { + + premiumBlobTierString = premiumBlobTierString.toLowerCase(Locale.US); + if ("p4".equals(premiumBlobTierString)) { return P4; } - else if ("p6".equals(premiumBlobTierString.toLowerCase(Locale.US))) { + else if ("p6".equals(premiumBlobTierString)) { return P6; } - else if ("p10".equals(premiumBlobTierString.toLowerCase(Locale.US))) { + else if ("p10".equals(premiumBlobTierString)) { return P10; } - else if ("p20".equals(premiumBlobTierString.toLowerCase(Locale.US))) { + else if ("p20".equals(premiumBlobTierString)) { return P20; } - else if ("p30".equals(premiumBlobTierString.toLowerCase(Locale.US))) { + else if ("p30".equals(premiumBlobTierString)) { return P30; } - else if ("p40".equals(premiumBlobTierString.toLowerCase(Locale.US))) { + else if ("p40".equals(premiumBlobTierString)) { return P40; } - else if ("p50".equals(premiumBlobTierString.toLowerCase(Locale.US))) { + else if ("p50".equals(premiumBlobTierString)) { return P50; } - else if ("p60".equals(premiumBlobTierString.toLowerCase(Locale.US))) { + else if ("p60".equals(premiumBlobTierString)) { return P60; } else { diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/RehydrationStatus.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/RehydrationStatus.java new file mode 100644 index 0000000..34f176d --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/RehydrationStatus.java @@ -0,0 +1,49 @@ +package com.microsoft.azure.storage.blob; + +import com.microsoft.azure.storage.core.Utility; + +import java.util.Locale; + +/** + * The rehydration status for the blob that is currently archived. + * Only applicable for block blobs on standard storage accounts for this version. + */ +public enum RehydrationStatus { + /** + * The rehydration status is not recognized by this version of the library. + */ + UNKNOWN, + + /** + * The blob is being rehydrated to hot storage. + */ + PENDING_TO_HOT, + + /** + * The blob is being rehydrated to cool storage. + **/ + PENDING_TO_COOL; + + /** + * Parses a rehydration status from the given string. + * + * @param rehydrationStatusString + * A String which represents the rehydration status to string. + * + * @return A RehydrationStatus value that represents the rehydration status of the blob. + */ + protected static RehydrationStatus parse(final String rehydrationStatusString) { + if (Utility.isNullOrEmpty(rehydrationStatusString)) { + return UNKNOWN; + } + else if ("rehydrate-pending-to-hot".equals(rehydrationStatusString.toLowerCase(Locale.US))) { + return PENDING_TO_HOT; + } + else if ("rehydrate-pending-to-cool".equals(rehydrationStatusString.toLowerCase(Locale.US))) { + return PENDING_TO_COOL; + } + else { + return UNKNOWN; + } + } +} \ No newline at end of file diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/StandardBlobTier.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/StandardBlobTier.java new file mode 100644 index 0000000..251c859 --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/StandardBlobTier.java @@ -0,0 +1,70 @@ +/** + * Copyright 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.azure.storage.blob; + +import com.microsoft.azure.storage.core.Utility; + +import java.util.Locale; + +/** + * The tier of the block blob on a standard storage account. + */ +public enum StandardBlobTier { + /** + * The tier is not recognized by this version of the library. + */ + UNKNOWN, + + /** + * The tier is hot storage. + */ + HOT, + + /** + * The tier is cool storage. + */ + COOL, + + /** + * The tier is archive storage. + */ + ARCHIVE; + + /** + * Parses a standard blob tier from the given string. + * + * @param standardBlobTierString + * A String which represents the tier of the blob tier on a standard storage account. + * + * @return A StandardBlobTier value that represents the standard blob tier. + */ + protected static StandardBlobTier parse(final String standardBlobTierString) { + if (Utility.isNullOrEmpty(standardBlobTierString)) { + return UNKNOWN; + } + else if ("hot".equals(standardBlobTierString.toLowerCase(Locale.US))) { + return HOT; + } + else if ("cool".equals(standardBlobTierString.toLowerCase(Locale.US))) { + return COOL; + } + else if ("archive".equals(standardBlobTierString.toLowerCase(Locale.US))) { + return ARCHIVE; + } + else { + return UNKNOWN; + } + } +} diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/file/CloudFileDirectory.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/file/CloudFileDirectory.java index b3964df..3337a71 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/file/CloudFileDirectory.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/file/CloudFileDirectory.java @@ -349,7 +349,7 @@ private StorageRequest deleteDirector @Override public HttpURLConnection buildRequest(CloudFileClient client, CloudFileDirectory directory, OperationContext context) throws Exception { - return FileRequest.deleteDirectory(directory.getStorageUri().getPrimaryUri(), options, context, + return FileRequest.deleteDirectory(directory.getTransformedAddress().getUri(this.getCurrentLocation()), options, context, accessCondition); }