diff --git a/BreakingChanges.txt b/BreakingChanges.txt index f5da6c58946d4..484672d6a5d96 100644 --- a/BreakingChanges.txt +++ b/BreakingChanges.txt @@ -1,3 +1,40 @@ +Changes in 0.7.0 + +BLOB + * Removed CloudPageBlob openOutputStream methods in favor of equivalent openWriteNew methods. + * Removed SharedAccessBlobPolicy permissionsFromString(String) and permissionsToString(EnumSet) static methods in favor of setPermissionsFromString(String) and permissionsToString() instance methods. + * Moved LeaseDuration, LeaseState, and LeaseStatus from the storage package to the blob package + * Made the parse(String) methods in LeaseDuration, LeaseState, and LeaseStatus internal + * Removed BlobType enum parse() method + * Removed CopyStatus enum parse() method + * Removed some BlobProperties setter methods (all originally marked "Internal Use Only") + * BlockEntry searchMode field must be accessed through its getter/setter + * Applied MaximumExecutionTime to downloadToByteArray and downloadRangeToByteArray methods + * Deprecated ConcurrentRequestCount and SingleBlobPutThresholdInBytes getters and setters on the blob service client. Use the getters and setters located on the request options object accessible via getDefaultRequestOptions() instead. + +QUEUE + * Removed SharedAccessQueuePolicy permissionsFromString(String) and permissionsToString(EnumSet) static methods in favor of setPermissionsFromString(String) and permissionsToString() instance methods. + * Removed CloudQueueMessage setExpirationTime(), setNextVisibleTime() and setPopReceipt() methods + +TABLE + * Moved all execute and executeSegmented methods for TableOperations, TableBatchOperations, and TableQueries from CloudTableClient to CloudTable. The CloudTableClient methods are removed. + * Removed SharedAccessTablePolicy permissionsFromString(String) and permissionsToString(EnumSet) static methods in favor of setPermissionsFromString(String) and permissionsToString() instance methods. + * Removed CloudTableClient constructors taking only URI/StorageUri and throw if credentials passed into constructors are null as tables do not allow anonymous access + * Removed TableConstants class + * Deprecated the TablePayloadFormat getter and setter on the table service client. Use the getter and setter located on the request options object accessible via getDefaultRequestOptions() instead. + +OTHER + * Changed package name from com.microsoft.windowsazure.storage to com.microsoft.azure.storage + * Removed OperationContext getCurrentRequestObject/setCurrentReqestObject methods + * Removed reserved methods from StorageCredentials classes + * Made the isUsePathStyleUris() method in ServiceClient protected + * RetryContext currentRetryCount and lastRequestResult fields must be accessed with their corresponding getters/setters + * Removed some classes/methods originally marked "Internal Use Only": Credentials.getSigningAccountName(), StorageCredentialsAccountAndKey.setSigningAccountName(), DeserializationHelper class + * Removed GeoReplicationStats.getGeoReplicationStatus(String) + * Deprecated LocationMode, RetryPolicyFactory, TimeoutInMs, and MaximumExecutionTimeInMs getters and setters on the service clients. Use the getters and setters located on the request options object accessible via getDefaultRequestOptions() instead. + * Removed server TimeoutInMs defaults. These are still settable via the DefaultRequestOptions object on the client if desired. + * Whitespace only metadata values are no longer accepted + Changes in 0.6.0 BLOB diff --git a/ChangeLog.txt b/ChangeLog.txt index ae1924d53423f..16ac571e19df1 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,39 @@ +2014.05.06 Version 0.7.0 + * Created a DefaultRequestOptions object for each service client + * Deprecated getter/setters for all request option properties on the service clients + * Removed server timeout defaults. These are still settable via the DefaultRequestOptions object on the client if desired + * Removed OperationContext getCurrentRequestObject/setCurrentReqestObject methods + * Removed SharedAccess{Blob|Queue|Table}Policy permissionsFromString(String) and permissionsToString(EnumSet) static methods in favor of setPermissionsFromString(String) and permissionsToString() instance methods + * Moved all execute and executeSegmented methods for TableOperations, TableBatchOperations, and TableQueries from CloudTableClient to CloudTable. The CloudTableClient methods are removed + * Deprecated getEntityClass() in TableQuery. Please use getClazzType() instead. + * Removed CloudPageBlob openOutputStream methods in favor of equivalent openWriteNew methods + * Removed reserved methods from StorageCredentials classes + * Made the isUsePathStyleUris() method in ServiceClient protected + * Removed CloudTableClient constructors taking only URI/StorageUri and throw if credentials passed into constructors are null as tables do not allow anonymous access + * Removed extraneous ServiceClient constructors + * Moved LeaseDuration, LeaseState, and LeaseStatus from the storage package to the blob package + * Made the parse(String) methods in LeaseDuration, LeaseState, and LeaseStatus internal + * RetryContext currentRetryCount and lastRequestResult fields must be accessed with their corresponding getters/setters + * BlockEntry searchMode field must be accessed through its getter/setter + * BlockEntry has an additional constructor taking only block id + * Removed BlobType enum parse() method + * Removed CopyStatus enum parse() method + * Removed CloudQueueMessage setExpirationTime(), setNextVisibleTime() and setPopReceipt() methods + * Removed TableConstants class + * Removed some classes/methods originally marked "Internal Use Only": Credentials.getSigningAccountName(), StorageCredentialsAccountAndKey.setSigningAccountName(), DeserializationHelper class, some BlobProperties setter methods + * Applied MaximumExecutionTime to downloadToByteArray and downloadRangeToByteArray methods + * Removed GeoReplicationStats.getGeoReplicationStatus(String) + * Moved SharedAccessPolicy, Permissions base classes (and serializers/deserializers) from core to storage + * Added container/queue/table constructors taking only URI or StorageUri to enable direct instantiation with a SAS token + * Fixed LeaseState so that it is parsed correctly. Previously, a leased blob returned LeaseState.UNSPECIFIED rather than LeaseState.LEASED + * Fixed the CloudTable(URI) method to correctly handle partition key and row key limits for passed in SAS tokens + * Fixed an issue that allowed whitespace metadata values to be set + * Changed package name from com.microsoft.windowsazure.storage to com.microsoft.azure.storage + * Deprecated AtomPub format for tables + * Added support for secondary location access in Azure Storage Emulator + * Removed unnecessary exceptions specified in the throws clause of method declarations + * Fixed issue with path-style uris and sas credentials + 2014.02.19 Version 0.6.0 * Removed OperationContext getCurrentOperationByteCount/setCurrentOperationByteCount and getIntermediateMD5/setIntermediateMD5 methods * Deprecated OperationContext getCurrentRequestObject/setCurrentReqestObject methods diff --git a/README.md b/README.md index 47939372e590b..a6f15c1acd240 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,12 @@ -#Windows Azure Storage SDK for Java +#Microsoft Azure Storage SDK for Java -This project provides a client library in Java that makes it easy to consume Windows Azure Storage services. For documentation please see the [Windows Azure Java Developer Center](http://www.windowsazure.com/en-us/develop/java/) and the [JavaDocs](http://dl.windowsazure.com/storage/javadoc). +This project provides a client library in Java that makes it easy to consume Microsoft Azure Storage services. For documentation please see the Microsoft Azure [Java Developer Center](http://azure.microsoft.com/en-us/develop/java/) and the [JavaDocs](http://dl.windowsazure.com/storage/javadoc). #Features * Blob * Create/Read/Update/Delete containers * Create/Read/Update/Delete blobs + * Advanced Blob Operations * Queue * Create/Delete Queues * Insert/Peek Queue Messages @@ -13,113 +14,120 @@ This project provides a client library in Java that makes it easy to consume Win * Table * Create/Read/Update/Delete tables * Create/Read/Update/Delete entities - * Batch operation + * Batch operations + * Advanced Table Operations #Getting Started ##Download -###Option 1: Via Git +###Option 1: Via Maven -To get the source code of the SDK via git just type: - - git clone git://github.com/WindowsAzure/azure-storage-java.git - cd ./azure-storage-java/microsoft-azure-storage - mvn compile - -###Option 2: Via Maven - -To get the binaries of this library as distributed by Microsoft, ready for use -within your project you can also have them installed by the Java package manager Maven. +To get the binaries of this library as distributed by Microsoft, ready for use within your project, you can use Maven. ```xml com.microsoft.windowsazure.storage microsoft-windowsazure-storage-sdk - 0.6.0 + 0.7.0 ``` +###Option 2: Source Via Git + +To get the source code of the SDK via git just type: + + git clone git://github.com/Azure/azure-storage-java.git + cd ./azure-storage-java/microsoft-azure-storage + mvn compile + +###Option 3: Source Zip + +To download a copy of the source code, click "Download ZIP" on the right side of the page or click [here](https://github.com/Azure/azure-storage-java/archive/master.zip). Unzip and navigate to the microsoft-azure-storage folder. + ##Minimum Requirements -* Java 1.6 +* Java 1.6+ +* [Jackson-Core](https://github.com/FasterXML/jackson-core) is used for JSON parsing. +* (Optional) [SLF4J](http://www.slf4j.org/) is a logging facade. +* (Optional) [SLF4J binding](http://www.slf4j.org/manual.html) is used to associate a specific logging framework with SLF4J. * (Optional) Maven - + +The two dependencies, [Jackson-Core](https://github.com/FasterXML/jackson-core) and [SLF4J](http://www.slf4j.org/), will be added automatically if Maven is used. Otherwise, please download the jars and add them to your build path. + +SLF4J is only needed if you enable logging through the OperationContext class. If you plan to use logging, please also download an [SLF4J binding](http://repo2.maven.org/maven2/org/slf4j/) which will link the SLF4J API with the logging implementation of your choice. Simple is a good default. See the [SLF4J user manual](http://www.slf4j.org/manual.html) for more information. ##Usage -To use this SDK to call Windows Azure services, you need to first create an -account. To host your Java code in Windows Azure, you additionally need to download -the full Windows Azure SDK for Java - which includes packaging, emulation, and -deployment tools. +To use this SDK to call Microsoft Azure storage services, you need to first [create an account](https://account.windowsazure.com/signup). + +Samples are provided in the microsoft-azure-storage-samples folder. The unit tests in microsoft-azure-storage-test can also be helpful. ##Code Sample -The following is a quick example on how to set up a Azure blob using the API and uploading a file to it. For additional information on using the client libraries to access Azure services see the How To guides for [blobs](http://www.windowsazure.com/en-us/develop/java/how-to-guides/blob-storage/), [queues](http://www.windowsazure.com/en-us/develop/java/how-to-guides/queue-service/) and [tables](http://www.windowsazure.com/en-us/develop/java/how-to-guides/table-service/) and the [general documentation](http://www.windowsazure.com/en-us/develop/java/). +The following is a quick example on how to upload a file to azure blob and download it back. You may also download and view the samples in the microsoft-azure-storage-samples folder. For additional information on using the client libraries to access Azure services see the How To guides for [blobs](http://azure.microsoft.com/en-us/documentation/articles/storage-java-how-to-use-blob-storage/), [queues](http://azure.microsoft.com/en-us/documentation/articles/storage-java-how-to-use-queue-storage/), [tables](http://azure.microsoft.com/en-us/documentation/articles/storage-java-how-to-use-table-storage/) and the [general documentation](http://azure.microsoft.com/en-us/develop/java/). ```java import java.io.*; -import com.microsoft.windowsazure.storage.*; -import com.microsoft.windowsazure.storage.blob.*; +import com.microsoft.azure.storage.*; +import com.microsoft.azure.storage.blob.*; public class BlobSample { public static final String storageConnectionString = - "DefaultEndpointsProtocol=http;" - + "AccountName=your_account_name;" - + "AccountKey= your_account_key"; + "DefaultEndpointsProtocol=http;" + + "AccountName=your_account_name;" + + "AccountKey= your_account_key"; public static void main(String[] args) { try { - CloudStorageAccount account; - CloudBlobClient serviceClient; - CloudBlobContainer container; - CloudBlockBlob blob; - - account = CloudStorageAccount.parse(storageConnectionString); - serviceClient = account.createCloudBlobClient(); - // Container name must be lower case. - container = serviceClient.getContainerReference("blobsample"); - container.createIfNotExists(); - - // Set anonymous access on the container. - BlobContainerPermissions containerPermissions; - containerPermissions = new BlobContainerPermissions(); - container.uploadPermissions(containerPermissions); - - // Upload an image file. - blob = container.getBlockBlobReference("image1.jpg"); - File fileReference = new File("c:\\myimages\\image1.jpg"); - blob.upload(new FileInputStream(fileReference), fileReference.length()); - } catch (FileNotFoundException fileNotFoundException) { - System.out.print("FileNotFoundException encountered: "); - System.out.println(fileNotFoundException.getMessage()); - System.exit(-1); - } catch (StorageException storageException) { - System.out.print("StorageException encountered: "); - System.out.println(storageException.getMessage()); - System.exit(-1); - } catch (Exception e) { - System.out.print("Exception encountered: "); - System.out.println(e.getMessage()); - System.exit(-1); - } - + CloudStorageAccount account = CloudStorageAccount.parse(storageConnectionString); + CloudBlobClient serviceClient = account.createCloudBlobClient(); + + // Container name must be lower case. + CloudBlobContainer container = serviceClient.getContainerReference("myimages"); + container.createIfNotExists(); + + // Upload an image file. + CloudBlockBlob blob = container.getBlockBlobReference("image1.jpg"); + File sourceFile = new File("c:\\myimages\\image1.jpg"); + blob.upload(new FileInputStream(sourceFile), sourceFile.length()); + + // Download the image file. + File destinationFile = new File(sourceFile.getParentFile(), "image1Download.tmp"); + blob.downloadToFile(destinationFile.getAbsolutePath()); + } + catch (FileNotFoundException fileNotFoundException) { + System.out.print("FileNotFoundException encountered: "); + System.out.println(fileNotFoundException.getMessage()); + System.exit(-1); + } + catch (StorageException storageException) { + System.out.print("StorageException encountered: "); + System.out.println(storageException.getMessage()); + System.exit(-1); + } + catch (Exception e) { + System.out.print("Exception encountered: "); + System.out.println(e.getMessage()); + System.exit(-1); + } } } ``` #Need Help? -Be sure to check out the Windows Azure [Developer Forums on MSDN](http://social.msdn.microsoft.com/Forums/windowsazure/en-US/home?forum=windowsazuredata) or the [Developer Forums on Stack Overflow](http://stackoverflow.com/questions/tagged/azure+windows-azure-storage) if you have trouble with the provided code. +Be sure to check out the Microsoft Azure [Developer Forums on MSDN](http://social.msdn.microsoft.com/Forums/windowsazure/en-US/home?forum=windowsazuredata) or the [Developer Forums on Stack Overflow](http://stackoverflow.com/questions/tagged/azure+windows-azure-storage) if you have trouble with the provided code. #Contribute Code or Provide Feedback -If you would like to become an active contributor to this project please follow the instructions provided in [Windows Azure Projects Contribution Guidelines](http://windowsazure.github.com/guidelines.html). +If you would like to become an active contributor to this project please follow the instructions provided in [Azure Projects Contribution Guidelines](http://azure.github.io/guidelines.html). -If you encounter any bugs with the library please file an issue in the [Issues](https://github.com/WindowsAzure/azure-storage-java/issues) section of the project. +If you encounter any bugs with the library please file an issue in the [Issues](https://github.com/Azure/azure-storage-java/issues) section of the project. #Learn More -* [Windows Azure Java Developer Center](http://www.windowsazure.com/en-us/develop/java/) -* [Windows Azure Storage Service](http://www.windowsazure.com/en-us/documentation/services/storage/) -* [JavaDocs](http://dl.windowsazure.com/storage/javadoc) +* [Azure Developer Center](http://azure.microsoft.com/en-us/develop/java/) +* [Azure Storage Service](http://azure.microsoft.com/en-us/documentation/services/storage/) +* [Azure Storage Team Blog](http://blogs.msdn.com/b/windowsazurestorage/) +* [JavaDocs](http://dl.windowsazure.com/storage/javadoc) \ No newline at end of file diff --git a/windowsazure-storage-samples/pom.xml b/microsoft-azure-storage-samples/pom.xml similarity index 86% rename from windowsazure-storage-samples/pom.xml rename to microsoft-azure-storage-samples/pom.xml index a130ab5e51ea6..fcfa2645dd1ff 100644 --- a/windowsazure-storage-samples/pom.xml +++ b/microsoft-azure-storage-samples/pom.xml @@ -3,8 +3,11 @@ windowsazure-storage-samples windowsazure-storage-samples 0.0.1-SNAPSHOT - windowsazure-storage-samples + + Microsoft Azure Storage Client Samples Samples for creating blobs, queues and tables + https://github.com/Azure/azure-storage-java + src @@ -22,7 +25,7 @@ com.microsoft.windowsazure.storage microsoft-windowsazure-storage-sdk - 0.6.0 + 0.7.0 \ No newline at end of file diff --git a/windowsazure-storage-samples/src/com/microsoft/windowsazure/storage/blob/gettingstarted/BlobBasics.java b/microsoft-azure-storage-samples/src/com/microsoft/azure/storage/blob/gettingstarted/BlobBasics.java similarity index 85% rename from windowsazure-storage-samples/src/com/microsoft/windowsazure/storage/blob/gettingstarted/BlobBasics.java rename to microsoft-azure-storage-samples/src/com/microsoft/azure/storage/blob/gettingstarted/BlobBasics.java index 60d61b5d6f32a..61d2be53ecfcb 100644 --- a/windowsazure-storage-samples/src/com/microsoft/windowsazure/storage/blob/gettingstarted/BlobBasics.java +++ b/microsoft-azure-storage-samples/src/com/microsoft/azure/storage/blob/gettingstarted/BlobBasics.java @@ -12,19 +12,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob.gettingstarted; +package com.microsoft.azure.storage.blob.gettingstarted; import java.net.URISyntaxException; import java.security.InvalidKeyException; -import com.microsoft.windowsazure.storage.CloudStorageAccount; -import com.microsoft.windowsazure.storage.blob.BlobContainerPermissions; -import com.microsoft.windowsazure.storage.blob.BlobContainerPublicAccessType; -import com.microsoft.windowsazure.storage.blob.CloudBlobClient; -import com.microsoft.windowsazure.storage.blob.CloudBlobContainer; -import com.microsoft.windowsazure.storage.blob.CloudBlockBlob; -import com.microsoft.windowsazure.storage.blob.ListBlobItem; -import com.microsoft.windowsazure.storage.util.Utility; +import com.microsoft.azure.storage.CloudStorageAccount; +import com.microsoft.azure.storage.blob.BlobContainerPermissions; +import com.microsoft.azure.storage.blob.BlobContainerPublicAccessType; +import com.microsoft.azure.storage.blob.CloudBlobClient; +import com.microsoft.azure.storage.blob.CloudBlobContainer; +import com.microsoft.azure.storage.blob.CloudBlockBlob; +import com.microsoft.azure.storage.blob.ListBlobItem; +import com.microsoft.azure.storage.util.Utility; /** * This sample illustrates basic usage of the various Blob Primitives provided diff --git a/windowsazure-storage-samples/src/com/microsoft/windowsazure/storage/queue/gettingstarted/QueueBasics.java b/microsoft-azure-storage-samples/src/com/microsoft/azure/storage/queue/gettingstarted/QueueBasics.java similarity index 89% rename from windowsazure-storage-samples/src/com/microsoft/windowsazure/storage/queue/gettingstarted/QueueBasics.java rename to microsoft-azure-storage-samples/src/com/microsoft/azure/storage/queue/gettingstarted/QueueBasics.java index fa40f97c6011b..5aa6f11287b89 100644 --- a/windowsazure-storage-samples/src/com/microsoft/windowsazure/storage/queue/gettingstarted/QueueBasics.java +++ b/microsoft-azure-storage-samples/src/com/microsoft/azure/storage/queue/gettingstarted/QueueBasics.java @@ -12,18 +12,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.queue.gettingstarted; +package com.microsoft.azure.storage.queue.gettingstarted; import java.net.URISyntaxException; import java.security.InvalidKeyException; import java.util.EnumSet; -import com.microsoft.windowsazure.storage.CloudStorageAccount; -import com.microsoft.windowsazure.storage.queue.CloudQueue; -import com.microsoft.windowsazure.storage.queue.CloudQueueClient; -import com.microsoft.windowsazure.storage.queue.CloudQueueMessage; -import com.microsoft.windowsazure.storage.queue.MessageUpdateFields; -import com.microsoft.windowsazure.storage.util.Utility; +import com.microsoft.azure.storage.CloudStorageAccount; +import com.microsoft.azure.storage.queue.CloudQueue; +import com.microsoft.azure.storage.queue.CloudQueueClient; +import com.microsoft.azure.storage.queue.CloudQueueMessage; +import com.microsoft.azure.storage.queue.MessageUpdateFields; +import com.microsoft.azure.storage.util.Utility; /** * This sample illustrates basic usage of the various Queue Primitives provided diff --git a/windowsazure-storage-samples/src/com/microsoft/windowsazure/storage/table/gettingtstarted/CustomerEntity.java b/microsoft-azure-storage-samples/src/com/microsoft/azure/storage/table/gettingtstarted/CustomerEntity.java similarity index 91% rename from windowsazure-storage-samples/src/com/microsoft/windowsazure/storage/table/gettingtstarted/CustomerEntity.java rename to microsoft-azure-storage-samples/src/com/microsoft/azure/storage/table/gettingtstarted/CustomerEntity.java index 2b63d9de6e686..054c5186157e1 100644 --- a/windowsazure-storage-samples/src/com/microsoft/windowsazure/storage/table/gettingtstarted/CustomerEntity.java +++ b/microsoft-azure-storage-samples/src/com/microsoft/azure/storage/table/gettingtstarted/CustomerEntity.java @@ -12,9 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.table.gettingtstarted; +package com.microsoft.azure.storage.table.gettingtstarted; -import com.microsoft.windowsazure.storage.table.TableServiceEntity; +import com.microsoft.azure.storage.table.TableServiceEntity; public class CustomerEntity extends TableServiceEntity { diff --git a/microsoft-azure-storage-samples/src/com/microsoft/azure/storage/table/gettingtstarted/TableBasics.java b/microsoft-azure-storage-samples/src/com/microsoft/azure/storage/table/gettingtstarted/TableBasics.java new file mode 100644 index 0000000000000..b2a834764277b --- /dev/null +++ b/microsoft-azure-storage-samples/src/com/microsoft/azure/storage/table/gettingtstarted/TableBasics.java @@ -0,0 +1,232 @@ +/** + * 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.table.gettingtstarted; + +import java.net.URISyntaxException; +import java.security.InvalidKeyException; + +import com.microsoft.azure.storage.CloudStorageAccount; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.table.CloudTable; +import com.microsoft.azure.storage.table.CloudTableClient; +import com.microsoft.azure.storage.table.TableBatchOperation; +import com.microsoft.azure.storage.table.TableOperation; +import com.microsoft.azure.storage.table.TableQuery; +import com.microsoft.azure.storage.table.TableQuery.QueryComparisons; +import com.microsoft.azure.storage.util.Utility; + +/** + * This sample illustrates basic usage of the various Table Primitives provided + * in the Storage Client Library including TableOperation, TableBatchOperation, + * and TableQuery. + */ +public class TableBasics { + protected static CloudTableClient tableClient; + protected static CloudTable table; + protected final static String tableName = "tablebasics"; + + /** + * Executes the sample. + * + * @param args + * No input args are expected from users. + * @throws URISyntaxException + * @throws InvalidKeyException + */ + public static void main(String[] args) throws InvalidKeyException, URISyntaxException { + Utility.printSampleStartInfo("TableBasics"); + + // Setup the cloud storage account. + CloudStorageAccount account = CloudStorageAccount.parse(Utility.storageConnectionString); + + // Create a table service client. + tableClient = account.createCloudTableClient(); + + try { + // Retrieve a reference to a table. + table = tableClient.getTableReference(tableName); + + // Create the table if it doesn't already exist. + table.createIfNotExists(); + + // Illustrates how to list the tables. + BasicListing(); + + // Illustrates how to form and execute a single insert operation. + BasicInsertEntity(); + + // Illustrates how to form and execute a batch operation. + BasicBatch(); + + // Illustrates how to form and execute a query operation. + BasicQuery(); + + // Illustrates how to form and execute an upsert operation. + BasicUpsert(); + + // Illustrates how to form and execute an entity delete operation. + BasicDeleteEntity(); + + // Delete the table. + table.deleteIfExists(); + + } + catch (Throwable t) { + Utility.printException(t); + } + + Utility.printSampleCompleteInfo("TableBasics"); + } + + /** + * Illustrates how to form and execute a single insert operation. + * + * @throws StorageException + */ + public static void BasicInsertEntity() throws StorageException { + // Note: the limitations on an insert operation are + // - the serialized payload must be 1 MB or less + // - up to 252 properties in addition to the partition key, row key and timestamp. 255 properties in total + // - the serialized payload of each property must be 64 KB or less + + // Create a new customer entity. + CustomerEntity customer1 = new CustomerEntity("Harp", "Walter"); + customer1.setEmail("Walter@contoso.com"); + customer1.setPhoneNumber("425-555-0101"); + + // Create an operation to add the new customer to the tablebasics table. + TableOperation insertCustomer1 = TableOperation.insert(customer1); + + // Submit the operation to the table service. + table.execute(insertCustomer1); + } + + /** + * Illustrates how to form and execute a batch operation. + * + * @throws StorageException + */ + public static void BasicBatch() throws StorageException { + // Note: the limitations on a batch operation are + // - up to 100 operations + // - all operations must share the same PartitionKey + // - if a retrieve is used it can be the only operation in the batch + // - the serialized batch payload must be 4 MB or less + + // Define a batch operation. + TableBatchOperation batchOperation = new TableBatchOperation(); + + // Create a customer entity to add to the table. + CustomerEntity customer = new CustomerEntity("Smith", "Jeff"); + customer.setEmail("Jeff@contoso.com"); + customer.setPhoneNumber("425-555-0104"); + batchOperation.insert(customer); + + // Create another customer entity to add to the table. + CustomerEntity customer2 = new CustomerEntity("Smith", "Ben"); + customer2.setEmail("Ben@contoso.com"); + customer2.setPhoneNumber("425-555-0102"); + batchOperation.insert(customer2); + + // Create a third customer entity to add to the table. + CustomerEntity customer3 = new CustomerEntity("Smith", "Denise"); + customer3.setEmail("Denise@contoso.com"); + customer3.setPhoneNumber("425-555-0103"); + batchOperation.insert(customer3); + + // Execute the batch of operations on the "tablebasics" table. + table.execute(batchOperation); + } + + /** + * Illustrates how to form and execute a query operation. + * + * @throws StorageException + */ + public static void BasicQuery() throws StorageException { + // Retrieve a single entity. + // Retrieve the entity with partition key of "Smith" and row key of "Jeff". + TableOperation retrieveSmithJeff = TableOperation.retrieve("Smith", "Jeff", CustomerEntity.class); + + // Submit the operation to the table service and get the specific entity. + @SuppressWarnings("unused") + CustomerEntity specificEntity = table.execute(retrieveSmithJeff).getResultAsType(); + + // Retrieve all entities in a partition. + // Create a filter condition where the partition key is "Smith". + String partitionFilter = TableQuery.generateFilterCondition("PartitionKey", QueryComparisons.EQUAL, "Smith"); + + // Specify a partition query, using "Smith" as the partition key filter. + TableQuery partitionQuery = TableQuery.from(CustomerEntity.class).where(partitionFilter); + + // Loop through the results, displaying information about the entity. + for (CustomerEntity entity : table.execute(partitionQuery)) { + System.out.println(entity.getPartitionKey() + " " + entity.getRowKey() + "\t" + entity.getEmail() + "\t" + + entity.getPhoneNumber()); + } + } + + /** + * Illustrates how to form and execute an upsert operation. + * + * @throws StorageException + */ + public static void BasicUpsert() throws StorageException { + // Retrieve the entity with partition key of "Smith" and row key of "Jeff". + TableOperation retrieveSmithJeff = TableOperation.retrieve("Smith", "Jeff", CustomerEntity.class); + + // Submit the operation to the table service and get the specific entity. + CustomerEntity specificEntity = table.execute(retrieveSmithJeff).getResultAsType(); + + // Specify a new phone number. + specificEntity.setPhoneNumber("425-555-0105"); + + // Create an operation to replace the entity. + TableOperation replaceEntity = TableOperation.merge(specificEntity); + + // Submit the operation to the table service. + table.execute(replaceEntity); + } + + /** + * Illustrates how to form and execute an entity delete operation. + * + * @throws StorageException + */ + public static void BasicDeleteEntity() throws StorageException { + // Create an operation to retrieve the entity with partition key of "Smith" and row key of "Jeff". + TableOperation retrieveSmithJeff = TableOperation.retrieve("Smith", "Jeff", CustomerEntity.class); + + // Retrieve the entity with partition key of "Smith" and row key of "Jeff". + CustomerEntity entitySmithJeff = table.execute(retrieveSmithJeff).getResultAsType(); + + // Create an operation to delete the entity. + TableOperation deleteSmithJeff = TableOperation.delete(entitySmithJeff); + + // Submit the delete operation to the table service. + table.execute(deleteSmithJeff); + } + + /** + * Illustrates how to list the tables. + */ + public static void BasicListing() { + // List the tables with a given prefix. + Iterable listTables = tableClient.listTables(tableName, null, null); + for (String s : listTables) { + System.out.println(s); + } + } +} diff --git a/windowsazure-storage-samples/src/com/microsoft/windowsazure/storage/table/payloadformat/CustomerEntity.java b/microsoft-azure-storage-samples/src/com/microsoft/azure/storage/table/payloadformat/CustomerEntity.java similarity index 92% rename from windowsazure-storage-samples/src/com/microsoft/windowsazure/storage/table/payloadformat/CustomerEntity.java rename to microsoft-azure-storage-samples/src/com/microsoft/azure/storage/table/payloadformat/CustomerEntity.java index c6a668ccda805..7a7e01909de10 100644 --- a/windowsazure-storage-samples/src/com/microsoft/windowsazure/storage/table/payloadformat/CustomerEntity.java +++ b/microsoft-azure-storage-samples/src/com/microsoft/azure/storage/table/payloadformat/CustomerEntity.java @@ -12,11 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.table.payloadformat; +package com.microsoft.azure.storage.table.payloadformat; import java.util.UUID; -import com.microsoft.windowsazure.storage.table.TableServiceEntity; +import com.microsoft.azure.storage.table.TableServiceEntity; public class CustomerEntity extends TableServiceEntity { diff --git a/windowsazure-storage-samples/src/com/microsoft/windowsazure/storage/table/payloadformat/PayloadFormat.java b/microsoft-azure-storage-samples/src/com/microsoft/azure/storage/table/payloadformat/PayloadFormat.java similarity index 79% rename from windowsazure-storage-samples/src/com/microsoft/windowsazure/storage/table/payloadformat/PayloadFormat.java rename to microsoft-azure-storage-samples/src/com/microsoft/azure/storage/table/payloadformat/PayloadFormat.java index 9f793d637315a..e4ba4e0847260 100644 --- a/windowsazure-storage-samples/src/com/microsoft/windowsazure/storage/table/payloadformat/PayloadFormat.java +++ b/microsoft-azure-storage-samples/src/com/microsoft/azure/storage/table/payloadformat/PayloadFormat.java @@ -12,26 +12,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.table.payloadformat; +package com.microsoft.azure.storage.table.payloadformat; import java.net.URISyntaxException; import java.security.InvalidKeyException; import java.util.UUID; -import com.microsoft.windowsazure.storage.CloudStorageAccount; -import com.microsoft.windowsazure.storage.table.CloudTable; -import com.microsoft.windowsazure.storage.table.CloudTableClient; -import com.microsoft.windowsazure.storage.table.DynamicTableEntity; -import com.microsoft.windowsazure.storage.table.EdmType; -import com.microsoft.windowsazure.storage.table.TableConstants; -import com.microsoft.windowsazure.storage.table.TableOperation; -import com.microsoft.windowsazure.storage.table.TablePayloadFormat; -import com.microsoft.windowsazure.storage.table.TableQuery; -import com.microsoft.windowsazure.storage.table.TableRequestOptions; -import com.microsoft.windowsazure.storage.table.TableQuery.QueryComparisons; -import com.microsoft.windowsazure.storage.table.TableRequestOptions.PropertyResolver; -import com.microsoft.windowsazure.storage.table.payloadformat.CustomerEntity; -import com.microsoft.windowsazure.storage.util.Utility; +import com.microsoft.azure.storage.CloudStorageAccount; +import com.microsoft.azure.storage.table.CloudTable; +import com.microsoft.azure.storage.table.CloudTableClient; +import com.microsoft.azure.storage.table.DynamicTableEntity; +import com.microsoft.azure.storage.table.EdmType; +import com.microsoft.azure.storage.table.TableOperation; +import com.microsoft.azure.storage.table.TablePayloadFormat; +import com.microsoft.azure.storage.table.TableQuery; +import com.microsoft.azure.storage.table.TableRequestOptions; +import com.microsoft.azure.storage.table.TableQuery.QueryComparisons; +import com.microsoft.azure.storage.table.TableRequestOptions.PropertyResolver; +import com.microsoft.azure.storage.table.payloadformat.CustomerEntity; +import com.microsoft.azure.storage.util.Utility; /** * This sample illustrates basic usage of the various Table Primitives provided @@ -61,7 +60,7 @@ public static void main(String[] args) throws InvalidKeyException, URISyntaxExce // Set the payload format on the client. For more information about the support for JSON, // check the following document: http://blogs.msdn.com/b/windowsazurestorage/archive/2013/12/05/windows-azure-tables-introducing-json.aspx. - tableClient.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata); + tableClient.getDefaultRequestOptions().setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata); try { // Retrieve a reference to a table. @@ -80,7 +79,7 @@ public static void main(String[] args) throws InvalidKeyException, URISyntaxExce TableOperation insertCustomer1 = TableOperation.insert(customer1); // Submit the operation to the table service. - tableClient.execute("tablepayloadformat", insertCustomer1); + table.execute(insertCustomer1); // When using JsonNoMetadata the client library will �infer� the property types(int, double, // String and some booleans) by inspecting the type information on the POJO entity type @@ -117,19 +116,19 @@ else if (key.equals("Id")) { // Retrieve all entities in a partition. // Create a filter condition where the partition key is "Harp". String partitionFilter = TableQuery.generateFilterCondition( - TableConstants.PARTITION_KEY, + "PartitionKey", QueryComparisons.EQUAL, "Harp"); // Specify a partition query, using "Harp" as the partition key filter. TableQuery partitionQuery = - TableQuery.from("tablepayloadformat", DynamicTableEntity.class) + TableQuery.from(DynamicTableEntity.class) .where(partitionFilter); // Loop through the results, displaying information about the entity. Note that the // TableRequestOptions is passed in to the execute method in order to resolve // the individual properties to their types since JsonNoMetadata is being used. - for (DynamicTableEntity entity : tableClient.execute(partitionQuery, options, null /*operationContext*/)) { + for (DynamicTableEntity entity : table.execute(partitionQuery, options, null /*operationContext*/)) { System.out.println(entity.getPartitionKey() + " " + entity.getRowKey() + "\t" + entity.getProperties().get("Email").getValueAsString() + "\t" + entity.getProperties().get("PhoneNumber").getValueAsString() + "\t" + entity.getProperties().get("Id").getValueAsUUID()); } @@ -138,13 +137,13 @@ else if (key.equals("Id")) { // the client library uses the class type to infer the correct property types. // Specify a partition query, using "Harp" as the partition key filter. TableQuery partitionQueryPOJO = - TableQuery.from("tablepayloadformat", CustomerEntity.class) + TableQuery.from(CustomerEntity.class) .where(partitionFilter); // Loop through the results, displaying information about the entity. Note that the // TableRequestOptions is passed in to the execute method in order to resolve // the individual properties to their types since JsonNoMetadata is being used. - for (CustomerEntity entity : tableClient.execute(partitionQueryPOJO)) { + for (CustomerEntity entity : table.execute(partitionQueryPOJO)) { System.out.println(entity.getPartitionKey() + " " + entity.getRowKey() + "\t" + entity.getEmail() + "\t" + entity.getPhoneNumber() + "\t" + entity.getId()); } diff --git a/windowsazure-storage-samples/src/com/microsoft/windowsazure/storage/util/Utility.java b/microsoft-azure-storage-samples/src/com/microsoft/azure/storage/util/Utility.java similarity index 97% rename from windowsazure-storage-samples/src/com/microsoft/windowsazure/storage/util/Utility.java rename to microsoft-azure-storage-samples/src/com/microsoft/azure/storage/util/Utility.java index 5929cbad9e2d6..4958ac86537fe 100644 --- a/windowsazure-storage-samples/src/com/microsoft/windowsazure/storage/util/Utility.java +++ b/microsoft-azure-storage-samples/src/com/microsoft/azure/storage/util/Utility.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.util; +package com.microsoft.azure.storage.util; import java.io.PrintWriter; import java.io.StringWriter; diff --git a/microsoft-azure-storage/src/test/resources/TestConfigurations.xml b/microsoft-azure-storage-test/res/TestConfigurations.xml similarity index 81% rename from microsoft-azure-storage/src/test/resources/TestConfigurations.xml rename to microsoft-azure-storage-test/res/TestConfigurations.xml index 55e695df84418..39db98edb91bf 100644 --- a/microsoft-azure-storage/src/test/resources/TestConfigurations.xml +++ b/microsoft-azure-storage-test/res/TestConfigurations.xml @@ -9,6 +9,9 @@ http://127.0.0.1:10000/devstoreaccount1 http://127.0.0.1:10001/devstoreaccount1 http://127.0.0.1:10002/devstoreaccount1 + http://127.0.0.1:10000/devstoreaccount1-secondary + http://127.0.0.1:10001/devstoreaccount1-secondary + http://127.0.0.1:10002/devstoreaccount1-secondary ProductionTenant diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/AlwaysRetry.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/AlwaysRetry.java similarity index 98% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/AlwaysRetry.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/AlwaysRetry.java index 3f9ca0cdc1d2e..bbe6d8a536f46 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/AlwaysRetry.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/AlwaysRetry.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import static org.junit.Assert.*; diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/EventFiringTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/EventFiringTests.java similarity index 92% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/EventFiringTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/EventFiringTests.java index 10cbd356a5f55..cafb899bf7144 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/EventFiringTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/EventFiringTests.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import static org.junit.Assert.*; @@ -23,16 +23,16 @@ import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; -import com.microsoft.windowsazure.storage.blob.BlobRequestOptions; -import com.microsoft.windowsazure.storage.blob.CloudBlobClient; -import com.microsoft.windowsazure.storage.blob.CloudBlobContainer; -import com.microsoft.windowsazure.storage.core.SR; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.blob.BlobRequestOptions; +import com.microsoft.azure.storage.blob.CloudBlobClient; +import com.microsoft.azure.storage.blob.CloudBlobContainer; +import com.microsoft.azure.storage.core.SR; @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) -public class EventFiringTests extends TestBase { +public class EventFiringTests { @Test public void testSendingRequestEvents() throws URISyntaxException, StorageException { @@ -62,7 +62,7 @@ public void eventOccurred(SendingRequestEvent eventArg) { assertEquals(0, callList.size()); assertEquals(0, globalCallList.size()); - CloudBlobClient blobClient = TestBase.createCloudBlobClient(); + CloudBlobClient blobClient = TestHelper.createCloudBlobClient(); CloudBlobContainer container = blobClient.getContainerReference("container1"); // make sure both update @@ -114,7 +114,7 @@ public void eventOccurred(ResponseReceivedEvent eventArg) { assertEquals(0, callList.size()); assertEquals(0, globalCallList.size()); - CloudBlobClient blobClient = TestBase.createCloudBlobClient(); + CloudBlobClient blobClient = TestHelper.createCloudBlobClient(); CloudBlobContainer container = blobClient.getContainerReference("container1"); // make sure both update @@ -166,7 +166,7 @@ public void eventOccurred(RequestCompletedEvent eventArg) { assertEquals(0, callList.size()); assertEquals(0, globalCallList.size()); - CloudBlobClient blobClient = TestBase.createCloudBlobClient(); + CloudBlobClient blobClient = TestHelper.createCloudBlobClient(); CloudBlobContainer container = blobClient.getContainerReference("container1"); // make sure both update @@ -227,7 +227,7 @@ public void eventOccurred(RetryingEvent eventArg) { retry.maximumAttempts = 1; eventOptions.setRetryPolicyFactory(retry); - CloudBlobClient blobClient = TestBase.createCloudBlobClient(); + CloudBlobClient blobClient = TestHelper.createCloudBlobClient(); CloudBlobContainer container = blobClient.getContainerReference("container1"); // make sure both update @@ -311,7 +311,7 @@ public void eventOccurred(RequestCompletedEvent eventArg) { retry.maximumAttempts = 1; eventOptions.setRetryPolicyFactory(retry); - CloudBlobClient blobClient = TestBase.createCloudBlobClient(); + CloudBlobClient blobClient = TestHelper.createCloudBlobClient(); CloudBlobContainer container = blobClient.getContainerReference("container1"); // make sure both update even if an exception is thrown and a retry occurs @@ -325,8 +325,8 @@ public void eventOccurred(RequestCompletedEvent eventArg) { assertEquals(StorageErrorCode.RESOURCE_NOT_FOUND.toString(), e.getErrorCode()); } - assertEquals(1, sendingCallList.size()); - assertEquals(1, completedCallList.size()); + assertEquals(2, sendingCallList.size()); + assertEquals(2, completedCallList.size()); // make sure neither update if an exception is thrown before sending occurs try { @@ -339,7 +339,7 @@ public void eventOccurred(RequestCompletedEvent eventArg) { assertEquals(SR.PRIMARY_ONLY_COMMAND, e.getCause().getMessage()); } - assertEquals(1, sendingCallList.size()); - assertEquals(1, completedCallList.size()); + assertEquals(2, sendingCallList.size()); + assertEquals(2, completedCallList.size()); } } diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/GenericTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/GenericTests.java similarity index 54% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/GenericTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/GenericTests.java index 63927d8438067..d176ca775f11f 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/GenericTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/GenericTests.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import static org.junit.Assert.*; @@ -20,36 +20,146 @@ import java.io.IOException; import java.net.HttpURLConnection; import java.net.URISyntaxException; +import java.util.ArrayList; import java.util.HashMap; import java.util.UUID; import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; -import com.microsoft.windowsazure.storage.TestRunners.SlowTests; -import com.microsoft.windowsazure.storage.blob.BlobOutputStream; -import com.microsoft.windowsazure.storage.blob.BlobRequestOptions; -import com.microsoft.windowsazure.storage.blob.BlobTestBase; -import com.microsoft.windowsazure.storage.blob.CloudBlobClient; -import com.microsoft.windowsazure.storage.blob.CloudBlobContainer; -import com.microsoft.windowsazure.storage.blob.CloudBlockBlob; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.Utility; -import com.microsoft.windowsazure.storage.queue.CloudQueue; -import com.microsoft.windowsazure.storage.queue.CloudQueueClient; -import com.microsoft.windowsazure.storage.table.CloudTable; -import com.microsoft.windowsazure.storage.table.CloudTableClient; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.TestRunners.SlowTests; +import com.microsoft.azure.storage.blob.BlobOutputStream; +import com.microsoft.azure.storage.blob.BlobRequestOptions; +import com.microsoft.azure.storage.blob.BlobTestHelper; +import com.microsoft.azure.storage.blob.CloudBlobClient; +import com.microsoft.azure.storage.blob.CloudBlobContainer; +import com.microsoft.azure.storage.blob.CloudBlockBlob; +import com.microsoft.azure.storage.core.BaseRequest; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; +import com.microsoft.azure.storage.queue.CloudQueue; +import com.microsoft.azure.storage.queue.CloudQueueClient; +import com.microsoft.azure.storage.table.CloudTable; +import com.microsoft.azure.storage.table.CloudTableClient; @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) -public class GenericTests extends TestBase { +public class GenericTests { + + /** + * ReadTimeout must always be explicitly set on HttpUrlConnection to avoid a bug in JDK 6. In certain cases this + * bug causes an immediate SocketException to be thrown indicating that the read timed out even if ReadTimeout was + * not set. The SocketException is retried and can cause server-side errors to be returned (in this case, an + * InvalidBlockList error). This tests to make sure we are setting read timeout so that this issue does not occur. + * + * @see {@link BaseRequest} + * @throws URISyntaxException + * @throws StorageException + * @throws IOException + */ + @Test + @Category({ DevFabricTests.class, DevStoreTests.class, SlowTests.class }) + public void testReadTimeoutIssue() throws URISyntaxException, StorageException, IOException { + // part 1 + byte[] buffer = BlobTestHelper.getRandomBuffer(1 * 1024 * 1024); + + // set the maximum execution time + BlobRequestOptions options = new BlobRequestOptions(); + options.setMaximumExecutionTimeInMs(5000); + + CloudBlobClient blobClient = TestHelper.createCloudBlobClient(); + CloudBlobContainer container = blobClient.getContainerReference(generateRandomContainerName()); + + String blobName = "testBlob"; + final CloudBlockBlob blockBlobRef = container.getBlockBlobReference(blobName); + blockBlobRef.setStreamWriteSizeInBytes(1 * 1024 * 1024); + + ByteArrayInputStream inputStream = new ByteArrayInputStream(buffer); + BlobOutputStream blobOutputStream = null; + + try { + container.createIfNotExists(); + blobOutputStream = blockBlobRef.openOutputStream(null, options, null); + try { + blobOutputStream.write(inputStream, buffer.length); + } + finally { + blobOutputStream.close(); + } + assertTrue(blockBlobRef.exists()); + } + finally { + inputStream.close(); + container.deleteIfExists(); + } + + // part 2 + int length2 = 10 * 1024 * 1024; + byte[] uploadBuffer2 = BlobTestHelper.getRandomBuffer(length2); + + CloudBlobClient blobClient2 = TestHelper.createCloudBlobClient(); + CloudBlobContainer container2 = blobClient2.getContainerReference(generateRandomContainerName()); + + String blobName2 = "testBlob"; + final CloudBlockBlob blockBlobRef2 = container2.getBlockBlobReference(blobName2); + + ByteArrayInputStream inputStream2 = new ByteArrayInputStream(uploadBuffer2); + + try { + container2.createIfNotExists(); + + blockBlobRef2.upload(inputStream2, length2); + } + finally { + inputStream2.close(); + container2.deleteIfExists(); + } + } + + /** + * Make sure that if a request throws an error when it is being built that the request is not sent. + * + * @throws URISyntaxException + * @throws StorageException + */ + @Test + public void testExecutionEngineErrorHandling() throws URISyntaxException, StorageException { + CloudBlobContainer container = BlobTestHelper.getRandomContainerReference(); + try { + final ArrayList callList = new ArrayList(); + + OperationContext opContext = new OperationContext(); + opContext.getSendingRequestEventHandler().addListener(new StorageEvent() { + // insert a metadata element with an empty value + @Override + public void eventOccurred(SendingRequestEvent eventArg) { + callList.add(true); + } + }); + + container.getMetadata().put("key", " "); // invalid value + try { + container.uploadMetadata(null, null, opContext); + fail(SR.METADATA_KEY_INVALID); + } + catch (StorageException e) { + // make sure a request was not sent + assertEquals(0, callList.size()); + + assertEquals(SR.METADATA_VALUE_INVALID, e.getMessage()); + } + } + finally { + container.deleteIfExists(); + } + } @Test public void testUserAgentString() throws URISyntaxException, StorageException { // Test with a blob request - CloudBlobClient blobClient = TestBase.createCloudBlobClient(); + CloudBlobClient blobClient = TestHelper.createCloudBlobClient(); CloudBlobContainer container = blobClient.getContainerReference("container1"); OperationContext sendingRequestEventContext = new OperationContext(); sendingRequestEventContext.getSendingRequestEventHandler().addListener(new StorageEvent() { @@ -71,19 +181,19 @@ public void eventOccurred(SendingRequestEvent eventArg) { container.exists(null, null, sendingRequestEventContext); // Test with a queue request - CloudQueueClient queueClient = TestBase.createCloudQueueClient(); + CloudQueueClient queueClient = TestHelper.createCloudQueueClient(); CloudQueue queue = queueClient.getQueueReference("queue1"); queue.exists(null, sendingRequestEventContext); // Test with a table request - CloudTableClient tableClient = TestBase.createCloudTableClient(); + CloudTableClient tableClient = TestHelper.createCloudTableClient(); CloudTable table = tableClient.getTableReference("table1"); table.exists(null, sendingRequestEventContext); } @Test public void testUserHeaders() throws URISyntaxException, StorageException { - CloudBlobClient blobClient = TestBase.createCloudBlobClient(); + CloudBlobClient blobClient = TestHelper.createCloudBlobClient(); CloudBlobContainer container = blobClient.getContainerReference("container1"); OperationContext context = new OperationContext(); @@ -127,16 +237,16 @@ public void eventOccurred(SendingRequestEvent eventArg) { @Test public void testNullRetryPolicy() throws URISyntaxException, StorageException { - CloudBlobClient blobClient = TestBase.createCloudBlobClient(); + CloudBlobClient blobClient = TestHelper.createCloudBlobClient(); CloudBlobContainer container = blobClient.getContainerReference("container1"); - blobClient.setRetryPolicyFactory(null); + blobClient.getDefaultRequestOptions().setRetryPolicyFactory(null); container.exists(); } @Test @Category({ DevFabricTests.class, DevStoreTests.class, SecondaryTests.class }) - public void testMaximumExecutionTime() throws URISyntaxException, StorageException, IOException { + public void testMaximumExecutionTime() throws URISyntaxException, StorageException { OperationContext opContext = new OperationContext(); setDelay(opContext, 2500); @@ -149,7 +259,7 @@ public void testMaximumExecutionTime() throws URISyntaxException, StorageExcepti options.setLocationMode(LocationMode.SECONDARY_THEN_PRIMARY); options.setTimeoutIntervalInMs(1000); - CloudBlobClient blobClient = TestBase.createCloudBlobClient(); + CloudBlobClient blobClient = TestHelper.createCloudBlobClient(); CloudBlobContainer container = blobClient.getContainerReference(generateRandomContainerName()); try { @@ -160,20 +270,20 @@ public void testMaximumExecutionTime() throws URISyntaxException, StorageExcepti fail("Maximum execution time was reached but request did not fail."); } catch (StorageException e) { - assertEquals(SR.MAXIMUM_EXCUTION_TIMEOUT_EXCEPTION, e.getMessage()); + assertEquals(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, e.getMessage()); } } @Test @Category({ DevFabricTests.class, DevStoreTests.class, SlowTests.class }) public void testMaximumExecutionTimeBlobWrites() throws URISyntaxException, StorageException, IOException { - byte[] buffer = BlobTestBase.getRandomBuffer(80 * 1024 * 1024); + byte[] buffer = BlobTestHelper.getRandomBuffer(80 * 1024 * 1024); // set the maximum execution time BlobRequestOptions options = new BlobRequestOptions(); options.setMaximumExecutionTimeInMs(5000); - CloudBlobClient blobClient = TestBase.createCloudBlobClient(); + CloudBlobClient blobClient = TestHelper.createCloudBlobClient(); CloudBlobContainer container = blobClient.getContainerReference(generateRandomContainerName()); String blobName = "testBlob"; @@ -192,10 +302,10 @@ public void testMaximumExecutionTimeBlobWrites() throws URISyntaxException, Stor fail("Maximum execution time was reached but request did not fail."); } catch (StorageException e) { - assertEquals(SR.MAXIMUM_EXCUTION_TIMEOUT_EXCEPTION, e.getMessage()); + assertEquals(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, e.getMessage()); } catch (IOException e) { - assertEquals(SR.MAXIMUM_EXCUTION_TIMEOUT_EXCEPTION, e.getCause().getMessage()); + assertEquals(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, e.getCause().getMessage()); } assertFalse(blockBlobRef.exists()); @@ -209,17 +319,17 @@ public void testMaximumExecutionTimeBlobWrites() throws URISyntaxException, Stor fail("Maximum execution time was reached but request did not fail."); } catch (StorageException e) { - assertEquals(SR.MAXIMUM_EXCUTION_TIMEOUT_EXCEPTION, e.getCause().getMessage()); + assertEquals(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, e.getCause().getMessage()); } catch (IOException e) { - assertEquals(SR.MAXIMUM_EXCUTION_TIMEOUT_EXCEPTION, e.getCause().getMessage()); + assertEquals(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, e.getCause().getMessage()); } finally { try { blobOutputStream.close(); } catch (IOException e) { - assertEquals(SR.MAXIMUM_EXCUTION_TIMEOUT_EXCEPTION, e.getCause().getMessage()); + assertEquals(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, e.getCause().getMessage()); } } assertFalse(blockBlobRef.exists()); @@ -232,14 +342,14 @@ public void testMaximumExecutionTimeBlobWrites() throws URISyntaxException, Stor fail("Maximum execution time was reached but request did not fail."); } catch (IOException e) { - assertEquals(SR.MAXIMUM_EXCUTION_TIMEOUT_EXCEPTION, e.getCause().getMessage()); + assertEquals(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, e.getCause().getMessage()); } finally { try { blobOutputStream.close(); } catch (IOException e) { - assertEquals(SR.MAXIMUM_EXCUTION_TIMEOUT_EXCEPTION, e.getCause().getMessage()); + assertEquals(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, e.getCause().getMessage()); } } assertFalse(blockBlobRef.exists()); @@ -261,6 +371,49 @@ public void testMaximumExecutionTimeBlobWrites() throws URISyntaxException, Stor } } + @Test + @Category({ DevFabricTests.class, DevStoreTests.class, SlowTests.class }) + public void testMaximumExecutionTimeBlobByteArray() throws URISyntaxException, StorageException, IOException { + int length = 10 * 1024 * 1024; + byte[] uploadBuffer = BlobTestHelper.getRandomBuffer(length); + byte[] downloadBuffer = new byte[length]; + + // set a delay in sending request + OperationContext opContext = new OperationContext(); + setDelay(opContext, 2500); + + // set the maximum execution time + BlobRequestOptions options = new BlobRequestOptions(); + options.setMaximumExecutionTimeInMs(2000); + + CloudBlobClient blobClient = TestHelper.createCloudBlobClient(); + CloudBlobContainer container = blobClient.getContainerReference(generateRandomContainerName()); + + String blobName = "testBlob"; + final CloudBlockBlob blockBlobRef = container.getBlockBlobReference(blobName); + + ByteArrayInputStream inputStream = new ByteArrayInputStream(uploadBuffer); + + try { + container.createIfNotExists(); + + blockBlobRef.upload(inputStream, length); + assertTrue(blockBlobRef.exists()); + + try { + blockBlobRef.downloadToByteArray(downloadBuffer, 0, null, options, opContext); + fail("Maximum execution time was reached but request did not fail."); + } + catch (StorageException e) { + assertEquals(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, e.getCause().getMessage()); + } + } + finally { + inputStream.close(); + container.deleteIfExists(); + } + } + private static String generateRandomContainerName() { String containerName = "container" + UUID.randomUUID().toString(); return containerName.replace("-", ""); diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/LoggerTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/LoggerTests.java similarity index 97% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/LoggerTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/LoggerTests.java index 918b222eac74a..f56835c303bb4 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/LoggerTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/LoggerTests.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import static org.junit.Assert.*; @@ -29,10 +29,10 @@ import org.junit.experimental.categories.Category; import org.slf4j.LoggerFactory; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; -import com.microsoft.windowsazure.storage.core.Logger; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.core.Logger; /* * To run pass these tests you must: @@ -69,7 +69,7 @@ */ @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) @Ignore -public class LoggerTests extends TestBase { +public class LoggerTests { private final static String TRACE = "TRACE"; private final static String DEBUG = "DEBUG"; diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/MultiLocationTestHelper.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/MultiLocationTestHelper.java similarity index 98% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/MultiLocationTestHelper.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/MultiLocationTestHelper.java index 5035a5b17a758..ec85c0156df12 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/MultiLocationTestHelper.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/MultiLocationTestHelper.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import static org.junit.Assert.*; diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/SecondaryTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/SecondaryTests.java similarity index 94% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/SecondaryTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/SecondaryTests.java index cd43a07973055..c3b52529ced05 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/SecondaryTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/SecondaryTests.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import static org.junit.Assert.*; @@ -24,32 +24,32 @@ import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; -import com.microsoft.windowsazure.storage.TestRunners.SlowTests; -import com.microsoft.windowsazure.storage.blob.BlobRequestOptions; -import com.microsoft.windowsazure.storage.blob.BlobTestBase; -import com.microsoft.windowsazure.storage.blob.CloudBlobClient; -import com.microsoft.windowsazure.storage.blob.CloudBlobContainer; -import com.microsoft.windowsazure.storage.blob.CloudBlockBlob; -import com.microsoft.windowsazure.storage.blob.CloudPageBlob; -import com.microsoft.windowsazure.storage.blob.DeleteSnapshotsOption; -import com.microsoft.windowsazure.storage.queue.CloudQueue; -import com.microsoft.windowsazure.storage.queue.CloudQueueClient; -import com.microsoft.windowsazure.storage.queue.QueueRequestOptions; -import com.microsoft.windowsazure.storage.queue.QueueTestBase; -import com.microsoft.windowsazure.storage.table.CloudTable; -import com.microsoft.windowsazure.storage.table.CloudTableClient; -import com.microsoft.windowsazure.storage.table.TableRequestOptions; -import com.microsoft.windowsazure.storage.table.TableTestBase; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.TestRunners.SlowTests; +import com.microsoft.azure.storage.blob.BlobRequestOptions; +import com.microsoft.azure.storage.blob.BlobTestHelper; +import com.microsoft.azure.storage.blob.CloudBlobClient; +import com.microsoft.azure.storage.blob.CloudBlobContainer; +import com.microsoft.azure.storage.blob.CloudBlockBlob; +import com.microsoft.azure.storage.blob.CloudPageBlob; +import com.microsoft.azure.storage.blob.DeleteSnapshotsOption; +import com.microsoft.azure.storage.queue.CloudQueue; +import com.microsoft.azure.storage.queue.CloudQueueClient; +import com.microsoft.azure.storage.queue.QueueRequestOptions; +import com.microsoft.azure.storage.queue.QueueTestHelper; +import com.microsoft.azure.storage.table.CloudTable; +import com.microsoft.azure.storage.table.CloudTableClient; +import com.microsoft.azure.storage.table.TableRequestOptions; +import com.microsoft.azure.storage.table.TableTestHelper; @Category({ SecondaryTests.class, DevFabricTests.class, DevStoreTests.class, CloudTests.class }) -public class SecondaryTests extends TestBase { +public class SecondaryTests { @Test public void testLocationModeWithMissingUri() throws URISyntaxException, StorageException { - CloudBlobClient client = createCloudBlobClient(); + CloudBlobClient client = TestHelper.createCloudBlobClient(); CloudBlobClient primaryOnlyClient = new CloudBlobClient(client.getEndpoint(), client.getCredentials()); CloudBlobContainer container = primaryOnlyClient.getContainerReference("nonexistingcontainer"); @@ -88,7 +88,7 @@ public void testLocationModeWithMissingUri() throws URISyntaxException, StorageE @Test public void testBlobIfExistsShouldNotHitSecondary() throws StorageException, URISyntaxException { - CloudBlobContainer container = BlobTestBase.getRandomContainerReference(); + CloudBlobContainer container = BlobTestHelper.getRandomContainerReference(); BlobRequestOptions options = new BlobRequestOptions(); @@ -198,7 +198,7 @@ public void testBlobIfExistsShouldNotHitSecondary() throws StorageException, URI @Test public void testQueueIfExistsShouldNotHitSecondary() throws StorageException, URISyntaxException { - CloudQueueClient client = createCloudQueueClient(); + CloudQueueClient client = TestHelper.createCloudQueueClient(); CloudQueue queue = client.getQueueReference("nonexistantqueue"); @@ -257,7 +257,7 @@ public void testQueueIfExistsShouldNotHitSecondary() throws StorageException, UR @Test public void testTableIfExistsShouldNotHitSecondary() throws StorageException, URISyntaxException { - CloudTableClient client = createCloudTableClient(); + CloudTableClient client = TestHelper.createCloudTableClient(); CloudTable table = client.getTableReference("nonexistanttable"); TableRequestOptions options = new TableRequestOptions(); @@ -666,11 +666,11 @@ private static RetryInfo populateRetryInfo(RetryInfo retryInfo, StorageLocation private static void testContainerDownloadAttributes(LocationMode optionsLocationMode, LocationMode clientLocationMode, StorageLocation initialLocation, List retryContextList, List retryInfoList) throws URISyntaxException, StorageException { - CloudBlobContainer container = BlobTestBase.getRandomContainerReference(); + CloudBlobContainer container = BlobTestHelper.getRandomContainerReference(); MultiLocationTestHelper helper = new MultiLocationTestHelper(container.getServiceClient().getStorageUri(), initialLocation, retryContextList, retryInfoList); - container.getServiceClient().setLocationMode(clientLocationMode); + container.getServiceClient().getDefaultRequestOptions().setLocationMode(clientLocationMode); BlobRequestOptions options = new BlobRequestOptions(); options.setLocationMode(optionsLocationMode); @@ -690,13 +690,13 @@ private static void testContainerDownloadAttributes(LocationMode optionsLocation private static void testQueueDownloadAttributes(LocationMode optionsLocationMode, LocationMode clientLocationMode, StorageLocation initialLocation, List retryContextList, List retryInfoList) throws URISyntaxException, StorageException { - CloudQueueClient client = createCloudQueueClient(); - CloudQueue queue = client.getQueueReference(QueueTestBase.generateRandomQueueName()); + CloudQueueClient client = TestHelper.createCloudQueueClient(); + CloudQueue queue = client.getQueueReference(QueueTestHelper.generateRandomQueueName()); MultiLocationTestHelper helper = new MultiLocationTestHelper(queue.getServiceClient().getStorageUri(), initialLocation, retryContextList, retryInfoList); - queue.getServiceClient().setLocationMode(clientLocationMode); + queue.getServiceClient().getDefaultRequestOptions().setLocationMode(clientLocationMode); QueueRequestOptions options = new QueueRequestOptions(); options.setLocationMode(optionsLocationMode); @@ -716,13 +716,13 @@ private static void testQueueDownloadAttributes(LocationMode optionsLocationMode private static void testTableDownloadPermissions(LocationMode optionsLocationMode, LocationMode clientLocationMode, StorageLocation initialLocation, List retryContextList, List retryInfoList) throws URISyntaxException, StorageException { - CloudTableClient client = createCloudTableClient(); - CloudTable table = client.getTableReference(TableTestBase.generateRandomTableName()); + CloudTableClient client = TestHelper.createCloudTableClient(); + CloudTable table = client.getTableReference(TableTestHelper.generateRandomTableName()); MultiLocationTestHelper helper = new MultiLocationTestHelper(table.getServiceClient().getStorageUri(), initialLocation, retryContextList, retryInfoList); - table.getServiceClient().setLocationMode(clientLocationMode); + table.getServiceClient().getDefaultRequestOptions().setLocationMode(clientLocationMode); TableRequestOptions options = new TableRequestOptions(); options.setLocationMode(optionsLocationMode); diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/ServicePropertiesTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/ServicePropertiesTests.java similarity index 93% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/ServicePropertiesTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/ServicePropertiesTests.java index 00c9ae05eb4dd..40ea032654ab7 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/ServicePropertiesTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/ServicePropertiesTests.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import static org.junit.Assert.*; @@ -24,17 +24,17 @@ import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; -import com.microsoft.windowsazure.storage.TestRunners.SlowTests; -import com.microsoft.windowsazure.storage.blob.CloudBlobClient; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.queue.CloudQueueClient; -import com.microsoft.windowsazure.storage.table.CloudTableClient; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.TestRunners.SlowTests; +import com.microsoft.azure.storage.blob.CloudBlobClient; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.queue.CloudQueueClient; +import com.microsoft.azure.storage.table.CloudTableClient; @Category({ SlowTests.class, DevFabricTests.class, DevStoreTests.class, CloudTests.class }) -public class ServicePropertiesTests extends TestBase { +public class ServicePropertiesTests { /** * Test Analytics Disable Service Properties @@ -44,16 +44,16 @@ public class ServicePropertiesTests extends TestBase { */ @Test public void testAnalyticsDisable() throws StorageException, InterruptedException { - ServiceClient client = createCloudBlobClient(); + ServiceClient client = TestHelper.createCloudBlobClient(); ServiceProperties props = new ServiceProperties(); props.setDefaultServiceVersion("2013-08-15"); testAnalyticsDisable(client, props); - client = createCloudQueueClient(); + client = TestHelper.createCloudQueueClient(); props = new ServiceProperties(); testAnalyticsDisable(client, props); - client = createCloudTableClient(); + client = TestHelper.createCloudTableClient(); props = new ServiceProperties(); testAnalyticsDisable(client, props); } @@ -87,16 +87,16 @@ private void testAnalyticsDisable(ServiceClient client, ServiceProperties props) */ @Test public void testAnalyticsDefaultServiceVersion() throws StorageException, InterruptedException { - ServiceClient client = createCloudBlobClient(); + ServiceClient client = TestHelper.createCloudBlobClient(); ServiceProperties props = new ServiceProperties(); props.setDefaultServiceVersion("2013-08-15"); testAnalyticsDefaultServiceVersion(client, props); - client = createCloudQueueClient(); + client = TestHelper.createCloudQueueClient(); props = new ServiceProperties(); testAnalyticsDefaultServiceVersion(client, props); - client = createCloudTableClient(); + client = TestHelper.createCloudTableClient(); props = new ServiceProperties(); testAnalyticsDefaultServiceVersion(client, props); } @@ -147,16 +147,16 @@ private void testAnalyticsDefaultServiceVersion(ServiceClient client, ServicePro */ @Test public void testAnalyticsLoggingOperations() throws StorageException, InterruptedException { - ServiceClient client = createCloudBlobClient(); + ServiceClient client = TestHelper.createCloudBlobClient(); ServiceProperties props = new ServiceProperties(); props.setDefaultServiceVersion("2013-08-15"); testAnalyticsLoggingOperations(client, props); - client = createCloudQueueClient(); + client = TestHelper.createCloudQueueClient(); props = new ServiceProperties(); testAnalyticsLoggingOperations(client, props); - client = createCloudTableClient(); + client = TestHelper.createCloudTableClient(); props = new ServiceProperties(); testAnalyticsLoggingOperations(client, props); } @@ -187,16 +187,16 @@ private void testAnalyticsLoggingOperations(ServiceClient client, ServicePropert */ @Test public void testAnalyticsMetricsLevel() throws StorageException, InterruptedException { - ServiceClient client = createCloudBlobClient(); + ServiceClient client = TestHelper.createCloudBlobClient(); ServiceProperties props = new ServiceProperties(); props.setDefaultServiceVersion("2013-08-15"); testAnalyticsMetricsLevel(client, props); - client = createCloudQueueClient(); + client = TestHelper.createCloudQueueClient(); props = new ServiceProperties(); testAnalyticsMetricsLevel(client, props); - client = createCloudTableClient(); + client = TestHelper.createCloudTableClient(); props = new ServiceProperties(); testAnalyticsMetricsLevel(client, props); } @@ -232,16 +232,16 @@ private void testAnalyticsMetricsLevel(ServiceClient client, ServiceProperties p */ @Test public void testAnalyticsMinuteMetricsLevel() throws StorageException, InterruptedException { - ServiceClient client = createCloudBlobClient(); + ServiceClient client = TestHelper.createCloudBlobClient(); ServiceProperties props = new ServiceProperties(); props.setDefaultServiceVersion("2013-08-15"); testAnalyticsMinuteMetricsLevel(client, props); - client = createCloudQueueClient(); + client = TestHelper.createCloudQueueClient(); props = new ServiceProperties(); testAnalyticsMinuteMetricsLevel(client, props); - client = createCloudTableClient(); + client = TestHelper.createCloudTableClient(); props = new ServiceProperties(); testAnalyticsMinuteMetricsLevel(client, props); } @@ -277,16 +277,16 @@ private void testAnalyticsMinuteMetricsLevel(ServiceClient client, ServiceProper */ @Test public void testAnalyticsRetentionPolicies() throws StorageException, InterruptedException { - ServiceClient client = createCloudBlobClient(); + ServiceClient client = TestHelper.createCloudBlobClient(); ServiceProperties props = new ServiceProperties(); props.setDefaultServiceVersion("2013-08-15"); testAnalyticsRetentionPolicies(client, props); - client = createCloudQueueClient(); + client = TestHelper.createCloudQueueClient(); props = new ServiceProperties(); testAnalyticsRetentionPolicies(client, props); - client = createCloudTableClient(); + client = TestHelper.createCloudTableClient(); props = new ServiceProperties(); testAnalyticsRetentionPolicies(client, props); } @@ -357,16 +357,16 @@ private void testAnalyticsRetentionPolicies(ServiceClient client, ServicePropert */ @Test public void testCloudValidCorsRules() throws StorageException, InterruptedException { - ServiceClient client = createCloudBlobClient(); + ServiceClient client = TestHelper.createCloudBlobClient(); ServiceProperties props = new ServiceProperties(); props.setDefaultServiceVersion("2013-08-15"); testCloudValidCorsRules(client, props); - client = createCloudQueueClient(); + client = TestHelper.createCloudQueueClient(); props = new ServiceProperties(); testCloudValidCorsRules(client, props); - client = createCloudTableClient(); + client = TestHelper.createCloudTableClient(); props = new ServiceProperties(); testCloudValidCorsRules(client, props); } @@ -475,17 +475,17 @@ private void testCloudValidCorsRules(ServiceClient client, ServiceProperties pro * Test CORS with invalid values. */ @Test - public void testCorsExpectedExceptions() throws StorageException, InterruptedException { - ServiceClient client = createCloudBlobClient(); + public void testCorsExpectedExceptions() throws StorageException { + ServiceClient client = TestHelper.createCloudBlobClient(); ServiceProperties props = new ServiceProperties(); props.setDefaultServiceVersion("2013-08-15"); testCorsExpectedExceptions(client, props); - client = createCloudQueueClient(); + client = TestHelper.createCloudQueueClient(); props = new ServiceProperties(); testCorsExpectedExceptions(client, props); - client = createCloudTableClient(); + client = TestHelper.createCloudTableClient(); props = new ServiceProperties(); testCorsExpectedExceptions(client, props); } @@ -535,16 +535,16 @@ private void testCorsExpectedExceptions(ServiceClient client, ServiceProperties */ @Test public void testCorsMaxOrigins() throws StorageException, InterruptedException { - ServiceClient client = createCloudBlobClient(); + ServiceClient client = TestHelper.createCloudBlobClient(); ServiceProperties props = new ServiceProperties(); props.setDefaultServiceVersion("2013-08-15"); testCorsMaxOrigins(client, props); - client = createCloudQueueClient(); + client = TestHelper.createCloudQueueClient(); props = new ServiceProperties(); testCorsMaxOrigins(client, props); - client = createCloudTableClient(); + client = TestHelper.createCloudTableClient(); props = new ServiceProperties(); testCorsMaxOrigins(client, props); } @@ -582,16 +582,16 @@ private void testCorsMaxOrigins(ServiceClient client, ServiceProperties props) t */ @Test public void testCorsMaxHeaders() throws StorageException, InterruptedException { - ServiceClient client = createCloudBlobClient(); + ServiceClient client = TestHelper.createCloudBlobClient(); ServiceProperties props = new ServiceProperties(); props.setDefaultServiceVersion("2013-08-15"); testCorsMaxHeaders(client, props); - client = createCloudQueueClient(); + client = TestHelper.createCloudQueueClient(); props = new ServiceProperties(); testCorsMaxHeaders(client, props); - client = createCloudTableClient(); + client = TestHelper.createCloudTableClient(); props = new ServiceProperties(); testCorsMaxHeaders(client, props); } @@ -681,16 +681,16 @@ private void testCorsMaxHeaders(ServiceClient client, ServiceProperties props) t */ @Test public void testOptionalServiceProperties() throws StorageException, InterruptedException { - ServiceClient client = createCloudBlobClient(); + ServiceClient client = TestHelper.createCloudBlobClient(); ServiceProperties props = new ServiceProperties(); props.setDefaultServiceVersion("2013-08-15"); testOptionalServiceProperties(client, props); - client = createCloudQueueClient(); + client = TestHelper.createCloudQueueClient(); props = new ServiceProperties(); testOptionalServiceProperties(client, props); - client = createCloudTableClient(); + client = TestHelper.createCloudTableClient(); props = new ServiceProperties(); testOptionalServiceProperties(client, props); } diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/StorageAccountTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/StorageAccountTests.java similarity index 86% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/StorageAccountTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/StorageAccountTests.java index 92c1a723b6d65..189b568c4cefd 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/StorageAccountTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/StorageAccountTests.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import static org.junit.Assert.*; @@ -25,20 +25,20 @@ import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; -import com.microsoft.windowsazure.storage.blob.CloudBlobClient; -import com.microsoft.windowsazure.storage.blob.CloudBlobContainer; -import com.microsoft.windowsazure.storage.core.Base64; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.queue.CloudQueue; -import com.microsoft.windowsazure.storage.queue.CloudQueueClient; -import com.microsoft.windowsazure.storage.table.CloudTable; -import com.microsoft.windowsazure.storage.table.CloudTableClient; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.blob.CloudBlobClient; +import com.microsoft.azure.storage.blob.CloudBlobContainer; +import com.microsoft.azure.storage.core.Base64; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.queue.CloudQueue; +import com.microsoft.azure.storage.queue.CloudQueueClient; +import com.microsoft.azure.storage.table.CloudTable; +import com.microsoft.azure.storage.table.CloudTableClient; @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) -public class StorageAccountTests extends TestBase { +public class StorageAccountTests { public static String accountName = UUID.randomUUID().toString(); public static String accountKey = Base64.encode(UUID.randomUUID().toString().getBytes()); @@ -54,7 +54,7 @@ public void testStorageCredentialsAnonymous() throws URISyntaxException, Storage } @Test - public void testStorageCredentialsSharedKey() throws URISyntaxException { + public void testStorageCredentialsSharedKey() throws URISyntaxException, StorageException { StorageCredentialsAccountAndKey cred = new StorageCredentialsAccountAndKey(accountName, accountKey); assertEquals(accountName, cred.getAccountName()); @@ -195,9 +195,12 @@ public void testCloudStorageAccountDevelopmentStorageAccount() throws InvalidKey assertEquals(devstoreAccount.getTableStorageUri().getPrimaryUri(), new URI( "http://127.0.0.1:10002/devstoreaccount1")); - assertNull(devstoreAccount.getBlobStorageUri().getSecondaryUri()); - assertNull(devstoreAccount.getQueueStorageUri().getSecondaryUri()); - assertNull(devstoreAccount.getTableStorageUri().getSecondaryUri()); + assertEquals(devstoreAccount.getBlobStorageUri().getSecondaryUri(), new URI( + "http://127.0.0.1:10000/devstoreaccount1-secondary")); + assertEquals(devstoreAccount.getQueueStorageUri().getSecondaryUri(), new URI( + "http://127.0.0.1:10001/devstoreaccount1-secondary")); + assertEquals(devstoreAccount.getTableStorageUri().getSecondaryUri(), new URI( + "http://127.0.0.1:10002/devstoreaccount1-secondary")); String devstoreAccountToStringWithSecrets = devstoreAccount.toString(true); CloudStorageAccount testAccount = CloudStorageAccount.parse(devstoreAccountToStringWithSecrets); @@ -382,6 +385,33 @@ public void testCloudStorageAccountDefaultEndpointOverride() throws URISyntaxExc assertNull(account.getBlobStorageUri().getSecondaryUri()); } + @Test + public void testCloudStorageAccountDevStore() throws URISyntaxException { + // default + CloudStorageAccount account = CloudStorageAccount.getDevelopmentStorageAccount(); + assertEquals(new URI("http://127.0.0.1:10000/devstoreaccount1"), account.getBlobEndpoint()); + assertEquals(new URI("http://127.0.0.1:10001/devstoreaccount1"), account.getQueueEndpoint()); + assertEquals(new URI("http://127.0.0.1:10002/devstoreaccount1"), account.getTableEndpoint()); + assertEquals(new URI("http://127.0.0.1:10000/devstoreaccount1-secondary"), account.getBlobStorageUri() + .getSecondaryUri()); + assertEquals(new URI("http://127.0.0.1:10001/devstoreaccount1-secondary"), account.getQueueStorageUri() + .getSecondaryUri()); + assertEquals(new URI("http://127.0.0.1:10002/devstoreaccount1-secondary"), account.getTableStorageUri() + .getSecondaryUri()); + + // proxy + account = CloudStorageAccount.getDevelopmentStorageAccount(new URI("http://ipv4.fiddler")); + assertEquals(new URI("http://ipv4.fiddler:10000/devstoreaccount1"), account.getBlobEndpoint()); + assertEquals(new URI("http://ipv4.fiddler:10001/devstoreaccount1"), account.getQueueEndpoint()); + assertEquals(new URI("http://ipv4.fiddler:10002/devstoreaccount1"), account.getTableEndpoint()); + assertEquals(new URI("http://ipv4.fiddler:10000/devstoreaccount1-secondary"), account.getBlobStorageUri() + .getSecondaryUri()); + assertEquals(new URI("http://ipv4.fiddler:10001/devstoreaccount1-secondary"), account.getQueueStorageUri() + .getSecondaryUri()); + assertEquals(new URI("http://ipv4.fiddler:10002/devstoreaccount1-secondary"), account.getTableStorageUri() + .getSecondaryUri()); + } + @Test public void testCloudStorageAccountDevStoreProxyUri() throws InvalidKeyException, URISyntaxException { CloudStorageAccount account = CloudStorageAccount @@ -390,9 +420,12 @@ public void testCloudStorageAccountDevStoreProxyUri() throws InvalidKeyException assertEquals(new URI("http://ipv4.fiddler:10000/devstoreaccount1"), account.getBlobEndpoint()); assertEquals(new URI("http://ipv4.fiddler:10001/devstoreaccount1"), account.getQueueEndpoint()); assertEquals(new URI("http://ipv4.fiddler:10002/devstoreaccount1"), account.getTableEndpoint()); - assertNull(account.getBlobStorageUri().getSecondaryUri()); - assertNull(account.getQueueStorageUri().getSecondaryUri()); - assertNull(account.getTableStorageUri().getSecondaryUri()); + assertEquals(new URI("http://ipv4.fiddler:10000/devstoreaccount1-secondary"), account.getBlobStorageUri() + .getSecondaryUri()); + assertEquals(new URI("http://ipv4.fiddler:10001/devstoreaccount1-secondary"), account.getQueueStorageUri() + .getSecondaryUri()); + assertEquals(new URI("http://ipv4.fiddler:10002/devstoreaccount1-secondary"), account.getTableStorageUri() + .getSecondaryUri()); } @Test @@ -470,7 +503,7 @@ public void testCloudStorageAccountExportKey() throws InvalidKeyException, URISy String accountString = "BlobEndpoint=http://blobs/;AccountName=test;AccountKey=" + accountKeyString; CloudStorageAccount account = CloudStorageAccount.parse(accountString); StorageCredentialsAccountAndKey accountAndKey = (StorageCredentialsAccountAndKey) account.getCredentials(); - String key = accountAndKey.getBase64EncodedKey(); + String key = accountAndKey.getCredentials().getKey().getBase64EncodedKey(); assertEquals(accountKeyString, key); byte[] keyBytes = accountAndKey.getCredentials().exportKey(); diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/StorageUriTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/StorageUriTests.java similarity index 81% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/StorageUriTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/StorageUriTests.java index a7b16e49ac9aa..a4cdc065192df 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/StorageUriTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/StorageUriTests.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import static org.junit.Assert.*; @@ -23,22 +23,22 @@ import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; -import com.microsoft.windowsazure.storage.blob.CloudBlobClient; -import com.microsoft.windowsazure.storage.blob.CloudBlobContainer; -import com.microsoft.windowsazure.storage.blob.CloudBlobDirectory; -import com.microsoft.windowsazure.storage.blob.CloudBlockBlob; -import com.microsoft.windowsazure.storage.blob.CloudPageBlob; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.queue.CloudQueue; -import com.microsoft.windowsazure.storage.queue.CloudQueueClient; -import com.microsoft.windowsazure.storage.table.CloudTable; -import com.microsoft.windowsazure.storage.table.CloudTableClient; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.blob.CloudBlobClient; +import com.microsoft.azure.storage.blob.CloudBlobContainer; +import com.microsoft.azure.storage.blob.CloudBlobDirectory; +import com.microsoft.azure.storage.blob.CloudBlockBlob; +import com.microsoft.azure.storage.blob.CloudPageBlob; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.queue.CloudQueue; +import com.microsoft.azure.storage.queue.CloudQueueClient; +import com.microsoft.azure.storage.table.CloudTable; +import com.microsoft.azure.storage.table.CloudTableClient; @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) -public class StorageUriTests extends TestBase { +public class StorageUriTests { private static final String ACCOUNT_NAME = "account"; private static final String SECONDARY_SUFFIX = "-secondary"; @@ -89,6 +89,43 @@ public void testStorageUriWithTwoUris() throws URISyntaxException { assertFalse(multiUri.equals(multiUri5)); } + @Test + public void DevelopmentStorageWithTwoUris() throws URISyntaxException { + CloudStorageAccount account = CloudStorageAccount.getDevelopmentStorageAccount(); + URI primaryClientURI = account.getBlobStorageUri().getPrimaryUri(); + URI primaryContainerURI = new URI(primaryClientURI.toString() + "/container"); + URI secondaryClientURI = account.getBlobStorageUri().getSecondaryUri(); + + StorageUri singleURI = new StorageUri(primaryClientURI); + assertTrue(primaryClientURI.equals(singleURI.getPrimaryUri())); + assertNull(singleURI.getSecondaryUri()); + + StorageUri singleURI2 = new StorageUri(primaryClientURI); + assertTrue(singleURI.equals(singleURI2)); + + StorageUri singleURI3 = new StorageUri(secondaryClientURI); + assertFalse(singleURI.equals(singleURI3)); + + StorageUri multiURI = new StorageUri(primaryClientURI, secondaryClientURI); + assertTrue(primaryClientURI.equals(multiURI.getPrimaryUri())); + assertTrue(secondaryClientURI.equals(multiURI.getSecondaryUri())); + assertFalse(multiURI.equals(singleURI)); + + StorageUri multiURI2 = new StorageUri(primaryClientURI, secondaryClientURI); + assertTrue(multiURI.equals(multiURI2)); + + try { + new StorageUri(primaryClientURI, primaryContainerURI); + fail("StorageUri constructor should fail if both URIs do not point to the same resource"); + } + catch (IllegalArgumentException e) { + assertEquals(SR.STORAGE_URI_MUST_MATCH, e.getMessage()); + } + + StorageUri multiURI3 = new StorageUri(secondaryClientURI, primaryClientURI); + assertFalse(multiURI.equals(multiURI3)); + } + @Test public void testCloudStorageAccountWithStorageUri() throws URISyntaxException, InvalidKeyException { StorageUri blobEndpoint = new StorageUri(new URI("http://" + ACCOUNT_NAME + BLOB_SERVICE + ENDPOINT_SUFFIX), @@ -117,7 +154,7 @@ public void testCloudStorageAccountWithStorageUri() throws URISyntaxException, I @Test public void testBlobTypesWithStorageUri() throws StorageException, URISyntaxException { - CloudBlobClient blobClient = TestBase.createCloudBlobClient(); + CloudBlobClient blobClient = TestHelper.createCloudBlobClient(); StorageUri endpoint = new StorageUri(new URI("http://" + ACCOUNT_NAME + BLOB_SERVICE + ENDPOINT_SUFFIX), new URI("http://" + ACCOUNT_NAME + SECONDARY_SUFFIX + BLOB_SERVICE + ENDPOINT_SUFFIX)); @@ -192,7 +229,7 @@ public void testBlobTypesWithStorageUri() throws StorageException, URISyntaxExce @Test public void testQueueTypesWithStorageUri() throws URISyntaxException, StorageException { - CloudQueueClient queueClient = TestBase.createCloudQueueClient(); + CloudQueueClient queueClient = TestHelper.createCloudQueueClient(); StorageUri endpoint = new StorageUri(new URI("http://" + ACCOUNT_NAME + QUEUE_SERVICE + ENDPOINT_SUFFIX), new URI("http://" + ACCOUNT_NAME + SECONDARY_SUFFIX + QUEUE_SERVICE + ENDPOINT_SUFFIX)); @@ -216,7 +253,7 @@ public void testQueueTypesWithStorageUri() throws URISyntaxException, StorageExc @Test public void testTableTypesWithStorageUri() throws URISyntaxException, StorageException { - CloudTableClient tableClient = TestBase.createCloudTableClient(); + CloudTableClient tableClient = TestHelper.createCloudTableClient(); StorageUri endpoint = new StorageUri(new URI("http://" + ACCOUNT_NAME + TABLE_SERVICE + ENDPOINT_SUFFIX), new URI("http://" + ACCOUNT_NAME + SECONDARY_SUFFIX + TABLE_SERVICE + ENDPOINT_SUFFIX)); diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/Tenant.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/Tenant.java similarity index 98% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/Tenant.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/Tenant.java index b7c6e173f7aec..e0aa913f6b57f 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/Tenant.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/Tenant.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import java.net.URI; diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/TestBase.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/TestHelper.java similarity index 76% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/TestBase.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/TestHelper.java index d1adbc5e8bdea..92f4c47dccd19 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/TestBase.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/TestHelper.java @@ -12,31 +12,31 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; -import java.security.InvalidKeyException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; -import org.junit.BeforeClass; +import junit.framework.Assert; + import org.w3c.dom.DOMException; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; -import com.microsoft.windowsazure.storage.blob.CloudBlobClient; -import com.microsoft.windowsazure.storage.queue.CloudQueueClient; -import com.microsoft.windowsazure.storage.table.CloudTableClient; +import com.microsoft.azure.storage.blob.CloudBlobClient; +import com.microsoft.azure.storage.queue.CloudQueueClient; +import com.microsoft.azure.storage.table.CloudTableClient; -public class TestBase { +public class TestHelper { private static Tenant tenant; private static StorageCredentialsAccountAndKey credentials; @@ -46,14 +46,46 @@ public class TestBase { private final static boolean enableFiddler = true; private final static boolean requireSecondaryEndpoint = false; - @BeforeClass - public static void testBaseClassSetup() throws URISyntaxException, SAXException, IOException, - ParserConfigurationException, DOMException, InvalidKeyException { + public static CloudBlobClient createCloudBlobClient() throws StorageException { + CloudBlobClient client = getAccount().createCloudBlobClient(); + client.setAuthenticationScheme(defaultAuthenticationScheme); + return client; + } + + public static CloudQueueClient createCloudQueueClient() throws StorageException { + CloudQueueClient client = getAccount().createCloudQueueClient(); + client.setAuthenticationScheme(defaultAuthenticationScheme); + return client; + } + + public static CloudTableClient createCloudTableClient() throws StorageException { + CloudTableClient client = getAccount().createCloudTableClient(); + client.setAuthenticationScheme(defaultAuthenticationScheme); + return client; + } + + protected static void enableFiddler() { + System.setProperty("http.proxyHost", "localhost"); + System.setProperty("http.proxyPort", "8888"); + } + + public static void verifyServiceStats(ServiceStats stats) { + Assert.assertNotNull(stats); + if (stats.getGeoReplication().getLastSyncTime() != null) { + Assert.assertEquals(GeoReplicationStatus.LIVE, stats.getGeoReplication().getStatus()); + } + else { + Assert.assertTrue(stats.getGeoReplication().getStatus() == GeoReplicationStatus.BOOTSTRAP + || stats.getGeoReplication().getStatus() == GeoReplicationStatus.UNAVAILABLE); + } + } + + private static CloudStorageAccount getAccount() throws StorageException { // Only do this the first time TestBase is called as storage account is static if (account == null) { //enable fiddler if (enableFiddler) - TestHelper.enableFiddler(); + enableFiddler(); // try to get the environment variable with the connection string String cloudAccount; @@ -76,19 +108,25 @@ public static void testBaseClassSetup() throws URISyntaxException, SAXException, // if storageConnection is set, use that as an account string // if storageTestConfiguration is set, use that as a path to the configurations file // if neither are set, use the local configurations file at TestConfigurations.xml - if (cloudAccount != null) { - account = CloudStorageAccount.parse(cloudAccount); - } - else if (accountConfig != null) { - tenant = readTestConfigsFromXml(new File(accountConfig)); - setAccountAndCredentials(); + try { + if (cloudAccount != null) { + account = CloudStorageAccount.parse(cloudAccount); + } + else if (accountConfig != null) { + tenant = readTestConfigsFromXml(new File(accountConfig)); + setAccountAndCredentials(); + } + else { + URL localTestConfig = TestHelper.class.getClassLoader().getResource("TestConfigurations.xml"); + tenant = readTestConfigsFromXml(new File(localTestConfig.getPath())); + setAccountAndCredentials(); + } } - else { - URL localTestConfig = TestBase.class.getClassLoader().getResource("TestConfigurations.xml"); - tenant = readTestConfigsFromXml(new File(localTestConfig.getPath())); - setAccountAndCredentials(); + catch (Exception e) { + throw StorageException.translateException(null, e, null); } } + return account; } private static void setAccountAndCredentials() { @@ -176,22 +214,4 @@ else if (name.equals("TableServiceSecondaryEndpoint")) { } return tenant; } - - public static CloudBlobClient createCloudBlobClient() { - CloudBlobClient client = account.createCloudBlobClient(); - client.setAuthenticationScheme(defaultAuthenticationScheme); - return client; - } - - public static CloudQueueClient createCloudQueueClient() { - CloudQueueClient client = account.createCloudQueueClient(); - client.setAuthenticationScheme(defaultAuthenticationScheme); - return client; - } - - public static CloudTableClient createCloudTableClient() { - CloudTableClient client = account.createCloudTableClient(); - client.setAuthenticationScheme(defaultAuthenticationScheme); - return client; - } } diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/TestRunners.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/TestRunners.java similarity index 72% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/TestRunners.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/TestRunners.java index cb6132948906f..9e80936a6df7e 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/TestRunners.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/TestRunners.java @@ -1,4 +1,4 @@ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import org.junit.experimental.categories.Categories; import org.junit.experimental.categories.Categories.ExcludeCategory; @@ -7,24 +7,24 @@ import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; -import com.microsoft.windowsazure.storage.blob.CloudBlobClientTests; -import com.microsoft.windowsazure.storage.blob.CloudBlobContainerTests; -import com.microsoft.windowsazure.storage.blob.CloudBlobDirectoryTests; -import com.microsoft.windowsazure.storage.blob.CloudBlockBlobTests; -import com.microsoft.windowsazure.storage.blob.CloudPageBlobTests; -import com.microsoft.windowsazure.storage.blob.LeaseTests; -import com.microsoft.windowsazure.storage.blob.SasTests; -import com.microsoft.windowsazure.storage.queue.CloudQueueClientGB18030Test; -import com.microsoft.windowsazure.storage.queue.CloudQueueClientTests; -import com.microsoft.windowsazure.storage.queue.CloudQueueTests; -import com.microsoft.windowsazure.storage.table.TableBatchOperationTests; -import com.microsoft.windowsazure.storage.table.TableClientTests; -import com.microsoft.windowsazure.storage.table.TableEscapingTests; -import com.microsoft.windowsazure.storage.table.TableODataTests; -import com.microsoft.windowsazure.storage.table.TableOperationTests; -import com.microsoft.windowsazure.storage.table.TableQueryTests; -import com.microsoft.windowsazure.storage.table.TableSerializerTests; -import com.microsoft.windowsazure.storage.table.TableTests; +import com.microsoft.azure.storage.blob.CloudBlobClientTests; +import com.microsoft.azure.storage.blob.CloudBlobContainerTests; +import com.microsoft.azure.storage.blob.CloudBlobDirectoryTests; +import com.microsoft.azure.storage.blob.CloudBlockBlobTests; +import com.microsoft.azure.storage.blob.CloudPageBlobTests; +import com.microsoft.azure.storage.blob.LeaseTests; +import com.microsoft.azure.storage.blob.SasTests; +import com.microsoft.azure.storage.queue.CloudQueueClientGB18030Test; +import com.microsoft.azure.storage.queue.CloudQueueClientTests; +import com.microsoft.azure.storage.queue.CloudQueueTests; +import com.microsoft.azure.storage.table.TableBatchOperationTests; +import com.microsoft.azure.storage.table.TableClientTests; +import com.microsoft.azure.storage.table.TableEscapingTests; +import com.microsoft.azure.storage.table.TableODataTests; +import com.microsoft.azure.storage.table.TableOperationTests; +import com.microsoft.azure.storage.table.TableQueryTests; +import com.microsoft.azure.storage.table.TableSerializerTests; +import com.microsoft.azure.storage.table.TableTests; /** * Contains the various test suites and test categories used to run JUnit tests @@ -36,8 +36,8 @@ * mvn jar:jar and mvn jar:test-jar which will add a compiled source and compiled test jar to the target directory or * run mvn install -DskipTests=true which will add those jars to both the target directory and your local repository * directory. - * 4. Suite: java org.junit.runner.JUnitCore com.microsoft.windowsazure.storage.TestRunners$FastTestSuite - * 5. Class: java org.junit.runner.JUnitCore com.microsoft.windowsazure.storage.TableOperationTests + * 4. Suite: java org.junit.runner.JUnitCore com.microsoft.azure.storage.TestRunners$FastTestSuite + * 5. Class: java org.junit.runner.JUnitCore com.microsoft.azure.storage.TableOperationTests * 6. Test: can't do this natively; must make a runner * * To run with maven from command line: @@ -80,8 +80,8 @@ public interface DevFabricTests { // Test suites @RunWith(Suite.class) - @SuiteClasses({ GenericTests.class, LoggerTests.class, SecondaryTests.class, ServicePropertiesTests.class, - StorageAccountTests.class, StorageUriTests.class }) + @SuiteClasses({ EventFiringTests.class, GenericTests.class, LoggerTests.class, SecondaryTests.class, + ServicePropertiesTests.class, StorageAccountTests.class, StorageUriTests.class }) public static class CoreTestSuite { } diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/BlobTestBase.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/BlobTestHelper.java similarity index 87% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/BlobTestBase.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/BlobTestHelper.java index e8f15ebfc98de..0049baf800cd1 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/BlobTestBase.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/BlobTestHelper.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -27,14 +27,14 @@ import junit.framework.Assert; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.TestBase; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.TestHelper; /** * Blob Test Base */ -public class BlobTestBase extends TestBase { +public class BlobTestHelper extends TestHelper { protected static String generateRandomContainerName() { String containerName = "container" + UUID.randomUUID().toString(); @@ -43,7 +43,7 @@ protected static String generateRandomContainerName() { public static CloudBlobContainer getRandomContainerReference() throws URISyntaxException, StorageException { String containerName = generateRandomContainerName(); - CloudBlobClient bClient = createCloudBlobClient(); + CloudBlobClient bClient = TestHelper.createCloudBlobClient(); CloudBlobContainer container = bClient.getContainerReference(containerName); return container; @@ -109,7 +109,7 @@ public static ByteArrayInputStream getRandomDataStream(int length) { return new ByteArrayInputStream(buff); } - protected void doDownloadTest(CloudBlob blob, int blobSize, int bufferSize, int bufferOffset) + protected static void doDownloadTest(CloudBlob blob, int blobSize, int bufferSize, int bufferOffset) throws StorageException, IOException { final Random randGenerator = new Random(); final byte[] buffer = new byte[blobSize]; @@ -134,8 +134,8 @@ protected void doDownloadTest(CloudBlob blob, int blobSize, int bufferSize, int } } - protected void doDownloadRangeToByteArrayTest(CloudBlob blob, int blobSize, int bufferSize, int bufferOffset, - Long blobOffset, Long length) throws IOException, StorageException { + protected static void doDownloadRangeToByteArrayTest(CloudBlob blob, int blobSize, int bufferSize, + int bufferOffset, Long blobOffset, Long length) throws IOException, StorageException { final Random randGenerator = new Random(); final byte[] buffer = new byte[blobSize]; randGenerator.nextBytes(buffer); @@ -169,7 +169,7 @@ protected void doDownloadRangeToByteArrayTest(CloudBlob blob, int blobSize, int } } - protected void doDownloadRangeToByteArrayNegativeTests(CloudBlob blob) throws StorageException, IOException { + protected static void doDownloadRangeToByteArrayNegativeTests(CloudBlob blob) throws StorageException, IOException { int blobLength = 1024; int resultBufSize = 1024; final Random randGenerator = new Random(); @@ -230,6 +230,33 @@ protected void doDownloadRangeToByteArrayNegativeTests(CloudBlob blob) throws St } } + protected static void assertStreamsAreEqual(ByteArrayInputStream src, ByteArrayInputStream dst) { + dst.reset(); + src.reset(); + Assert.assertEquals(src.available(), dst.available()); + + while (src.available() > 0) { + Assert.assertEquals(src.read(), dst.read()); + } + } + + protected static void assertStreamsAreEqualAtIndex(ByteArrayInputStream src, ByteArrayInputStream dst, + int srcIndex, int dstIndex, int length, int bufferSize) throws IOException { + dst.reset(); + src.reset(); + + dst.skip(dstIndex); + src.skip(srcIndex); + byte[] origBuffer = new byte[bufferSize]; + byte[] retrBuffer = new byte[bufferSize]; + src.read(origBuffer); + dst.read(retrBuffer); + + for (int i = 0; i < length; i++) { + Assert.assertEquals(src.read(), dst.read()); + } + } + public static CloudBlockBlob defiddler(CloudBlockBlob blob) throws URISyntaxException, StorageException { URI oldUri = blob.getUri(); URI newUri = defiddler(oldUri); @@ -296,7 +323,7 @@ public static Map getBlockEntryList(int count) { return blocks; } - public void setBlobProperties(CloudBlob blob) { + public static void setBlobProperties(CloudBlob blob) { blob.getProperties().setCacheControl("no-transform"); blob.getProperties().setContentDisposition("attachment"); blob.getProperties().setContentEncoding("gzip"); diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/CloudBlobClientTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlobClientTests.java similarity index 65% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/CloudBlobClientTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlobClientTests.java index a43ee590a47a4..dd6be2f3cb1db 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/CloudBlobClientTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlobClientTests.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import static org.junit.Assert.*; @@ -24,34 +24,31 @@ import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.LocationMode; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.ResultContinuation; -import com.microsoft.windowsazure.storage.ResultSegment; -import com.microsoft.windowsazure.storage.SendingRequestEvent; -import com.microsoft.windowsazure.storage.StorageEvent; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.TestHelper; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.LocationMode; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.ResultContinuation; +import com.microsoft.azure.storage.ResultSegment; +import com.microsoft.azure.storage.SendingRequestEvent; +import com.microsoft.azure.storage.StorageEvent; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; /** * Blob Client Tests */ -public class CloudBlobClientTests extends BlobTestBase { +public class CloudBlobClientTests { /** * * @throws StorageException * @throws URISyntaxException - * @throws IOException - * @throws InterruptedException */ @Test @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) - public void testListContainersTest() throws StorageException, URISyntaxException, IOException, InterruptedException { - CloudBlobClient bClient = createCloudBlobClient(); + public void testListContainersTest() throws StorageException, URISyntaxException { + CloudBlobClient bClient = BlobTestHelper.createCloudBlobClient(); ArrayList containerList = new ArrayList(); String prefix = UUID.randomUUID().toString(); for (int i = 0; i < 30; i++) { @@ -87,35 +84,40 @@ public void testListContainersTest() throws StorageException, URISyntaxException @Test @Category({ CloudTests.class }) public void testGetServiceStats() throws StorageException { - CloudBlobClient bClient = createCloudBlobClient(); - bClient.setLocationMode(LocationMode.SECONDARY_ONLY); - TestHelper.verifyServiceStats(bClient.getServiceStats()); + CloudBlobClient bClient = BlobTestHelper.createCloudBlobClient(); + bClient.getDefaultRequestOptions().setLocationMode(LocationMode.SECONDARY_ONLY); + BlobTestHelper.verifyServiceStats(bClient.getServiceStats()); } @Test @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) public void testSingleBlobPutThresholdInBytes() throws URISyntaxException, StorageException, IOException { - CloudBlobClient bClient = createCloudBlobClient(); + CloudBlobClient bClient = BlobTestHelper.createCloudBlobClient(); try { - bClient.setSingleBlobPutThresholdInBytes(BlobConstants.MAX_SINGLE_UPLOAD_BLOB_SIZE_IN_BYTES + 1); + bClient.getDefaultRequestOptions().setSingleBlobPutThresholdInBytes( + BlobConstants.MAX_SINGLE_UPLOAD_BLOB_SIZE_IN_BYTES + 1); fail("Cannot set upload blob threshold above 64 MB"); } catch (IllegalArgumentException e) { - assertEquals("SingleBlobUploadThresholdInBytes", e.getMessage()); + assertEquals( + "The argument is out of range. Argument name: singleBlobPutThresholdInBytes, Value passed: 67108865.", + e.getMessage()); } try { - bClient.setSingleBlobPutThresholdInBytes(Constants.MB - 1); + bClient.getDefaultRequestOptions().setSingleBlobPutThresholdInBytes(Constants.MB - 1); fail("Cannot set upload blob threshold below 1 MB"); } catch (IllegalArgumentException e) { - assertEquals("SingleBlobUploadThresholdInBytes", e.getMessage()); + assertEquals( + "The argument is out of range. Argument name: singleBlobPutThresholdInBytes, Value passed: 1048575.", + e.getMessage()); } int maxSize = 2 * Constants.MB; - bClient.setSingleBlobPutThresholdInBytes(maxSize); + bClient.getDefaultRequestOptions().setSingleBlobPutThresholdInBytes(maxSize); final ArrayList callList = new ArrayList(); OperationContext sendingRequestEventContext = new OperationContext(); @@ -132,24 +134,24 @@ public void eventOccurred(SendingRequestEvent eventArg) { CloudBlobContainer container = null; try { - container = bClient.getContainerReference(BlobTestBase.generateRandomContainerName()); + container = bClient.getContainerReference(BlobTestHelper.generateRandomContainerName()); container.createIfNotExists(); - CloudBlockBlob blob = container.getBlockBlobReference(BlobTestBase + CloudBlockBlob blob = container.getBlockBlobReference(BlobTestHelper .generateRandomBlobNameWithPrefix("uploadThreshold")); // this should make a single call as it is less than the max - blob.upload(BlobTestBase.getRandomDataStream(maxSize - 1), maxSize - 1, null, null, + blob.upload(BlobTestHelper.getRandomDataStream(maxSize - 1), maxSize - 1, null, null, sendingRequestEventContext); assertEquals(1, callList.size()); // this should make one call as it is equal to the max - blob.upload(BlobTestBase.getRandomDataStream(maxSize), maxSize, null, null, sendingRequestEventContext); + blob.upload(BlobTestHelper.getRandomDataStream(maxSize), maxSize, null, null, sendingRequestEventContext); assertEquals(2, callList.size()); // this should make two calls as it is greater than the max - blob.upload(BlobTestBase.getRandomDataStream(maxSize + 1), maxSize + 1, null, null, + blob.upload(BlobTestHelper.getRandomDataStream(maxSize + 1), maxSize + 1, null, null, sendingRequestEventContext); assertEquals(4, callList.size()); diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/CloudBlobContainerTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlobContainerTests.java similarity index 80% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/CloudBlobContainerTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlobContainerTests.java index cd6ee20002b0f..67bc0b4ffb08d 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/CloudBlobContainerTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlobContainerTests.java @@ -12,11 +12,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import static org.junit.Assert.*; import java.io.IOException; +import java.net.HttpURLConnection; import java.net.URISyntaxException; import java.util.Calendar; import java.util.Date; @@ -30,35 +31,34 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.ResultContinuation; -import com.microsoft.windowsazure.storage.ResultSegment; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; -import com.microsoft.windowsazure.storage.TestRunners.SlowTests; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.ResultContinuation; +import com.microsoft.azure.storage.ResultSegment; +import com.microsoft.azure.storage.SendingRequestEvent; +import com.microsoft.azure.storage.StorageEvent; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.TestRunners.SlowTests; +import com.microsoft.azure.storage.core.SR; /** * Blob Container Tests */ @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) -public class CloudBlobContainerTests extends BlobTestBase { +public class CloudBlobContainerTests { protected static CloudBlobClient client; protected CloudBlobContainer container; - @BeforeClass - public static void blobContainerTestClassSetUp() { - client = createCloudBlobClient(); - } - @Before - public void blobContainerTestMethodSetUp() throws URISyntaxException, StorageException { - container = getRandomContainerReference(); + public void blobContainerTestMethodSetUp() throws StorageException, URISyntaxException { + container = BlobTestHelper.getRandomContainerReference(); } @After @@ -74,7 +74,7 @@ public void blobContainerTestMethodTearDown() throws StorageException { */ @Test public void testCloudBlobContainerReference() throws StorageException, URISyntaxException { - + CloudBlobClient client = BlobTestHelper.createCloudBlobClient(); CloudBlobContainer container = client.getContainerReference("container"); CloudBlockBlob blockBlob = container.getBlockBlobReference("directory1/blob1"); CloudPageBlob pageBlob = container.getPageBlobReference("directory2/blob2"); @@ -97,10 +97,9 @@ public void testCloudBlobContainerReference() throws StorageException, URISyntax * Create and delete a container * * @throws StorageException - * @throws URISyntaxException */ @Test - public void testCloudBlobContainerCreate() throws StorageException, URISyntaxException { + public void testCloudBlobContainerCreate() throws StorageException { container.create(); try { container.create(); @@ -116,10 +115,9 @@ public void testCloudBlobContainerCreate() throws StorageException, URISyntaxExc * Try to create a container after it is created * * @throws StorageException - * @throws URISyntaxException */ @Test - public void testCloudBlobContainerCreateIfNotExists() throws StorageException, URISyntaxException { + public void testCloudBlobContainerCreateIfNotExists() throws StorageException { assertTrue(container.createIfNotExists()); assertTrue(container.exists()); assertFalse(container.createIfNotExists()); @@ -128,11 +126,10 @@ public void testCloudBlobContainerCreateIfNotExists() throws StorageException, U /** * Try to delete a non-existing container * - * @throws URISyntaxException * @throws StorageException */ @Test - public void testCloudBlobContainerDeleteIfExists() throws URISyntaxException, StorageException { + public void testCloudBlobContainerDeleteIfExists() throws StorageException { assertFalse(container.deleteIfExists()); container.create(); assertTrue(container.deleteIfExists()); @@ -143,11 +140,10 @@ public void testCloudBlobContainerDeleteIfExists() throws URISyntaxException, St /** * Check a container's existence * - * @throws URISyntaxException * @throws StorageException */ @Test - public void testCloudBlobContainerExists() throws URISyntaxException, StorageException { + public void testCloudBlobContainerExists() throws StorageException { assertFalse(container.exists()); container.create(); @@ -167,8 +163,9 @@ public void testCloudBlobContainerExists() throws URISyntaxException, StorageExc */ @Test @Category(SlowTests.class) - public void testCloudBlobContainerSetPermissions() throws URISyntaxException, StorageException, - InterruptedException { + public void testCloudBlobContainerSetPermissions() throws StorageException, InterruptedException, + URISyntaxException { + CloudBlobClient client = BlobTestHelper.createCloudBlobClient(); container.create(); BlobContainerPermissions permissions = container.downloadPermissions(); @@ -208,7 +205,6 @@ public void testCloudBlobContainerSetPermissions() throws URISyntaxException, St /** * Get permissions from string - * */ @Test public void testCloudBlobContainerPermissionsFromString() { @@ -296,20 +292,68 @@ public void testCloudBlobContainerUploadMetadata() throws StorageException, URIS Assert.assertEquals(0, container2.getMetadata().size()); } + @Test + public void testCloudBlobContainerInvalidMetadata() throws StorageException { + // test client-side fails correctly + testMetadataFailures(container, null, "value1", true); + testMetadataFailures(container, "", "value1", true); + testMetadataFailures(container, " ", "value1", true); + testMetadataFailures(container, "\n \t", "value1", true); + + testMetadataFailures(container, "key1", null, false); + testMetadataFailures(container, "key1", "", false); + testMetadataFailures(container, "key1", " ", false); + testMetadataFailures(container, "key1", "\n \t", false); + + // test client can get empty metadata + container.create(); + + OperationContext opContext = new OperationContext(); + opContext.getSendingRequestEventHandler().addListener(new StorageEvent() { + // insert a metadata element with an empty value + @Override + public void eventOccurred(SendingRequestEvent eventArg) { + HttpURLConnection request = (HttpURLConnection) eventArg.getConnectionObject(); + request.setRequestProperty(Constants.HeaderConstants.PREFIX_FOR_STORAGE_METADATA + "key1", ""); + } + }); + container.uploadMetadata(null, null, opContext); + + container.downloadAttributes(); + assertEquals(1, container.getMetadata().size()); + assertEquals("", container.getMetadata().get("key1")); + } + + private static void testMetadataFailures(CloudBlobContainer container, String key, String value, boolean badKey) { + container.getMetadata().put(key, value); + try { + container.uploadMetadata(); + fail(SR.METADATA_KEY_INVALID); + } + catch (StorageException e) { + if (badKey) { + assertEquals(SR.METADATA_KEY_INVALID, e.getMessage()); + } + else { + assertEquals(SR.METADATA_VALUE_INVALID, e.getMessage()); + } + + } + container.getMetadata().remove(key); + } + /** * List the blobs in a container * * @throws URISyntaxException * @throws StorageException * @throws IOException - * @throws InterruptedException */ @Test - public void testCloudBlobContainerListBlobs() throws URISyntaxException, StorageException, IOException, - InterruptedException { + public void testCloudBlobContainerListBlobs() throws StorageException, IOException, URISyntaxException { container.create(); int numBlobs = 200; - List blobNames = uploadNewBlobs(container, BlobType.BLOCK_BLOB, numBlobs, 128, null); + List blobNames = BlobTestHelper.uploadNewBlobs(container, BlobType.BLOCK_BLOB, numBlobs, 128, null); assertEquals(numBlobs, blobNames.size()); @@ -344,28 +388,34 @@ public void testCloudBlobContainerListBlobs() throws URISyntaxException, Storage * @throws InterruptedException */ @Test - public void testCloudBlobContainerListBlobsOptions() throws URISyntaxException, StorageException, IOException, - InterruptedException { + public void testCloudBlobContainerListBlobsOptions() throws StorageException, IOException, InterruptedException, + URISyntaxException { container.create(); final int length = 128; // regular blob - CloudBlockBlob originalBlob = (CloudBlockBlob) uploadNewBlob(container, BlobType.BLOCK_BLOB, "originalBlob", - length, null); + CloudBlockBlob originalBlob = (CloudBlockBlob) BlobTestHelper.uploadNewBlob(container, BlobType.BLOCK_BLOB, + "originalBlob", length, null); + + // leased blob + CloudBlockBlob leasedBlob = (CloudBlockBlob) BlobTestHelper.uploadNewBlob(container, BlobType.BLOCK_BLOB, + "originalBlobLeased", length, null); + leasedBlob.acquireLease(null, null); // copy of regular blob - CloudBlockBlob copyBlob = container.getBlockBlobReference(generateRandomBlobNameWithPrefix("originalBlobCopy")); + CloudBlockBlob copyBlob = container.getBlockBlobReference(BlobTestHelper + .generateRandomBlobNameWithPrefix("originalBlobCopy")); copyBlob.startCopyFromBlob(originalBlob); - waitForCopy(copyBlob); + BlobTestHelper.waitForCopy(copyBlob); // snapshot of regular blob CloudBlockBlob blobSnapshot = (CloudBlockBlob) originalBlob.createSnapshot(); // snapshot of the copy of the regular blob - CloudBlockBlob copySnapshot = container - .getBlockBlobReference(generateRandomBlobNameWithPrefix("originalBlobSnapshotCopy")); + CloudBlockBlob copySnapshot = container.getBlockBlobReference(BlobTestHelper + .generateRandomBlobNameWithPrefix("originalBlobSnapshotCopy")); copySnapshot.startCopyFromBlob(copyBlob); - waitForCopy(copySnapshot); + BlobTestHelper.waitForCopy(copySnapshot); int count = 0; for (ListBlobItem item : container.listBlobs("originalBlob", true, EnumSet.allOf(BlobListingDetails.class), @@ -374,6 +424,9 @@ public void testCloudBlobContainerListBlobsOptions() throws URISyntaxException, if (blob.getName().equals(originalBlob.getName()) && !blob.isSnapshot()) { assertCreatedAndListedBlobsEquivalent(originalBlob, blob, length); } + else if (blob.getName().equals(leasedBlob.getName())) { + assertCreatedAndListedBlobsEquivalent(leasedBlob, blob, length); + } else if (blob.getName().equals(copyBlob.getName())) { assertCreatedAndListedBlobsEquivalent(copyBlob, blob, length); } @@ -388,16 +441,15 @@ else if (blob.getName().equals(copySnapshot.getName())) { } count++; } - assertEquals(4, count); + assertEquals(5, count); } /** * @throws StorageException - * @throws URISyntaxException * @throws InterruptedException */ @Test - public void testCloudBlobContainerSharedKeyLite() throws StorageException, URISyntaxException, InterruptedException { + public void testCloudBlobContainerSharedKeyLite() throws StorageException, InterruptedException { BlobContainerPermissions expectedPermissions; BlobContainerPermissions testPermissions; diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/CloudBlobDirectoryTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlobDirectoryTests.java similarity index 96% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/CloudBlobDirectoryTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlobDirectoryTests.java index 7d2a16e852477..32b569efbadd0 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/CloudBlobDirectoryTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlobDirectoryTests.java @@ -1,4 +1,4 @@ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import static org.junit.Assert.*; @@ -12,22 +12,21 @@ import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.ResultContinuation; -import com.microsoft.windowsazure.storage.ResultSegment; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.TestBase; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; -import com.microsoft.windowsazure.storage.core.PathUtility; +import com.microsoft.azure.storage.ResultContinuation; +import com.microsoft.azure.storage.ResultSegment; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.core.PathUtility; @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) -public class CloudBlobDirectoryTests extends BlobTestBase { +public class CloudBlobDirectoryTests { private static final String[] delimiters = { "$", ":", "@", "-", "%", "/", "|", "//", "%%", " " }; @Test - public void testGetDirectoryAbsoluteUriAppended() throws URISyntaxException, StorageException, IOException { + public void testGetDirectoryAbsoluteUriAppended() throws URISyntaxException, StorageException { for (int i = 0; i < delimiters.length; i++) { CloudBlobContainer container = null; try { @@ -41,7 +40,7 @@ public void testGetDirectoryAbsoluteUriAppended() throws URISyntaxException, Sto } private void testGetDirectoryAbsoluteUriAppended(String delimiter, CloudBlobContainer container) - throws URISyntaxException, StorageException { + throws URISyntaxException { CloudBlobDirectory dir = container.getDirectoryReference(container.getUri().toString()); assertEquals(PathUtility.appendPathToSingleUri(container.getUri(), container.getUri().toString() + delimiter), dir.getUri()); @@ -53,7 +52,7 @@ private void testGetDirectoryAbsoluteUriAppended(String delimiter, CloudBlobCont } @Test - public void testFlatListingWithContainer() throws URISyntaxException, StorageException, IOException { + public void testFlatListingWithContainer() throws URISyntaxException, StorageException { for (int i = 0; i < delimiters.length; i++) { CloudBlobContainer container = null; try { @@ -162,7 +161,7 @@ private void testFlatListingWithContainer(String delimiter, CloudBlobContainer c } @Test - public void testListingWithDirectory() throws URISyntaxException, StorageException, IOException { + public void testListingWithDirectory() throws URISyntaxException, StorageException { for (int i = 0; i < delimiters.length; i++) { CloudBlobContainer container = null; try { @@ -202,7 +201,7 @@ private void testListingWithDirectory(String delimiter, CloudBlobContainer conta } @Test - public void testListingWithDirectorySegmented() throws URISyntaxException, StorageException, IOException { + public void testListingWithDirectorySegmented() throws URISyntaxException, StorageException { for (int i = 0; i < delimiters.length; i++) { CloudBlobContainer container = null; try { @@ -238,7 +237,7 @@ private void testListingWithDirectorySegmented(String delimiter, CloudBlobContai } @Test - public void testPrefixListingWithDirectory() throws URISyntaxException, StorageException, IOException { + public void testPrefixListingWithDirectory() throws URISyntaxException, StorageException { for (int i = 0; i < delimiters.length; i++) { CloudBlobContainer container = null; try { @@ -276,7 +275,7 @@ private void testPrefixListingWithDirectory(String delimiter, CloudBlobContainer } @Test - public void testPrefixListingWithDirectorySegmented() throws URISyntaxException, StorageException, IOException { + public void testPrefixListingWithDirectorySegmented() throws URISyntaxException, StorageException { for (int i = 0; i < delimiters.length; i++) { CloudBlobContainer container = null; try { @@ -312,7 +311,7 @@ private void testPrefixListingWithDirectorySegmented(String delimiter, CloudBlob } @Test - public void testFlatListingWithDirectory() throws URISyntaxException, StorageException, IOException { + public void testFlatListingWithDirectory() throws URISyntaxException, StorageException { for (int i = 0; i < delimiters.length; i++) { CloudBlobContainer container = null; try { @@ -378,7 +377,7 @@ private void testFlatListingWithDirectory(String delimiter, CloudBlobContainer c } @Test - public void testFlatListingWithDirectorySegmented() throws URISyntaxException, StorageException, IOException { + public void testFlatListingWithDirectorySegmented() throws URISyntaxException, StorageException { for (int i = 0; i < delimiters.length; i++) { CloudBlobContainer container = null; try { @@ -443,7 +442,7 @@ private void testFlatListingWithDirectorySegmented(String delimiter, CloudBlobCo } @Test - public void testGetParent() throws URISyntaxException, StorageException, IOException { + public void testGetParent() throws URISyntaxException, StorageException { for (int i = 0; i < delimiters.length; i++) { CloudBlobContainer container = null; try { @@ -503,7 +502,7 @@ private void testGetReferences(String delimiter, CloudBlobContainer container) t assertEquals("Dir1" + delimiter, pageParent.getPrefix()); CloudBlockBlob blockBlob = dir1.getBlockBlobReference("BlockBlob"); - blockBlob.upload(BlobTestBase.getRandomDataStream(128), 128); + blockBlob.upload(BlobTestHelper.getRandomDataStream(128), 128); assertTrue(blockBlob.exists()); assertEquals(dir1.getContainer().getName(), pageBlob.getContainer().getName()); assertEquals(dir1.getServiceClient().getEndpoint().toString(), blockBlob.getServiceClient().getEndpoint() @@ -544,7 +543,7 @@ private void testGetReferences(String delimiter, CloudBlobContainer container) t } @Test - public void testGetSubdirectoryAndTraverseBackToParent() throws URISyntaxException, StorageException, IOException { + public void testGetSubdirectoryAndTraverseBackToParent() throws URISyntaxException, StorageException { for (int i = 0; i < delimiters.length; i++) { CloudBlobContainer container = null; try { @@ -567,7 +566,7 @@ private void testGetSubdirectoryAndTraverseBackToParent(String delimiter, CloudB } @Test - public void testGetParentOnRoot() throws URISyntaxException, StorageException, IOException { + public void testGetParentOnRoot() throws URISyntaxException, StorageException { for (int i = 0; i < delimiters.length; i++) { CloudBlobContainer container = null; try { @@ -612,7 +611,7 @@ private void testGetParentOnRoot(String delimiter, CloudBlobContainer container) } @Test - public void testHierarchicalTraversal() throws URISyntaxException, StorageException, IOException { + public void testHierarchicalTraversal() throws URISyntaxException, StorageException { for (int i = 0; i < delimiters.length; i++) { CloudBlobContainer container = null; try { @@ -648,7 +647,7 @@ private void testHierarchicalTraversal(String delimiter, CloudBlobContainer cont } @Test - public void testParentValidate() throws URISyntaxException, StorageException, IOException { + public void testParentValidate() throws URISyntaxException, StorageException { for (int i = 0; i < delimiters.length; i++) { CloudBlobContainer container = null; try { @@ -673,14 +672,14 @@ private void testParentValidate(String delimiter, CloudBlobContainer container) } @Test - public void testValidateInRootContainer() throws URISyntaxException, StorageException, IOException { + public void testValidateInRootContainer() throws URISyntaxException, StorageException { for (int i = 0; i < delimiters.length; i++) { testValidateInRootContainer(delimiters[i]); } } private void testValidateInRootContainer(String delimiter) throws URISyntaxException, StorageException { - CloudBlobClient client = TestBase.createCloudBlobClient(); + CloudBlobClient client = BlobTestHelper.createCloudBlobClient(); client.setDirectoryDelimiter(delimiter); CloudBlobContainer container = client.getContainerReference("$root"); @@ -728,7 +727,7 @@ private void testValidateInRootContainer(String delimiter) throws URISyntaxExcep } @Test - public void testDelimitersInARow() throws URISyntaxException, StorageException, IOException { + public void testDelimitersInARow() throws URISyntaxException, StorageException { for (int i = 0; i < delimiters.length; i++) { CloudBlobContainer container = null; try { @@ -769,7 +768,7 @@ private void testDelimitersInARow(String delimiter, CloudBlobContainer container } @Test - public void testMultipleDelimiters() throws URISyntaxException, StorageException, IOException { + public void testMultipleDelimiters() throws URISyntaxException, StorageException { for (int i = 0; i < delimiters.length; i++) { CloudBlobContainer container = null; try { @@ -843,9 +842,9 @@ private static void populateContainer(CloudBlobContainer container, String delim } private static CloudBlobContainer createContainer(String delimiter) throws URISyntaxException, StorageException { - CloudBlobClient client = TestBase.createCloudBlobClient(); + CloudBlobClient client = BlobTestHelper.createCloudBlobClient(); client.setDirectoryDelimiter(delimiter); - String name = BlobTestBase.generateRandomContainerName(); + String name = BlobTestHelper.generateRandomContainerName(); CloudBlobContainer container = client.getContainerReference(name); container.create(); return container; diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/CloudBlockBlobTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlockBlobTests.java similarity index 84% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/CloudBlockBlobTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlockBlobTests.java index 54f075ae6a596..c73e3ceddda0d 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/CloudBlockBlobTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlockBlobTests.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import static org.junit.Assert.*; @@ -35,8 +35,6 @@ import java.util.Random; import java.util.TimeZone; -import javax.xml.stream.XMLStreamException; - import junit.framework.Assert; import org.junit.After; @@ -44,32 +42,31 @@ import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.AccessCondition; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.RetryNoRetry; -import com.microsoft.windowsazure.storage.SendingRequestEvent; -import com.microsoft.windowsazure.storage.StorageCredentialsSharedAccessSignature; -import com.microsoft.windowsazure.storage.StorageEvent; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.TestHelper; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; -import com.microsoft.windowsazure.storage.TestRunners.SlowTests; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.AccessCondition; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.RetryNoRetry; +import com.microsoft.azure.storage.SendingRequestEvent; +import com.microsoft.azure.storage.StorageCredentialsSharedAccessSignature; +import com.microsoft.azure.storage.StorageEvent; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.TestRunners.SlowTests; +import com.microsoft.azure.storage.core.Utility; /** * Block Blob Tests */ @Category(CloudTests.class) -public class CloudBlockBlobTests extends BlobTestBase { +public class CloudBlockBlobTests { protected CloudBlobContainer container; @Before public void blockBlobTestMethodSetup() throws URISyntaxException, StorageException { - container = getRandomContainerReference(); + container = BlobTestHelper.getRandomContainerReference(); container.create(); } @@ -114,7 +111,7 @@ public void testCopyBlockBlobWithMetadataOverride() throws URISyntaxException, S String data = "String data"; CloudBlockBlob source = container.getBlockBlobReference("source"); - setBlobProperties(source); + BlobTestHelper.setBlobProperties(source); source.uploadText(data, Constants.UTF8_CHARSET, null, null, null); @@ -123,8 +120,8 @@ public void testCopyBlockBlobWithMetadataOverride() throws URISyntaxException, S CloudBlockBlob copy = container.getBlockBlobReference("copy"); copy.getMetadata().put("Test2", "value2"); - String copyId = copy.startCopyFromBlob(defiddler(source)); - waitForCopy(copy); + String copyId = copy.startCopyFromBlob(BlobTestHelper.defiddler(source)); + BlobTestHelper.waitForCopy(copy); assertEquals(CopyStatus.SUCCESS, copy.getCopyState().getStatus()); assertEquals(source.getQualifiedUri().getPath(), copy.getCopyState().getSource().getPath()); @@ -161,7 +158,7 @@ public void testCopyBlockBlobFromSnapshot() throws StorageException, IOException CloudBlockBlob source = container.getBlockBlobReference("source"); String data = "String data"; - setBlobProperties(source); + BlobTestHelper.setBlobProperties(source); source.uploadText(data, Constants.UTF8_CHARSET, null, null, null); @@ -185,8 +182,8 @@ public void testCopyBlockBlobFromSnapshot() throws StorageException, IOException assertFalse(source.getMetadata().get("Test").equals(snapshot.getMetadata().get("Test"))); CloudBlockBlob copy = container.getBlockBlobReference("copy"); - String copyId = copy.startCopyFromBlob(defiddler(snapshot)); - waitForCopy(copy); + String copyId = copy.startCopyFromBlob(BlobTestHelper.defiddler(snapshot)); + BlobTestHelper.waitForCopy(copy); copy.downloadAttributes(); @@ -220,10 +217,10 @@ public void testCopyBlockBlobFromSnapshot() throws StorageException, IOException */ @Test @Category({ DevFabricTests.class, DevStoreTests.class }) - public void testCopyFromBlobAbortTest() throws StorageException, URISyntaxException, IOException, - InterruptedException { + public void testCopyFromBlobAbortTest() throws StorageException, URISyntaxException, IOException { final int length = 128; - CloudBlob originalBlob = uploadNewBlob(container, BlobType.BLOCK_BLOB, "originalBlob", length, null); + CloudBlob originalBlob = BlobTestHelper.uploadNewBlob(container, BlobType.BLOCK_BLOB, "originalBlob", length, + null); CloudBlob copyBlob = container.getBlockBlobReference(originalBlob.getName() + "copyed"); copyBlob.startCopyFromBlob(originalBlob); @@ -247,11 +244,10 @@ public void testCopyFromBlobAbortTest() throws StorageException, URISyntaxExcept */ @Test @Category({ DevFabricTests.class, DevStoreTests.class }) - public void testBlobSnapshotValidationTest() throws StorageException, URISyntaxException, IOException, - InterruptedException { + public void testBlobSnapshotValidationTest() throws StorageException, URISyntaxException, IOException { final int length = 1024; - CloudBlockBlob blockBlobRef = (CloudBlockBlob) uploadNewBlob(container, BlobType.BLOCK_BLOB, "originalBlob", - length, null); + CloudBlockBlob blockBlobRef = (CloudBlockBlob) BlobTestHelper.uploadNewBlob(container, BlobType.BLOCK_BLOB, + "originalBlob", length, null); final CloudBlob blobSnapshot = blockBlobRef.createSnapshot(); for (ListBlobItem blob : container.listBlobs(null, true, EnumSet.allOf(BlobListingDetails.class), null, null)) { @@ -324,22 +320,21 @@ public void testBlobSnapshotValidationTest() throws StorageException, URISyntaxE * @throws URISyntaxException * @throws IOException * @throws InterruptedException - * @throws XMLStreamException */ @Test @Category({ DevFabricTests.class, DevStoreTests.class }) - public void testBlobDownloadRangeValidationTest() throws StorageException, URISyntaxException, IOException, - InterruptedException { + public void testBlobDownloadRangeValidationTest() throws StorageException, URISyntaxException, IOException { final int blockLength = 1024 * 1024; final int length = 5 * blockLength; - final String blockBlobName = generateRandomBlobNameWithPrefix("testBlockBlob"); + final String blockBlobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlockBlob"); final CloudBlockBlob blockBlobRef = container.getBlockBlobReference(blockBlobName); ArrayList blockList = new ArrayList(); for (int i = 1; i <= 5; i++) { String blockID = String.format("%08d", i); - blockBlobRef.uploadBlock(blockID, getRandomDataStream(length), blockLength, null, null, null); + blockBlobRef + .uploadBlock(blockID, BlobTestHelper.getRandomDataStream(length), blockLength, null, null, null); blockList.add(new BlockEntry(blockID, BlockSearchMode.LATEST)); } @@ -363,10 +358,10 @@ public void testBlobDownloadRangeValidationTest() throws StorageException, URISy @Category({ DevFabricTests.class, DevStoreTests.class }) public void testDownloadBlockList() throws URISyntaxException, StorageException, IOException { int length = 1024; - byte[] buffer = getRandomBuffer(length); - Map blocks = BlobTestBase.getBlockEntryList(3); - Map extraBlocks = BlobTestBase.getBlockEntryList(2); - String blobName = BlobTestBase.generateRandomBlobNameWithPrefix("blob1"); + byte[] buffer = BlobTestHelper.getRandomBuffer(length); + Map blocks = BlobTestHelper.getBlockEntryList(3); + Map extraBlocks = BlobTestHelper.getBlockEntryList(2); + String blobName = BlobTestHelper.generateRandomBlobNameWithPrefix("blob1"); CloudBlockBlob blob = container.getBlockBlobReference(blobName); for (BlockEntry block : blocks.values()) { @@ -385,7 +380,7 @@ public void testDownloadBlockList() throws URISyntaxException, StorageException, List blockList = blob2.downloadBlockList(); assertEquals(3, blockList.size()); for (BlockEntry blockItem : blockList) { - assertEquals(BlockSearchMode.COMMITTED, blockItem.searchMode); + assertEquals(BlockSearchMode.COMMITTED, blockItem.getSearchMode()); assertEquals(length, blockItem.getSize()); assertFalse(blocks.remove(blockItem.getId()) == null); } @@ -394,7 +389,7 @@ public void testDownloadBlockList() throws URISyntaxException, StorageException, blockList = blob2.downloadBlockList(BlockListingFilter.UNCOMMITTED, null, null, null); assertEquals(2, blockList.size()); for (BlockEntry blockItem : blockList) { - assertEquals(BlockSearchMode.UNCOMMITTED, blockItem.searchMode); + assertEquals(BlockSearchMode.UNCOMMITTED, blockItem.getSearchMode()); assertEquals(length, blockItem.getSize()); assertFalse(extraBlocks.remove(blockItem.getId()) == null); } @@ -404,7 +399,7 @@ public void testDownloadBlockList() throws URISyntaxException, StorageException, @Test @Category({ DevFabricTests.class, DevStoreTests.class }) public void testBlockBlobDownloadRangeTest() throws URISyntaxException, StorageException, IOException { - byte[] buffer = getRandomBuffer(2 * 1024); + byte[] buffer = BlobTestHelper.getRandomBuffer(2 * 1024); CloudBlockBlob blob = container.getBlockBlobReference("blob1"); ByteArrayInputStream wholeBlob = new ByteArrayInputStream(buffer); @@ -420,8 +415,8 @@ public void testBlockBlobDownloadRangeTest() throws URISyntaxException, StorageE blob.downloadRange(0, new Long(1024), blobStream); assertEquals(blobStream.size(), 1024); - TestHelper.assertStreamsAreEqualAtIndex(new ByteArrayInputStream(blobStream.toByteArray()), wholeBlob, 0, 0, - 1024, 2 * 1024); + BlobTestHelper.assertStreamsAreEqualAtIndex(new ByteArrayInputStream(blobStream.toByteArray()), wholeBlob, 0, + 0, 1024, 2 * 1024); CloudBlockBlob blob2 = container.getBlockBlobReference("blob1"); try { @@ -433,44 +428,44 @@ public void testBlockBlobDownloadRangeTest() throws URISyntaxException, StorageE ByteArrayOutputStream blobStream2 = new ByteArrayOutputStream(); blob2.downloadRange(1024, new Long(1024), blobStream2); - TestHelper.assertStreamsAreEqualAtIndex(new ByteArrayInputStream(blobStream2.toByteArray()), wholeBlob, 1024, - 1024, 1024, 2 * 1024); + BlobTestHelper.assertStreamsAreEqualAtIndex(new ByteArrayInputStream(blobStream2.toByteArray()), wholeBlob, + 1024, 1024, 1024, 2 * 1024); blob2.downloadAttributes(); - assertAreEqual(blob, blob2); + BlobTestHelper.assertAreEqual(blob, blob2); } @Test @Category({ DevFabricTests.class, DevStoreTests.class }) public void testBlobUploadFromStreamTest() throws URISyntaxException, StorageException, IOException { - final String blockBlobName = generateRandomBlobNameWithPrefix("testBlockBlob"); + final String blockBlobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlockBlob"); final CloudBlockBlob blockBlobRef = container.getBlockBlobReference(blockBlobName); int length = 2 * 1024; - ByteArrayInputStream srcStream = getRandomDataStream(length); + ByteArrayInputStream srcStream = BlobTestHelper.getRandomDataStream(length); blockBlobRef.upload(srcStream, -1); ByteArrayOutputStream dstStream = new ByteArrayOutputStream(); blockBlobRef.download(dstStream); - TestHelper.assertStreamsAreEqual(srcStream, new ByteArrayInputStream(dstStream.toByteArray())); + BlobTestHelper.assertStreamsAreEqual(srcStream, new ByteArrayInputStream(dstStream.toByteArray())); length = 5 * 1024 * 1024; - srcStream = getRandomDataStream(length); + srcStream = BlobTestHelper.getRandomDataStream(length); blockBlobRef.upload(srcStream, length); dstStream = new ByteArrayOutputStream(); blockBlobRef.download(dstStream); - TestHelper.assertStreamsAreEqual(srcStream, new ByteArrayInputStream(dstStream.toByteArray())); + BlobTestHelper.assertStreamsAreEqual(srcStream, new ByteArrayInputStream(dstStream.toByteArray())); } @Test @Category({ DevFabricTests.class, DevStoreTests.class }) public void testBlobUploadFromStreamRequestOptionsTest() throws URISyntaxException, StorageException, IOException { - final String blockBlobName1 = generateRandomBlobNameWithPrefix("testBlockBlob"); + final String blockBlobName1 = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlockBlob"); final CloudBlockBlob blockBlobRef1 = container.getBlockBlobReference(blockBlobName1); - final String blockBlobName2 = generateRandomBlobNameWithPrefix("testBlockBlob"); + final String blockBlobName2 = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlockBlob"); final CloudBlockBlob blockBlobRef2 = container.getBlockBlobReference(blockBlobName2); - final int length = 2 * com.microsoft.windowsazure.storage.Constants.MB; - ByteArrayInputStream srcStream = getRandomDataStream(length); + final int length = 2 * com.microsoft.azure.storage.Constants.MB; + ByteArrayInputStream srcStream = BlobTestHelper.getRandomDataStream(length); BlobRequestOptions options = new BlobRequestOptions(); options.setSingleBlobPutThresholdInBytes(length / 2); @@ -498,15 +493,15 @@ public void testUploadDownloadBlobProperties() throws URISyntaxException, Storag options.setDisableContentMD5Validation(true); // with explicit upload/download of properties - String blockBlobName1 = generateRandomBlobNameWithPrefix("testBlockBlob"); + String blockBlobName1 = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlockBlob"); CloudBlockBlob blockBlobRef1 = container.getBlockBlobReference(blockBlobName1); - blockBlobRef1.upload(getRandomDataStream(length), length); + blockBlobRef1.upload(BlobTestHelper.getRandomDataStream(length), length); // this is not set by upload (it is for page blob!), so set this manually blockBlobRef1.getProperties().setLength(length); - setBlobProperties(blockBlobRef1); + BlobTestHelper.setBlobProperties(blockBlobRef1); BlobProperties props1 = blockBlobRef1.getProperties(); blockBlobRef1.uploadProperties(); @@ -514,31 +509,31 @@ public void testUploadDownloadBlobProperties() throws URISyntaxException, Storag BlobProperties props2 = blockBlobRef1.getProperties(); Assert.assertEquals(props1.getLength(), props2.getLength()); - assertAreEqual(props1, props2); + BlobTestHelper.assertAreEqual(props1, props2); // by uploading/downloading the blob - blockBlobName1 = generateRandomBlobNameWithPrefix("testBlockBlob"); + blockBlobName1 = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlockBlob"); blockBlobRef1 = container.getBlockBlobReference(blockBlobName1); - setBlobProperties(blockBlobRef1); + BlobTestHelper.setBlobProperties(blockBlobRef1); props1 = blockBlobRef1.getProperties(); - blockBlobRef1.upload(getRandomDataStream(length), length); + blockBlobRef1.upload(BlobTestHelper.getRandomDataStream(length), length); blockBlobRef1.download(new ByteArrayOutputStream(), null, options, null); props2 = blockBlobRef1.getProperties(); - assertAreEqual(props1, props2); + BlobTestHelper.assertAreEqual(props1, props2); } @Test @Category({ DevFabricTests.class, DevStoreTests.class }) public void testBlobUploadWithoutMD5Validation() throws URISyntaxException, StorageException, IOException { - final String blockBlobName = generateRandomBlobNameWithPrefix("testBlockBlob"); + final String blockBlobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlockBlob"); final CloudBlockBlob blockBlobRef = container.getBlockBlobReference(blockBlobName); final int length = 2 * 1024; - ByteArrayInputStream srcStream = getRandomDataStream(length); + ByteArrayInputStream srcStream = BlobTestHelper.getRandomDataStream(length); BlobRequestOptions options = new BlobRequestOptions(); options.setDisableContentMD5Validation(false); options.setStoreBlobContentMD5(false); @@ -564,11 +559,11 @@ public void testBlobUploadWithoutMD5Validation() throws URISyntaxException, Stor @Test @Category({ DevFabricTests.class, DevStoreTests.class }) public void testBlockBlobUploadContentMD5() throws URISyntaxException, StorageException, IOException { - final String blockBlobName = generateRandomBlobNameWithPrefix("testBlockBlob"); + final String blockBlobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlockBlob"); CloudBlockBlob blockBlobRef = container.getBlockBlobReference(blockBlobName); int length = 16 * 1024; - ByteArrayInputStream srcStream = getRandomDataStream(length); + ByteArrayInputStream srcStream = BlobTestHelper.getRandomDataStream(length); final ArrayList callList = new ArrayList(); OperationContext sendingRequestEventContext = new OperationContext(); @@ -601,7 +596,7 @@ public void eventOccurred(SendingRequestEvent eventArg) { }; length = 33 * 1024 * 1024; - srcStream = getRandomDataStream(length); + srcStream = BlobTestHelper.getRandomDataStream(length); sendingRequestEventContext.getSendingRequestEventHandler().addListener(event); assertEquals(0, callList.size()); @@ -614,11 +609,11 @@ public void eventOccurred(SendingRequestEvent eventArg) { @Test @Category({ DevFabricTests.class, DevStoreTests.class }) public void testBlobEmptyHeaderSigningTest() throws URISyntaxException, StorageException, IOException { - final String blockBlobName = generateRandomBlobNameWithPrefix("testBlockBlob"); + final String blockBlobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlockBlob"); final CloudBlockBlob blockBlobRef = container.getBlockBlobReference(blockBlobName); final int length = 2 * 1024; - ByteArrayInputStream srcStream = getRandomDataStream(length); + ByteArrayInputStream srcStream = BlobTestHelper.getRandomDataStream(length); OperationContext context = new OperationContext(); context.getSendingRequestEventHandler().addListener(new StorageEvent() { @@ -638,47 +633,50 @@ public void eventOccurred(SendingRequestEvent eventArg) { @Category({ DevFabricTests.class, DevStoreTests.class }) public void testCloudBlockBlobDownloadToByteArray() throws URISyntaxException, StorageException, IOException { CloudBlockBlob blob = container.getBlockBlobReference("blob1"); - this.doDownloadTest(blob, 1 * 512, 2 * 512, 0); - this.doDownloadTest(blob, 1 * 512, 2 * 512, 1 * 512); - this.doDownloadTest(blob, 2 * 512, 4 * 512, 1 * 512); - this.doDownloadTest(blob, 5 * 1024 * 1024, 5 * 1024 * 1024, 0); - this.doDownloadTest(blob, 5 * 1024 * 1024, 6 * 1024 * 1024, 512); + BlobTestHelper.doDownloadTest(blob, 1 * 512, 2 * 512, 0); + BlobTestHelper.doDownloadTest(blob, 1 * 512, 2 * 512, 1 * 512); + BlobTestHelper.doDownloadTest(blob, 2 * 512, 4 * 512, 1 * 512); + BlobTestHelper.doDownloadTest(blob, 5 * 1024 * 1024, 5 * 1024 * 1024, 0); + BlobTestHelper.doDownloadTest(blob, 5 * 1024 * 1024, 6 * 1024 * 1024, 512); } @Test @Category({ DevFabricTests.class, DevStoreTests.class }) public void testCloudBlockBlobDownloadRangeToByteArray() throws URISyntaxException, StorageException, IOException { - CloudBlockBlob blob = container.getBlockBlobReference(generateRandomBlobNameWithPrefix("downloadrange")); - - this.doDownloadRangeToByteArrayTest(blob, 8 * 1024 * 1024, 8 * 1024 * 1024, 1 * 1024 * 1024, new Long( - 1 * 1024 * 1024), new Long(5 * 1024 * 1024)); - this.doDownloadRangeToByteArrayTest(blob, 8 * 1024 * 1024, 8 * 1024 * 1024, 2 * 1024 * 1024, new Long( - 2 * 1024 * 1024), new Long(6 * 1024 * 1024)); - this.doDownloadRangeToByteArrayTest(blob, 8 * 1024 * 1024, 8 * 1024 * 1024, 1 * 1024 * 1024, new Long( - 4 * 1024 * 1024), new Long(4 * 1024 * 1024)); - - this.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 0, new Long(1 * 512), new Long(1 * 512)); - this.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 1 * 512, new Long(0), null); - this.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 1 * 512, new Long(1 * 512), null); - this.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 1 * 512, new Long(0), new Long(1 * 512)); - this.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 2 * 512, new Long(1 * 512), new Long(1 * 512)); - this.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 2 * 512, new Long(1 * 512), new Long(2 * 512)); + CloudBlockBlob blob = container.getBlockBlobReference(BlobTestHelper + .generateRandomBlobNameWithPrefix("downloadrange")); + + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 8 * 1024 * 1024, 8 * 1024 * 1024, 1 * 1024 * 1024, + new Long(1 * 1024 * 1024), new Long(5 * 1024 * 1024)); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 8 * 1024 * 1024, 8 * 1024 * 1024, 2 * 1024 * 1024, + new Long(2 * 1024 * 1024), new Long(6 * 1024 * 1024)); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 8 * 1024 * 1024, 8 * 1024 * 1024, 1 * 1024 * 1024, + new Long(4 * 1024 * 1024), new Long(4 * 1024 * 1024)); + + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 0, new Long(1 * 512), new Long(1 * 512)); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 1 * 512, new Long(0), null); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 1 * 512, new Long(1 * 512), null); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 1 * 512, new Long(0), new Long(1 * 512)); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 2 * 512, new Long(1 * 512), new Long( + 1 * 512)); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 2 * 512, new Long(1 * 512), new Long( + 2 * 512)); // Edge cases - this.doDownloadRangeToByteArrayTest(blob, 1024, 1024, 1023, new Long(1023), new Long(1)); - this.doDownloadRangeToByteArrayTest(blob, 1024, 1024, 0, new Long(1023), new Long(1)); - this.doDownloadRangeToByteArrayTest(blob, 1024, 1024, 0, new Long(0), new Long(1)); - this.doDownloadRangeToByteArrayTest(blob, 1024, 1024, 0, new Long(512), new Long(1)); - this.doDownloadRangeToByteArrayTest(blob, 1024, 1024, 512, new Long(1023), new Long(1)); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 1024, 1024, 1023, new Long(1023), new Long(1)); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 1024, 1024, 0, new Long(1023), new Long(1)); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 1024, 1024, 0, new Long(0), new Long(1)); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 1024, 1024, 0, new Long(512), new Long(1)); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 1024, 1024, 512, new Long(1023), new Long(1)); } @Test @Category({ DevFabricTests.class, DevStoreTests.class }) public void testCloudBlockBlobDownloadRangeToByteArrayNegativeTest() throws URISyntaxException, StorageException, IOException { - CloudBlockBlob blob = container - .getBlockBlobReference(generateRandomBlobNameWithPrefix("downloadrangenegative")); - this.doDownloadRangeToByteArrayNegativeTests(blob); + CloudBlockBlob blob = container.getBlockBlobReference(BlobTestHelper + .generateRandomBlobNameWithPrefix("downloadrangenegative")); + BlobTestHelper.doDownloadRangeToByteArrayNegativeTests(blob); } @Test @@ -689,13 +687,13 @@ public void testCloudBlockBlobUploadFromStreamWithAccessCondition() throws URISy AccessCondition accessCondition = AccessCondition.generateIfNoneMatchCondition("\"*\""); final int length = 2 * 1024 * 1024; - ByteArrayInputStream srcStream = getRandomDataStream(length); + ByteArrayInputStream srcStream = BlobTestHelper.getRandomDataStream(length); blob1.upload(srcStream, length, accessCondition, null, null); blob1.downloadAttributes(); - CloudBlockBlob blob2 = (CloudBlockBlob) uploadNewBlob(container, BlobType.BLOCK_BLOB, "accesscond", length, - null); + CloudBlockBlob blob2 = (CloudBlockBlob) BlobTestHelper.uploadNewBlob(container, BlobType.BLOCK_BLOB, + "accesscond", length, null); blob2.downloadAttributes(); srcStream.reset(); @@ -737,12 +735,12 @@ public void testBlobNamePlusEncodingTest() throws StorageException, URISyntaxExc InterruptedException { final int length = 1 * 1024; - final CloudBlockBlob originalBlob = (CloudBlockBlob) uploadNewBlob(container, BlobType.BLOCK_BLOB, "a+b.txt", - length, null); + final CloudBlockBlob originalBlob = (CloudBlockBlob) BlobTestHelper.uploadNewBlob(container, + BlobType.BLOCK_BLOB, "a+b.txt", length, null); final CloudBlob copyBlob = container.getBlockBlobReference(originalBlob.getName() + "copyed"); copyBlob.startCopyFromBlob(originalBlob); - waitForCopy(copyBlob); + BlobTestHelper.waitForCopy(copyBlob); copyBlob.downloadAttributes(); } @@ -754,8 +752,7 @@ public void testBlobNamePlusEncodingTest() throws StorageException, URISyntaxExc */ @Test @Category({ DevFabricTests.class, DevStoreTests.class }) - public void testSendingRequestEventBlob() throws StorageException, URISyntaxException, IOException, - InterruptedException { + public void testSendingRequestEventBlob() throws StorageException, URISyntaxException, IOException { final int length = 128; final ArrayList callList = new ArrayList(); @@ -772,7 +769,8 @@ public void eventOccurred(SendingRequestEvent eventArg) { assertEquals(0, callList.size()); //Put blob - CloudBlob blob = uploadNewBlob(container, BlobType.BLOCK_BLOB, "bb", length, sendingRequestEventContext); + CloudBlob blob = BlobTestHelper.uploadNewBlob(container, BlobType.BLOCK_BLOB, "bb", length, + sendingRequestEventContext); assertEquals(1, callList.size()); @@ -800,7 +798,7 @@ public void eventOccurred(SendingRequestEvent eventArg) { public void testBlobInputStream() throws URISyntaxException, StorageException, IOException { final int blobLength = 16 * 1024; final Random randGenerator = new Random(); - String blobName = generateRandomBlobNameWithPrefix("testblob"); + String blobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testblob"); final CloudBlockBlob blobRef = container.getBlockBlobReference(blobName); final byte[] buff = new byte[blobLength]; @@ -832,8 +830,8 @@ public void testBlobInputStream() throws URISyntaxException, StorageException, I @Test public void testBlobOutputStream() throws URISyntaxException, StorageException, IOException { int blobLengthToUse = 8 * 512; - byte[] buffer = CloudPageBlobTests.getRandomBuffer(8 * 512); - String blobName = generateRandomBlobNameWithPrefix("testblob"); + byte[] buffer = BlobTestHelper.getRandomBuffer(8 * 512); + String blobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testblob"); CloudBlockBlob blockBlob = container.getBlockBlobReference(blobName); BlobOutputStream str = blockBlob.openOutputStream(); @@ -869,7 +867,7 @@ public void testBlobOutputStream() throws URISyntaxException, StorageException, @Test @Category({ DevFabricTests.class, DevStoreTests.class }) public void testUploadFromByteArray() throws Exception { - String blobName = generateRandomBlobNameWithPrefix("testblob"); + String blobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testblob"); final CloudBlockBlob blob = container.getBlockBlobReference(blobName); this.doUploadFromByteArrayTest(blob, 4 * 512, 0, 4 * 512); @@ -881,7 +879,7 @@ public void testUploadFromByteArray() throws Exception { private void doUploadFromByteArrayTest(CloudBlockBlob blob, int bufferSize, int bufferOffset, int count) throws Exception { - byte[] buffer = getRandomBuffer(bufferSize); + byte[] buffer = BlobTestHelper.getRandomBuffer(bufferSize); byte[] downloadedBuffer = new byte[bufferSize]; blob.uploadFromByteArray(buffer, bufferOffset, count); @@ -900,7 +898,7 @@ private void doUploadFromByteArrayTest(CloudBlockBlob blob, int bufferSize, int @Test @Category({ DevFabricTests.class, DevStoreTests.class }) public void testUploadDownloadFromFile() throws IOException, StorageException, URISyntaxException { - String blobName = generateRandomBlobNameWithPrefix("testblob"); + String blobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testblob"); final CloudBlockBlob blob = container.getBlockBlobReference(blobName); this.doUploadDownloadFileTest(blob, 0); @@ -916,7 +914,7 @@ private void doUploadDownloadFileTest(CloudBlockBlob blob, int fileSize) throws try { - byte[] buffer = getRandomBuffer(fileSize); + byte[] buffer = BlobTestHelper.getRandomBuffer(fileSize); FileOutputStream fos = new FileOutputStream(sourceFile); fos.write(buffer); fos.close(); @@ -949,7 +947,7 @@ private void doUploadDownloadFileTest(CloudBlockBlob blob, int fileSize) throws @Test @Category({ DevFabricTests.class, DevStoreTests.class }) public void testUploadDownloadFromText() throws URISyntaxException, StorageException, IOException { - String blobName = generateRandomBlobNameWithPrefix("testblob"); + String blobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testblob"); final CloudBlockBlob blob = container.getBlockBlobReference(blobName); this.doUploadDownloadStringTest(blob, 0); @@ -959,11 +957,11 @@ public void testUploadDownloadFromText() throws URISyntaxException, StorageExcep @Test @Category({ DevFabricTests.class, DevStoreTests.class }) public void testBlobMultiConditionHeaders() throws URISyntaxException, StorageException, IOException { - final String blockBlobName = generateRandomBlobNameWithPrefix("testBlockBlob"); + final String blockBlobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlockBlob"); final CloudBlockBlob blockBlobRef = container.getBlockBlobReference(blockBlobName); final int length = 2 * 1024; - ByteArrayInputStream srcStream = getRandomDataStream(length); + ByteArrayInputStream srcStream = BlobTestHelper.getRandomDataStream(length); OperationContext context = new OperationContext(); blockBlobRef.upload(srcStream, -1, null, null, context); @@ -988,8 +986,8 @@ public void eventOccurred(SendingRequestEvent eventArg) { @Test @Category({ DevFabricTests.class, DevStoreTests.class }) public void testBlobConditionalAccess() throws StorageException, IOException, URISyntaxException { - CloudBlockBlob blob = (CloudBlockBlob) BlobTestBase.uploadNewBlob(container, BlobType.BLOCK_BLOB, "test", 128, - null); + CloudBlockBlob blob = (CloudBlockBlob) BlobTestHelper.uploadNewBlob(container, BlobType.BLOCK_BLOB, "test", + 128, null); blob.downloadAttributes(); String currentETag = blob.getProperties().getEtag(); @@ -1232,7 +1230,7 @@ private void doCloudBlockBlobCopy(boolean sourceIsSas, boolean destinationIsSas) // Start copy and wait for completion String copyId = copyDestination.startCopyFromBlob(copySource); - waitForCopy(copyDestination); + BlobTestHelper.waitForCopy(copyDestination); Calendar calendar = Calendar.getInstance(Utility.UTC_ZONE); destination.downloadAttributes(); diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/CloudPageBlobTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudPageBlobTests.java similarity index 79% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/CloudPageBlobTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudPageBlobTests.java index 960ddace6b6d0..fbc75c95ec292 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/CloudPageBlobTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudPageBlobTests.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import static org.junit.Assert.*; @@ -30,8 +30,6 @@ import java.util.EnumSet; import java.util.Random; -import javax.xml.stream.XMLStreamException; - import junit.framework.Assert; import org.junit.After; @@ -39,26 +37,25 @@ import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.AccessCondition; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.RetryNoRetry; -import com.microsoft.windowsazure.storage.SendingRequestEvent; -import com.microsoft.windowsazure.storage.StorageEvent; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.TestHelper; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.AccessCondition; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.RetryNoRetry; +import com.microsoft.azure.storage.SendingRequestEvent; +import com.microsoft.azure.storage.StorageEvent; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) -public class CloudPageBlobTests extends BlobTestBase { +public class CloudPageBlobTests { protected CloudBlobContainer container; @Before public void pageBlobTestMethodSetup() throws URISyntaxException, StorageException { - container = getRandomContainerReference(); + container = BlobTestHelper.getRandomContainerReference(); container.create(); } @@ -76,10 +73,10 @@ public void pageBlobTestMethodTearDown() throws StorageException { * @throws InterruptedException */ @Test - public void testCopyFromPageBlobAbortTest() throws StorageException, URISyntaxException, IOException, - InterruptedException { + public void testCopyFromPageBlobAbortTest() throws StorageException, URISyntaxException, IOException { final int length = 512; - CloudBlob originalBlob = uploadNewBlob(container, BlobType.PAGE_BLOB, "originalBlob", length, null); + CloudBlob originalBlob = BlobTestHelper.uploadNewBlob(container, BlobType.PAGE_BLOB, "originalBlob", length, + null); CloudBlob copyBlob = container.getPageBlobReference(originalBlob.getName() + "copyed"); copyBlob.startCopyFromBlob(originalBlob); @@ -102,11 +99,10 @@ public void testCopyFromPageBlobAbortTest() throws StorageException, URISyntaxEx * @throws InterruptedException */ @Test - public void testPageBlobSnapshotValidationTest() throws StorageException, URISyntaxException, IOException, - InterruptedException { + public void testPageBlobSnapshotValidationTest() throws StorageException, URISyntaxException, IOException { final int length = 1024; - CloudPageBlob blockBlobRef = (CloudPageBlob) uploadNewBlob(container, BlobType.PAGE_BLOB, "originalBlob", - length, null); + CloudPageBlob blockBlobRef = (CloudPageBlob) BlobTestHelper.uploadNewBlob(container, BlobType.PAGE_BLOB, + "originalBlob", length, null); final CloudBlob blobSnapshot = blockBlobRef.createSnapshot(); for (ListBlobItem blob : container.listBlobs(null, true, EnumSet.allOf(BlobListingDetails.class), null, null)) { @@ -179,17 +175,15 @@ public void testPageBlobSnapshotValidationTest() throws StorageException, URISyn * @throws URISyntaxException * @throws IOException * @throws InterruptedException - * @throws XMLStreamException */ @Test - public void testPageBlobDownloadRangeValidationTest() throws StorageException, URISyntaxException, IOException, - InterruptedException { + public void testPageBlobDownloadRangeValidationTest() throws StorageException, URISyntaxException, IOException { final int length = 5 * 1024 * 1024; - final String blockBlobName = generateRandomBlobNameWithPrefix("testBlockBlob"); + final String blockBlobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlockBlob"); final CloudPageBlob pageBlobRef = container.getPageBlobReference(blockBlobName); - pageBlobRef.upload(getRandomDataStream(length), length); + pageBlobRef.upload(BlobTestHelper.getRandomDataStream(length), length); //Download full blob pageBlobRef.download(new ByteArrayOutputStream()); @@ -204,31 +198,31 @@ public void testPageBlobDownloadRangeValidationTest() throws StorageException, U @Test public void testPageBlobUploadFromStreamTest() throws URISyntaxException, StorageException, IOException { - final String pageBlobName = generateRandomBlobNameWithPrefix("testPageBlob"); + final String pageBlobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testPageBlob"); final CloudPageBlob pageBlobRef = container.getPageBlobReference(pageBlobName); int length = 2 * 1024; - ByteArrayInputStream srcStream = getRandomDataStream(length); + ByteArrayInputStream srcStream = BlobTestHelper.getRandomDataStream(length); pageBlobRef.upload(srcStream, length); ByteArrayOutputStream dstStream = new ByteArrayOutputStream(); pageBlobRef.download(dstStream); - TestHelper.assertStreamsAreEqual(srcStream, new ByteArrayInputStream(dstStream.toByteArray())); + BlobTestHelper.assertStreamsAreEqual(srcStream, new ByteArrayInputStream(dstStream.toByteArray())); length = 5 * 1024 * 1024; - srcStream = getRandomDataStream(length); + srcStream = BlobTestHelper.getRandomDataStream(length); pageBlobRef.upload(srcStream, length); dstStream = new ByteArrayOutputStream(); pageBlobRef.download(dstStream); - TestHelper.assertStreamsAreEqual(srcStream, new ByteArrayInputStream(dstStream.toByteArray())); + BlobTestHelper.assertStreamsAreEqual(srcStream, new ByteArrayInputStream(dstStream.toByteArray())); } @Test public void testBlobUploadWithoutMD5Validation() throws URISyntaxException, StorageException, IOException { - final String pageBlobName = generateRandomBlobNameWithPrefix("testPageBlob"); + final String pageBlobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testPageBlob"); final CloudPageBlob pageBlobRef = container.getPageBlobReference(pageBlobName); final int length = 2 * 1024; - ByteArrayInputStream srcStream = getRandomDataStream(length); + ByteArrayInputStream srcStream = BlobTestHelper.getRandomDataStream(length); BlobRequestOptions options = new BlobRequestOptions(); options.setDisableContentMD5Validation(false); options.setStoreBlobContentMD5(false); @@ -253,11 +247,11 @@ public void testBlobUploadWithoutMD5Validation() throws URISyntaxException, Stor @Test public void testBlobEmptyHeaderSigningTest() throws URISyntaxException, StorageException, IOException { - final String pageBlobName = generateRandomBlobNameWithPrefix("testPageBlob"); + final String pageBlobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testPageBlob"); final CloudPageBlob pageBlobRef = container.getPageBlobReference(pageBlobName); final int length = 2 * 1024; - ByteArrayInputStream srcStream = getRandomDataStream(length); + ByteArrayInputStream srcStream = BlobTestHelper.getRandomDataStream(length); OperationContext context = new OperationContext(); context.getSendingRequestEventHandler().addListener(new StorageEvent() { @@ -275,7 +269,7 @@ public void eventOccurred(SendingRequestEvent eventArg) { @Test public void testPageBlobDownloadRangeTest() throws URISyntaxException, StorageException, IOException { - byte[] buffer = getRandomBuffer(2 * 1024); + byte[] buffer = BlobTestHelper.getRandomBuffer(2 * 1024); CloudPageBlob blob = container.getPageBlobReference("blob1"); ByteArrayInputStream wholeBlob = new ByteArrayInputStream(buffer); @@ -291,8 +285,8 @@ public void testPageBlobDownloadRangeTest() throws URISyntaxException, StorageEx blob.downloadRange(0, new Long(1024), blobStream); assertEquals(blobStream.size(), 1024); - TestHelper.assertStreamsAreEqualAtIndex(new ByteArrayInputStream(blobStream.toByteArray()), wholeBlob, 0, 0, - 1024, 2 * 1024); + BlobTestHelper.assertStreamsAreEqualAtIndex(new ByteArrayInputStream(blobStream.toByteArray()), wholeBlob, 0, + 0, 1024, 2 * 1024); CloudPageBlob blob2 = container.getPageBlobReference("blob1"); try { @@ -304,53 +298,57 @@ public void testPageBlobDownloadRangeTest() throws URISyntaxException, StorageEx ByteArrayOutputStream blobStream2 = new ByteArrayOutputStream(); blob2.downloadRange(1024, new Long(1024), blobStream2); - TestHelper.assertStreamsAreEqualAtIndex(new ByteArrayInputStream(blobStream2.toByteArray()), wholeBlob, 1024, - 1024, 1024, 2 * 1024); + BlobTestHelper.assertStreamsAreEqualAtIndex(new ByteArrayInputStream(blobStream2.toByteArray()), wholeBlob, + 1024, 1024, 1024, 2 * 1024); - assertAreEqual(blob, blob2); + BlobTestHelper.assertAreEqual(blob, blob2); } @Test public void testCloudPageBlobDownloadToByteArray() throws URISyntaxException, StorageException, IOException { CloudPageBlob blob = container.getPageBlobReference("blob1"); - this.doDownloadTest(blob, 1 * 512, 2 * 512, 0); - this.doDownloadTest(blob, 1 * 512, 2 * 512, 1 * 512); - this.doDownloadTest(blob, 2 * 512, 4 * 512, 1 * 512); - this.doDownloadTest(blob, 5 * 1024 * 1024, 5 * 1024 * 1024, 0); - this.doDownloadTest(blob, 5 * 1024 * 1024, 6 * 1024 * 1024, 512); + BlobTestHelper.doDownloadTest(blob, 1 * 512, 2 * 512, 0); + BlobTestHelper.doDownloadTest(blob, 1 * 512, 2 * 512, 1 * 512); + BlobTestHelper.doDownloadTest(blob, 2 * 512, 4 * 512, 1 * 512); + BlobTestHelper.doDownloadTest(blob, 5 * 1024 * 1024, 5 * 1024 * 1024, 0); + BlobTestHelper.doDownloadTest(blob, 5 * 1024 * 1024, 6 * 1024 * 1024, 512); } @Test public void testCloudPageBlobDownloadRangeToByteArray() throws URISyntaxException, StorageException, IOException { - CloudPageBlob blob = container.getPageBlobReference(generateRandomBlobNameWithPrefix("downloadrange")); - - this.doDownloadRangeToByteArrayTest(blob, 8 * 1024 * 1024, 8 * 1024 * 1024, 1 * 1024 * 1024, new Long( - 1 * 1024 * 1024), new Long(5 * 1024 * 1024)); - this.doDownloadRangeToByteArrayTest(blob, 8 * 1024 * 1024, 8 * 1024 * 1024, 2 * 1024 * 1024, new Long( - 2 * 1024 * 1024), new Long(6 * 1024 * 1024)); - this.doDownloadRangeToByteArrayTest(blob, 8 * 1024 * 1024, 8 * 1024 * 1024, 1 * 1024 * 1024, new Long( - 4 * 1024 * 1024), new Long(4 * 1024 * 1024)); - - this.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 0, new Long(1 * 512), new Long(1 * 512)); - this.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 1 * 512, new Long(0), null); - this.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 1 * 512, new Long(1 * 512), null); - this.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 1 * 512, new Long(0), new Long(1 * 512)); - this.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 2 * 512, new Long(1 * 512), new Long(1 * 512)); - this.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 2 * 512, new Long(1 * 512), new Long(2 * 512)); + CloudPageBlob blob = container.getPageBlobReference(BlobTestHelper + .generateRandomBlobNameWithPrefix("downloadrange")); + + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 8 * 1024 * 1024, 8 * 1024 * 1024, 1 * 1024 * 1024, + new Long(1 * 1024 * 1024), new Long(5 * 1024 * 1024)); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 8 * 1024 * 1024, 8 * 1024 * 1024, 2 * 1024 * 1024, + new Long(2 * 1024 * 1024), new Long(6 * 1024 * 1024)); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 8 * 1024 * 1024, 8 * 1024 * 1024, 1 * 1024 * 1024, + new Long(4 * 1024 * 1024), new Long(4 * 1024 * 1024)); + + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 0, new Long(1 * 512), new Long(1 * 512)); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 1 * 512, new Long(0), null); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 1 * 512, new Long(1 * 512), null); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 1 * 512, new Long(0), new Long(1 * 512)); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 2 * 512, new Long(1 * 512), new Long( + 1 * 512)); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 2 * 512, 4 * 512, 2 * 512, new Long(1 * 512), new Long( + 2 * 512)); // Edge cases - this.doDownloadRangeToByteArrayTest(blob, 1024, 1024, 1023, new Long(1023), new Long(1)); - this.doDownloadRangeToByteArrayTest(blob, 1024, 1024, 0, new Long(1023), new Long(1)); - this.doDownloadRangeToByteArrayTest(blob, 1024, 1024, 0, new Long(0), new Long(1)); - this.doDownloadRangeToByteArrayTest(blob, 1024, 1024, 0, new Long(512), new Long(1)); - this.doDownloadRangeToByteArrayTest(blob, 1024, 1024, 512, new Long(1023), new Long(1)); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 1024, 1024, 1023, new Long(1023), new Long(1)); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 1024, 1024, 0, new Long(1023), new Long(1)); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 1024, 1024, 0, new Long(0), new Long(1)); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 1024, 1024, 0, new Long(512), new Long(1)); + BlobTestHelper.doDownloadRangeToByteArrayTest(blob, 1024, 1024, 512, new Long(1023), new Long(1)); } @Test public void testCloudPageBlobDownloadRangeToByteArrayNegativeTest() throws URISyntaxException, StorageException, IOException { - CloudPageBlob blob = container.getPageBlobReference(generateRandomBlobNameWithPrefix("downloadrangenegative")); - this.doDownloadRangeToByteArrayNegativeTests(blob); + CloudPageBlob blob = container.getPageBlobReference(BlobTestHelper + .generateRandomBlobNameWithPrefix("downloadrangenegative")); + BlobTestHelper.doDownloadRangeToByteArrayNegativeTests(blob); } @Test @@ -359,7 +357,7 @@ public void testCloudPageBlobUploadFromStreamWithAccessCondition() throws URISyn CloudPageBlob blob1 = container.getPageBlobReference("blob1"); AccessCondition accessCondition = AccessCondition.generateIfNoneMatchCondition("\"*\""); final int length = 6 * 512; - ByteArrayInputStream srcStream = getRandomDataStream(length); + ByteArrayInputStream srcStream = BlobTestHelper.getRandomDataStream(length); blob1.upload(srcStream, length, accessCondition, null, null); srcStream.reset(); @@ -403,12 +401,12 @@ public void testPageBlobNamePlusEncodingTest() throws StorageException, URISynta InterruptedException { final int length = 1 * 1024; - final CloudPageBlob originalBlob = (CloudPageBlob) uploadNewBlob(container, BlobType.PAGE_BLOB, "a+b.txt", - length, null); + final CloudPageBlob originalBlob = (CloudPageBlob) BlobTestHelper.uploadNewBlob(container, BlobType.PAGE_BLOB, + "a+b.txt", length, null); final CloudBlob copyBlob = container.getPageBlobReference(originalBlob.getName() + "copyed"); copyBlob.startCopyFromBlob(originalBlob); - waitForCopy(copyBlob); + BlobTestHelper.waitForCopy(copyBlob); copyBlob.downloadAttributes(); } @@ -421,7 +419,7 @@ public void testPageBlobNamePlusEncodingTest() throws StorageException, URISynta public void testPageBlobInputStream() throws URISyntaxException, StorageException, IOException { final int blobLength = 16 * 1024; final Random randGenerator = new Random(); - String blobName = generateRandomBlobNameWithPrefix("testblob"); + String blobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testblob"); final CloudPageBlob blobRef = container.getPageBlobReference(blobName); final byte[] buff = new byte[blobLength]; @@ -451,7 +449,7 @@ public void testPageBlobInputStream() throws URISyntaxException, StorageExceptio @Test public void testUploadFromByteArray() throws Exception { - String blobName = generateRandomBlobNameWithPrefix("testblob"); + String blobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testblob"); final CloudPageBlob blob = container.getPageBlobReference(blobName); this.doUploadFromByteArrayTest(blob, 4 * 512, 0, 4 * 512); @@ -462,7 +460,7 @@ public void testUploadFromByteArray() throws Exception { @Test public void testUploadDownloadFromFile() throws IOException, StorageException, URISyntaxException { - String blobName = generateRandomBlobNameWithPrefix("testblob"); + String blobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testblob"); final CloudPageBlob blob = container.getPageBlobReference(blobName); this.doUploadDownloadFileTest(blob, 512); @@ -477,15 +475,15 @@ public void testPageBlobCopyTest() throws URISyntaxException, StorageException, CloudPageBlob source = container.getPageBlobReference("source"); - byte[] buffer = getRandomBuffer(512); + byte[] buffer = BlobTestHelper.getRandomBuffer(512); ByteArrayInputStream stream = new ByteArrayInputStream(buffer); source.upload(stream, buffer.length); source.getMetadata().put("Test", "value"); source.uploadMetadata(); CloudPageBlob copy = container.getPageBlobReference("copy"); - String copyId = copy.startCopyFromBlob(defiddler(source)); - waitForCopy(copy); + String copyId = copy.startCopyFromBlob(BlobTestHelper.defiddler(source)); + BlobTestHelper.waitForCopy(copy); assertEquals(CopyStatus.SUCCESS, copy.getCopyState().getStatus()); assertEquals(source.getQualifiedUri().getPath(), copy.getCopyState().getSource().getPath()); @@ -508,7 +506,7 @@ public void testPageBlobCopyTest() throws URISyntaxException, StorageException, ByteArrayOutputStream copyStream = new ByteArrayOutputStream(); copy.download(copyStream); - TestHelper.assertStreamsAreEqual(stream, new ByteArrayInputStream(copyStream.toByteArray())); + BlobTestHelper.assertStreamsAreEqual(stream, new ByteArrayInputStream(copyStream.toByteArray())); copy.downloadAttributes(); BlobProperties prop1 = copy.getProperties(); @@ -532,7 +530,7 @@ public void testPageBlobCopyWithMetadataOverride() throws URISyntaxException, St Calendar calendar = Calendar.getInstance(Utility.UTC_ZONE); CloudPageBlob source = container.getPageBlobReference("source"); - byte[] buffer = getRandomBuffer(512); + byte[] buffer = BlobTestHelper.getRandomBuffer(512); ByteArrayInputStream stream = new ByteArrayInputStream(buffer); source.upload(stream, buffer.length); @@ -542,8 +540,8 @@ public void testPageBlobCopyWithMetadataOverride() throws URISyntaxException, St CloudPageBlob copy = container.getPageBlobReference("copy"); copy.getMetadata().put("Test2", "value2"); - String copyId = copy.startCopyFromBlob(defiddler(source)); - waitForCopy(copy); + String copyId = copy.startCopyFromBlob(BlobTestHelper.defiddler(source)); + BlobTestHelper.waitForCopy(copy); assertEquals(CopyStatus.SUCCESS, copy.getCopyState().getStatus()); assertEquals(source.getQualifiedUri().getPath(), copy.getCopyState().getSource().getPath()); @@ -554,7 +552,7 @@ public void testPageBlobCopyWithMetadataOverride() throws URISyntaxException, St ByteArrayOutputStream copyStream = new ByteArrayOutputStream(); copy.download(copyStream); - TestHelper.assertStreamsAreEqual(stream, new ByteArrayInputStream(copyStream.toByteArray())); + BlobTestHelper.assertStreamsAreEqual(stream, new ByteArrayInputStream(copyStream.toByteArray())); copy.downloadAttributes(); source.downloadAttributes(); @@ -579,7 +577,7 @@ public void testPageBlobCopyFromSnapshot() throws StorageException, IOException, InterruptedException { CloudPageBlob source = container.getPageBlobReference("source"); - byte[] buffer = getRandomBuffer(512); + byte[] buffer = BlobTestHelper.getRandomBuffer(512); ByteArrayInputStream stream = new ByteArrayInputStream(buffer); source.upload(stream, buffer.length); @@ -590,7 +588,7 @@ public void testPageBlobCopyFromSnapshot() throws StorageException, IOException, CloudPageBlob snapshot = (CloudPageBlob) source.createSnapshot(); //Modify source - byte[] buffer2 = getRandomBuffer(512); + byte[] buffer2 = BlobTestHelper.getRandomBuffer(512); ByteArrayInputStream stream2 = new ByteArrayInputStream(buffer2); source.getMetadata().put("Test", "newvalue"); source.uploadMetadata(); @@ -602,22 +600,22 @@ public void testPageBlobCopyFromSnapshot() throws StorageException, IOException, ByteArrayOutputStream snapshotStream = new ByteArrayOutputStream(); snapshot.download(snapshotStream); - TestHelper.assertStreamsAreEqual(stream2, new ByteArrayInputStream(outputStream.toByteArray())); - TestHelper.assertStreamsAreEqual(stream, new ByteArrayInputStream(snapshotStream.toByteArray())); + BlobTestHelper.assertStreamsAreEqual(stream2, new ByteArrayInputStream(outputStream.toByteArray())); + BlobTestHelper.assertStreamsAreEqual(stream, new ByteArrayInputStream(snapshotStream.toByteArray())); source.downloadAttributes(); snapshot.downloadAttributes(); assertFalse(source.getMetadata().get("Test").equals(snapshot.getMetadata().get("Test"))); CloudPageBlob copy = container.getPageBlobReference("copy"); - String copyId = copy.startCopyFromBlob(defiddler(snapshot)); - waitForCopy(copy); + String copyId = copy.startCopyFromBlob(BlobTestHelper.defiddler(snapshot)); + BlobTestHelper.waitForCopy(copy); ByteArrayOutputStream copyStream = new ByteArrayOutputStream(); copy.download(copyStream); assertEquals(CopyStatus.SUCCESS, copy.getCopyState().getStatus()); - TestHelper.assertStreamsAreEqual(stream, new ByteArrayInputStream(copyStream.toByteArray())); + BlobTestHelper.assertStreamsAreEqual(stream, new ByteArrayInputStream(copyStream.toByteArray())); assertEquals(copyId, copy.getProperties().getCopyState().getCopyId()); copy.downloadAttributes(); @@ -638,7 +636,7 @@ public void testPageBlobCopyFromSnapshot() throws StorageException, IOException, private void doUploadFromByteArrayTest(CloudPageBlob blob, int bufferSize, int bufferOffset, int count) throws Exception { - byte[] buffer = getRandomBuffer(bufferSize); + byte[] buffer = BlobTestHelper.getRandomBuffer(bufferSize); byte[] downloadedBuffer = new byte[bufferSize]; blob.uploadFromByteArray(buffer, bufferOffset, count); @@ -660,7 +658,7 @@ private void doUploadDownloadFileTest(CloudPageBlob blob, int fileSize) throws I try { - byte[] buffer = getRandomBuffer(fileSize); + byte[] buffer = BlobTestHelper.getRandomBuffer(fileSize); FileOutputStream fos = new FileOutputStream(sourceFile); fos.write(buffer); fos.close(); @@ -693,9 +691,9 @@ private void doUploadDownloadFileTest(CloudPageBlob blob, int fileSize) throws I @Test public void testUploadPages() throws URISyntaxException, StorageException, IOException { int blobLengthToUse = 8 * 512; - byte[] buffer = CloudPageBlobTests.getRandomBuffer(8 * 512); + byte[] buffer = BlobTestHelper.getRandomBuffer(8 * 512); - String blobName = generateRandomBlobNameWithPrefix("testblob"); + String blobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testblob"); final CloudPageBlob blobRef = container.getPageBlobReference(blobName); blobRef.create(blobLengthToUse); @@ -753,9 +751,9 @@ public void testUploadPages() throws URISyntaxException, StorageException, IOExc @Test public void testClearPages() throws URISyntaxException, StorageException, IOException { int blobLengthToUse = 8 * 512; - byte[] buffer = CloudPageBlobTests.getRandomBuffer(8 * 512); + byte[] buffer = BlobTestHelper.getRandomBuffer(8 * 512); - String blobName = generateRandomBlobNameWithPrefix("testblob"); + String blobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testblob"); final CloudPageBlob blobRef = container.getPageBlobReference(blobName); blobRef.create(blobLengthToUse); @@ -826,9 +824,9 @@ public void testResize() throws StorageException, URISyntaxException { @Test public void testDownloadPages() throws StorageException, URISyntaxException, IOException { int blobLengthToUse = 8 * 512; - byte[] buffer = CloudPageBlobTests.getRandomBuffer(8 * 512); + byte[] buffer = BlobTestHelper.getRandomBuffer(8 * 512); - String blobName = generateRandomBlobNameWithPrefix("testblob"); + String blobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testblob"); final CloudPageBlob blobRef = container.getPageBlobReference(blobName); blobRef.create(blobLengthToUse); @@ -866,41 +864,41 @@ public void testUploadDownloadBlobProperties() throws URISyntaxException, Storag options.setDisableContentMD5Validation(true); // with explicit upload/download of properties - String pageBlobName1 = generateRandomBlobNameWithPrefix("testBlockBlob"); + String pageBlobName1 = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlockBlob"); CloudPageBlob pageBlobRef1 = container.getPageBlobReference(pageBlobName1); - pageBlobRef1.upload(getRandomDataStream(length), length); + pageBlobRef1.upload(BlobTestHelper.getRandomDataStream(length), length); - setBlobProperties(pageBlobRef1); + BlobTestHelper.setBlobProperties(pageBlobRef1); BlobProperties props1 = pageBlobRef1.getProperties(); pageBlobRef1.uploadProperties(); pageBlobRef1.downloadAttributes(null, options, null); BlobProperties props2 = pageBlobRef1.getProperties(); - assertAreEqual(props1, props2); + BlobTestHelper.assertAreEqual(props1, props2); // by uploading/downloading the blob - pageBlobName1 = generateRandomBlobNameWithPrefix("testBlockBlob"); + pageBlobName1 = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlockBlob"); pageBlobRef1 = container.getPageBlobReference(pageBlobName1); - setBlobProperties(pageBlobRef1); + BlobTestHelper.setBlobProperties(pageBlobRef1); props1 = pageBlobRef1.getProperties(); - pageBlobRef1.upload(getRandomDataStream(length), length); + pageBlobRef1.upload(BlobTestHelper.getRandomDataStream(length), length); pageBlobRef1.download(new ByteArrayOutputStream(), null, options, null); props2 = pageBlobRef1.getProperties(); - assertAreEqual(props1, props2); + BlobTestHelper.assertAreEqual(props1, props2); } @Test public void testOpenOutputStreamNotAligned() throws StorageException, URISyntaxException { int blobLengthToUse = 8 * 512; - byte[] buffer = CloudPageBlobTests.getRandomBuffer(8 * 512); + byte[] buffer = BlobTestHelper.getRandomBuffer(8 * 512); - String blobName = generateRandomBlobNameWithPrefix("testblob"); + String blobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testblob"); final CloudPageBlob blobRef = container.getPageBlobReference(blobName); blobRef.create(blobLengthToUse); @@ -929,9 +927,9 @@ public void testOpenOutputStreamNotAligned() throws StorageException, URISyntaxE @Test public void testOpenOutputStream() throws URISyntaxException, StorageException, IOException { int blobLengthToUse = 8 * 512; - byte[] buffer = CloudPageBlobTests.getRandomBuffer(8 * 512); + byte[] buffer = BlobTestHelper.getRandomBuffer(8 * 512); - String blobName = generateRandomBlobNameWithPrefix("testblob"); + String blobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testblob"); final CloudPageBlob blobRef = container.getPageBlobReference(blobName); blobRef.create(blobLengthToUse); @@ -962,7 +960,7 @@ public void testOpenOutputStream() throws URISyntaxException, StorageException, @Test public void testOpenOutputStreamNoArgs() throws URISyntaxException, StorageException { - String blobName = generateRandomBlobNameWithPrefix("testblob"); + String blobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testblob"); CloudPageBlob pageBlob = container.getPageBlobReference(blobName); try { diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/LeaseTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/LeaseTests.java similarity index 86% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/LeaseTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/LeaseTests.java index e1400fd27b195..1ae52e6956a62 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/LeaseTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/LeaseTests.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import static org.junit.Assert.*; @@ -27,23 +27,23 @@ import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.AccessCondition; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageErrorCodeStrings; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; -import com.microsoft.windowsazure.storage.TestRunners.SlowTests; +import com.microsoft.azure.storage.AccessCondition; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.StorageErrorCodeStrings; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.TestRunners.SlowTests; @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) -public class LeaseTests extends BlobTestBase { +public class LeaseTests { protected CloudBlobContainer container; @Before - public void leaseTestMethodSetup() throws URISyntaxException, StorageException { - container = getRandomContainerReference(); + public void leaseTestMethodSetup() throws StorageException, URISyntaxException { + container = BlobTestHelper.getRandomContainerReference(); container.create(); } @@ -53,12 +53,12 @@ public void leaseTestMethodTearDown() throws StorageException { } @Test - public void testContainerAcquireLease() throws StorageException, URISyntaxException, InterruptedException { - CloudBlobContainer leaseContainer1 = getRandomContainerReference(); + public void testContainerAcquireLease() throws StorageException, URISyntaxException { + CloudBlobContainer leaseContainer1 = BlobTestHelper.getRandomContainerReference(); leaseContainer1.create(); String proposedLeaseId1 = UUID.randomUUID().toString(); - CloudBlobContainer leaseContainer2 = getRandomContainerReference(); + CloudBlobContainer leaseContainer2 = BlobTestHelper.getRandomContainerReference(); leaseContainer2.create(); String proposedLeaseId2 = UUID.randomUUID().toString(); @@ -96,7 +96,7 @@ public void testContainerAcquireLease() throws StorageException, URISyntaxExcept } @Test - public void testContainerReleaseLease() throws StorageException, URISyntaxException, InterruptedException { + public void testContainerReleaseLease() throws StorageException { // 15 sec String proposedLeaseId = UUID.randomUUID().toString(); String leaseId = container.acquireLease(15, proposedLeaseId); @@ -118,7 +118,7 @@ public void testContainerReleaseLease() throws StorageException, URISyntaxExcept @Test @Category(SlowTests.class) - public void testContainerBreakLease() throws StorageException, URISyntaxException, InterruptedException { + public void testContainerBreakLease() throws StorageException, InterruptedException { String proposedLeaseId = UUID.randomUUID().toString(); try { // 5 sec @@ -148,7 +148,7 @@ public void testContainerBreakLease() throws StorageException, URISyntaxExceptio } @Test - public void testContainerRenewLeaseTest() throws StorageException, URISyntaxException, InterruptedException { + public void testContainerRenewLeaseTest() throws StorageException { String proposedLeaseId = UUID.randomUUID().toString(); try { // 5 sec @@ -178,7 +178,7 @@ public void testContainerRenewLeaseTest() throws StorageException, URISyntaxExce } @Test - public void testContainerChangeLeaseTest() throws StorageException, URISyntaxException, InterruptedException { + public void testContainerChangeLeaseTest() throws StorageException { // Get Lease String leaseID1; String leaseID2; @@ -249,9 +249,9 @@ public void testContainerChangeLeaseTest() throws StorageException, URISyntaxExc } @Test - public void testBlobLeaseAcquireAndRelease() throws URISyntaxException, StorageException, IOException { + public void testBlobLeaseAcquireAndRelease() throws StorageException, IOException, URISyntaxException { final int length = 128; - final CloudBlob blobRef = uploadNewBlob(container, BlobType.BLOCK_BLOB, "test", 128, null); + final CloudBlob blobRef = BlobTestHelper.uploadNewBlob(container, BlobType.BLOCK_BLOB, "test", 128, null); // Get Lease OperationContext operationContext = new OperationContext(); @@ -263,19 +263,19 @@ public void testBlobLeaseAcquireAndRelease() throws URISyntaxException, StorageE tryUploadWithBadLease(length, blobRef, null, StorageErrorCodeStrings.LEASE_ID_MISSING); // Try to upload with lease - blobRef.upload(getRandomDataStream(length), -1, leaseCondition, null, null); + blobRef.upload(BlobTestHelper.getRandomDataStream(length), -1, leaseCondition, null, null); // Release lease blobRef.releaseLease(leaseCondition); // now upload with no lease specified. - blobRef.upload(getRandomDataStream(length), -1); + blobRef.upload(BlobTestHelper.getRandomDataStream(length), -1); } @Test public void testBlobLeaseChange() throws StorageException, IOException, URISyntaxException { final int length = 128; - final CloudBlob blobRef = uploadNewBlob(container, BlobType.BLOCK_BLOB, "test", 128, null); + final CloudBlob blobRef = BlobTestHelper.uploadNewBlob(container, BlobType.BLOCK_BLOB, "test", 128, null); // Get Lease OperationContext operationContext = new OperationContext(); @@ -295,7 +295,7 @@ public void testBlobLeaseChange() throws StorageException, IOException, URISynta StorageErrorCodeStrings.LEASE_ID_MISMATCH_WITH_BLOB_OPERATION); // Try to upload with correct lease - blobRef.upload(getRandomDataStream(length), -1, leaseCondition1, null, null); + blobRef.upload(BlobTestHelper.getRandomDataStream(length), -1, leaseCondition1, null, null); // Fail to change the lease with a bad accessCondition try { @@ -318,7 +318,7 @@ public void testBlobLeaseChange() throws StorageException, IOException, URISynta StorageErrorCodeStrings.LEASE_ID_MISMATCH_WITH_BLOB_OPERATION); // Try to upload with correct lease - blobRef.upload(getRandomDataStream(length), -1, leaseCondition2, null, null); + blobRef.upload(BlobTestHelper.getRandomDataStream(length), -1, leaseCondition2, null, null); } /** @@ -331,7 +331,7 @@ public void testBlobLeaseChange() throws StorageException, IOException, URISynta private void tryUploadWithBadLease(final int length, final CloudBlob blobRef, final AccessCondition leaseCondition, final String expectedError) throws IOException { try { - blobRef.upload(getRandomDataStream(length), -1, leaseCondition, null, null); + blobRef.upload(BlobTestHelper.getRandomDataStream(length), -1, leaseCondition, null, null); fail("Did not throw expected exception"); } catch (final StorageException ex) { @@ -341,8 +341,8 @@ private void tryUploadWithBadLease(final int length, final CloudBlob blobRef, fi } @Test - public void testBlobLeaseBreak() throws URISyntaxException, StorageException, IOException, InterruptedException { - final CloudBlob blobRef = uploadNewBlob(container, BlobType.BLOCK_BLOB, "test", 128, null); + public void testBlobLeaseBreak() throws StorageException, IOException, URISyntaxException { + final CloudBlob blobRef = BlobTestHelper.uploadNewBlob(container, BlobType.BLOCK_BLOB, "test", 128, null); // Get Lease String leaseID = blobRef.acquireLease(null, null); @@ -355,8 +355,8 @@ public void testBlobLeaseBreak() throws URISyntaxException, StorageException, IO @Test @Category(SlowTests.class) - public void testBlobLeaseRenew() throws URISyntaxException, StorageException, IOException, InterruptedException { - final CloudBlob blobRef = uploadNewBlob(container, BlobType.BLOCK_BLOB, "test", 128, null); + public void testBlobLeaseRenew() throws StorageException, IOException, InterruptedException, URISyntaxException { + final CloudBlob blobRef = BlobTestHelper.uploadNewBlob(container, BlobType.BLOCK_BLOB, "test", 128, null); // Get Lease final String leaseID = blobRef.acquireLease(15, null); diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/SasTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/SasTests.java similarity index 78% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/SasTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/SasTests.java index 171599e09473f..886fa22a0e2ee 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/blob/SasTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/SasTests.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import static org.junit.Assert.*; @@ -37,34 +37,34 @@ import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.LocationMode; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.RetryNoRetry; -import com.microsoft.windowsazure.storage.SecondaryTests; -import com.microsoft.windowsazure.storage.SendingRequestEvent; -import com.microsoft.windowsazure.storage.StorageCredentials; -import com.microsoft.windowsazure.storage.StorageCredentialsSharedAccessSignature; -import com.microsoft.windowsazure.storage.StorageEvent; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; -import com.microsoft.windowsazure.storage.TestRunners.SlowTests; -import com.microsoft.windowsazure.storage.core.PathUtility; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.LocationMode; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.RetryNoRetry; +import com.microsoft.azure.storage.SecondaryTests; +import com.microsoft.azure.storage.SendingRequestEvent; +import com.microsoft.azure.storage.StorageCredentials; +import com.microsoft.azure.storage.StorageCredentialsSharedAccessSignature; +import com.microsoft.azure.storage.StorageEvent; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.TestRunners.SlowTests; +import com.microsoft.azure.storage.core.PathUtility; @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) -public class SasTests extends BlobTestBase { +public class SasTests { protected CloudBlobContainer container; protected CloudBlockBlob blob; @Before public void leaseTestMethodSetup() throws URISyntaxException, StorageException, IOException { - container = getRandomContainerReference(); + container = BlobTestHelper.getRandomContainerReference(); container.create(); - blob = (CloudBlockBlob) uploadNewBlob(container, BlobType.BLOCK_BLOB, "test", 100, null); + blob = (CloudBlockBlob) BlobTestHelper.uploadNewBlob(container, BlobType.BLOCK_BLOB, "test", 100, null); } @After @@ -74,7 +74,7 @@ public void leaseTestMethodTearDown() throws StorageException { @Test @Category({ SecondaryTests.class, SlowTests.class }) - public void testContainerSaS() throws IllegalArgumentException, StorageException, URISyntaxException, IOException, + public void testContainerSaS() throws IllegalArgumentException, StorageException, URISyntaxException, InvalidKeyException, InterruptedException { SharedAccessBlobPolicy sp1 = createSharedAccessPolicy( EnumSet.of(SharedAccessBlobPermissions.READ, SharedAccessBlobPermissions.WRITE, @@ -89,9 +89,9 @@ public void testContainerSaS() throws IllegalArgumentException, StorageException Thread.sleep(30000); String containerReadListSas = container.generateSharedAccessSignature(sp2, null); - CloudBlobClient sasClient = new CloudBlobClient(createCloudBlobClient().getStorageUri(), - new StorageCredentialsSharedAccessSignature(containerReadListSas)); - CloudBlobContainer readListContainer = sasClient.getContainerReference(container.name); + CloudBlobContainer readListContainer = new CloudBlobContainer(PathUtility.addToQuery(container.getUri(), + containerReadListSas)); + assertEquals(StorageCredentialsSharedAccessSignature.class.toString(), readListContainer.getServiceClient() .getCredentials().getClass().toString()); @@ -100,7 +100,7 @@ public void testContainerSaS() throws IllegalArgumentException, StorageException // do not give the client and check that the new container's client has the correct perms CloudBlobContainer containerFromUri = new CloudBlobContainer(PathUtility.addToQuery( - readListContainer.getStorageUri(), container.generateSharedAccessSignature(null, "readlist")), null); + readListContainer.getStorageUri(), container.generateSharedAccessSignature(null, "readlist"))); assertEquals(StorageCredentialsSharedAccessSignature.class.toString(), containerFromUri.getServiceClient() .getCredentials().getClass().toString()); @@ -109,27 +109,29 @@ public void testContainerSaS() throws IllegalArgumentException, StorageException CloudBlobClient bClient = container.getServiceClient(); // set some arbitrary settings to make sure they are passed on - bClient.setConcurrentRequestCount(5); + bClient.getDefaultRequestOptions().setConcurrentRequestCount(5); bClient.setDirectoryDelimiter("%"); - bClient.setLocationMode(LocationMode.PRIMARY_THEN_SECONDARY); - bClient.setSingleBlobPutThresholdInBytes(5 * Constants.MB); - bClient.setTimeoutInMs(1000); - bClient.setRetryPolicyFactory(new RetryNoRetry()); + bClient.getDefaultRequestOptions().setLocationMode(LocationMode.PRIMARY_THEN_SECONDARY); + bClient.getDefaultRequestOptions().setSingleBlobPutThresholdInBytes(5 * Constants.MB); + bClient.getDefaultRequestOptions().setTimeoutIntervalInMs(1000); + bClient.getDefaultRequestOptions().setRetryPolicyFactory(new RetryNoRetry()); containerFromUri = new CloudBlobContainer(PathUtility.addToQuery(readListContainer.getStorageUri(), container.generateSharedAccessSignature(null, "readlist")), container.getServiceClient()); assertEquals(StorageCredentialsSharedAccessSignature.class.toString(), containerFromUri.getServiceClient() .getCredentials().getClass().toString()); - assertEquals(bClient.getConcurrentRequestCount(), containerFromUri.getServiceClient() - .getConcurrentRequestCount()); + assertEquals(bClient.getDefaultRequestOptions().getConcurrentRequestCount(), containerFromUri + .getServiceClient().getDefaultRequestOptions().getConcurrentRequestCount()); assertEquals(bClient.getDirectoryDelimiter(), containerFromUri.getServiceClient().getDirectoryDelimiter()); - assertEquals(bClient.getLocationMode(), containerFromUri.getServiceClient().getLocationMode()); - assertEquals(bClient.getSingleBlobPutThresholdInBytes(), containerFromUri.getServiceClient() - .getSingleBlobPutThresholdInBytes()); - assertEquals(bClient.getTimeoutInMs(), containerFromUri.getServiceClient().getTimeoutInMs()); - assertEquals(bClient.getRetryPolicyFactory().getClass(), containerFromUri.getServiceClient() - .getRetryPolicyFactory().getClass()); + assertEquals(bClient.getDefaultRequestOptions().getLocationMode(), containerFromUri.getServiceClient() + .getDefaultRequestOptions().getLocationMode()); + assertEquals(bClient.getDefaultRequestOptions().getSingleBlobPutThresholdInBytes(), containerFromUri + .getServiceClient().getDefaultRequestOptions().getSingleBlobPutThresholdInBytes()); + assertEquals(bClient.getDefaultRequestOptions().getTimeoutIntervalInMs(), containerFromUri.getServiceClient() + .getDefaultRequestOptions().getTimeoutIntervalInMs()); + assertEquals(bClient.getDefaultRequestOptions().getRetryPolicyFactory().getClass(), containerFromUri + .getServiceClient().getDefaultRequestOptions().getRetryPolicyFactory().getClass()); } @Test @@ -147,12 +149,11 @@ public void testContainerUpdateSAS() throws InvalidKeyException, StorageExceptio String sasToken = container.generateSharedAccessSignature(policy, null); - CloudBlockBlob blob = (CloudBlockBlob) uploadNewBlob(container, BlobType.BLOCK_BLOB, "blockblob", 64, null); + CloudBlockBlob blob = (CloudBlockBlob) BlobTestHelper.uploadNewBlob(container, BlobType.BLOCK_BLOB, + "blockblob", 64, null); testAccess(sasToken, EnumSet.of(SharedAccessBlobPermissions.READ, SharedAccessBlobPermissions.WRITE), null, container, blob); - StorageCredentials creds = new StorageCredentialsSharedAccessSignature(sasToken); - //Change the policy to only read and update SAS. SharedAccessBlobPolicy policy2 = createSharedAccessPolicy(EnumSet.of(SharedAccessBlobPermissions.READ), 300); perms = new BlobContainerPermissions(); @@ -161,15 +162,12 @@ public void testContainerUpdateSAS() throws InvalidKeyException, StorageExceptio container.uploadPermissions(perms); Thread.sleep(30000); - String sasToken2 = container.generateSharedAccessSignature(policy2, null); - creds = new StorageCredentialsSharedAccessSignature(sasToken2); - // Extra check to make sure that we have actually updated the SAS token. - CloudBlobClient client = new CloudBlobClient(createCloudBlobClient().getStorageUri(), creds); - CloudBlobContainer sasContainer = new CloudBlobContainer(container.getUri(), client); + String sasToken2 = container.generateSharedAccessSignature(policy2, null); + CloudBlobContainer sasContainer = new CloudBlobContainer(PathUtility.addToQuery(container.getUri(), sasToken2)); try { - uploadNewBlob(sasContainer, BlobType.BLOCK_BLOB, "blockblob", 64, null); + BlobTestHelper.uploadNewBlob(sasContainer, BlobType.BLOCK_BLOB, "blockblob", 64, null); Assert.fail(); } catch (StorageException ex) { @@ -210,12 +208,12 @@ public void testContainerSASCombinations() throws StorageException, URISyntaxExc String sasToken = container.generateSharedAccessSignature(policy, null); - CloudBlockBlob testBlockBlob = (CloudBlockBlob) uploadNewBlob(container, BlobType.BLOCK_BLOB, "blockblob", - 64, null); + CloudBlockBlob testBlockBlob = (CloudBlockBlob) BlobTestHelper.uploadNewBlob(container, + BlobType.BLOCK_BLOB, "blockblob", 64, null); testAccess(sasToken, permissions, null, container, testBlockBlob); - CloudPageBlob testPageBlob = (CloudPageBlob) uploadNewBlob(container, BlobType.PAGE_BLOB, "pageblob", 512, - null); + CloudPageBlob testPageBlob = (CloudPageBlob) BlobTestHelper.uploadNewBlob(container, BlobType.PAGE_BLOB, + "pageblob", 512, null); testAccess(sasToken, permissions, null, container, testPageBlob); } @@ -225,9 +223,10 @@ public void testContainerSASCombinations() throws StorageException, URISyntaxExc @Category(SlowTests.class) public void testContainerPublicAccess() throws StorageException, IOException, URISyntaxException, InterruptedException { - CloudBlockBlob testBlockBlob = (CloudBlockBlob) uploadNewBlob(container, BlobType.BLOCK_BLOB, "blockblob", 64, - null); - CloudPageBlob testPageBlob = (CloudPageBlob) uploadNewBlob(container, BlobType.PAGE_BLOB, "pageblob", 512, null); + CloudBlockBlob testBlockBlob = (CloudBlockBlob) BlobTestHelper.uploadNewBlob(container, BlobType.BLOCK_BLOB, + "blockblob", 64, null); + CloudPageBlob testPageBlob = (CloudPageBlob) BlobTestHelper.uploadNewBlob(container, BlobType.PAGE_BLOB, + "pageblob", 512, null); BlobContainerPermissions permissions = new BlobContainerPermissions(); @@ -249,7 +248,7 @@ public void testContainerPublicAccess() throws StorageException, IOException, UR @Test public void testBlockBlobSASCombinations() throws URISyntaxException, StorageException, InvalidKeyException, - IOException, InterruptedException { + IOException { for (int i = 1; i < 8; i++) { final EnumSet permissions = EnumSet.noneOf(SharedAccessBlobPermissions.class); addPermissions(permissions, i); @@ -259,7 +258,7 @@ public void testBlockBlobSASCombinations() throws URISyntaxException, StorageExc @Test public void testPageBlobSASCombinations() throws InvalidKeyException, StorageException, IOException, - URISyntaxException, InterruptedException { + URISyntaxException { for (int i = 1; i < 8; i++) { final EnumSet permissions = EnumSet.noneOf(SharedAccessBlobPermissions.class); addPermissions(permissions, i); @@ -270,7 +269,7 @@ public void testPageBlobSASCombinations() throws InvalidKeyException, StorageExc @Test @Category(SlowTests.class) public void testBlobSaS() throws InvalidKeyException, IllegalArgumentException, StorageException, - URISyntaxException, IOException, InterruptedException { + URISyntaxException, InterruptedException { SharedAccessBlobPolicy sp = createSharedAccessPolicy( EnumSet.of(SharedAccessBlobPermissions.READ, SharedAccessBlobPermissions.LIST), 300); BlobContainerPermissions perms = new BlobContainerPermissions(); @@ -294,32 +293,35 @@ public void testBlobSaS() throws InvalidKeyException, IllegalArgumentException, CloudBlobClient bClient = sasBlob.getServiceClient(); // set some arbitrary settings to make sure they are passed on - bClient.setConcurrentRequestCount(5); + bClient.getDefaultRequestOptions().setConcurrentRequestCount(5); bClient.setDirectoryDelimiter("%"); - bClient.setLocationMode(LocationMode.PRIMARY_THEN_SECONDARY); - bClient.setSingleBlobPutThresholdInBytes(5 * Constants.MB); - bClient.setTimeoutInMs(1000); - bClient.setRetryPolicyFactory(new RetryNoRetry()); + bClient.getDefaultRequestOptions().setLocationMode(LocationMode.PRIMARY_THEN_SECONDARY); + bClient.getDefaultRequestOptions().setSingleBlobPutThresholdInBytes(5 * Constants.MB); + bClient.getDefaultRequestOptions().setTimeoutIntervalInMs(1000); + bClient.getDefaultRequestOptions().setRetryPolicyFactory(new RetryNoRetry()); blobFromUri = new CloudBlockBlob(PathUtility.addToQuery(blob.getStorageUri(), blob.generateSharedAccessSignature(null, "readperm")), bClient); assertEquals(StorageCredentialsSharedAccessSignature.class.toString(), blobFromUri.getServiceClient() .getCredentials().getClass().toString()); - assertEquals(bClient.getConcurrentRequestCount(), blobFromUri.getServiceClient().getConcurrentRequestCount()); + assertEquals(bClient.getDefaultRequestOptions().getConcurrentRequestCount(), blobFromUri.getServiceClient() + .getDefaultRequestOptions().getConcurrentRequestCount()); assertEquals(bClient.getDirectoryDelimiter(), blobFromUri.getServiceClient().getDirectoryDelimiter()); - assertEquals(bClient.getLocationMode(), blobFromUri.getServiceClient().getLocationMode()); - assertEquals(bClient.getSingleBlobPutThresholdInBytes(), blobFromUri.getServiceClient() - .getSingleBlobPutThresholdInBytes()); - assertEquals(bClient.getTimeoutInMs(), blobFromUri.getServiceClient().getTimeoutInMs()); - assertEquals(bClient.getRetryPolicyFactory().getClass(), blobFromUri.getServiceClient().getRetryPolicyFactory() - .getClass()); + assertEquals(bClient.getDefaultRequestOptions().getLocationMode(), blobFromUri.getServiceClient() + .getDefaultRequestOptions().getLocationMode()); + assertEquals(bClient.getDefaultRequestOptions().getSingleBlobPutThresholdInBytes(), blobFromUri + .getServiceClient().getDefaultRequestOptions().getSingleBlobPutThresholdInBytes()); + assertEquals(bClient.getDefaultRequestOptions().getTimeoutIntervalInMs(), blobFromUri.getServiceClient() + .getDefaultRequestOptions().getTimeoutIntervalInMs()); + assertEquals(bClient.getDefaultRequestOptions().getRetryPolicyFactory().getClass(), blobFromUri + .getServiceClient().getDefaultRequestOptions().getRetryPolicyFactory().getClass()); } @Test @Category(SlowTests.class) public void testBlobSaSWithSharedAccessBlobHeaders() throws InvalidKeyException, IllegalArgumentException, - StorageException, URISyntaxException, IOException, InterruptedException { + StorageException, URISyntaxException, InterruptedException { SharedAccessBlobPolicy sp = createSharedAccessPolicy(EnumSet.of(SharedAccessBlobPermissions.READ, SharedAccessBlobPermissions.WRITE, SharedAccessBlobPermissions.LIST), 300); BlobContainerPermissions perms = new BlobContainerPermissions(); @@ -377,9 +379,7 @@ private static void testAccess(String sasToken, EnumSet permissions, SharedAccessBlobHeaders headers) throws StorageException, - IOException, URISyntaxException, InvalidKeyException, InterruptedException { - CloudBlob blob = uploadNewBlob(container, type, "blob", 512, null); + IOException, URISyntaxException, InvalidKeyException { + CloudBlob blob = BlobTestHelper.uploadNewBlob(container, type, "blob", 512, null); SharedAccessBlobPolicy policy = createSharedAccessPolicy(permissions, 300); diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/queue/CloudQueueClientGB18030Test.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/queue/CloudQueueClientGB18030Test.java similarity index 72% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/queue/CloudQueueClientGB18030Test.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/queue/CloudQueueClientGB18030Test.java index 48754df78796a..f3ac8f8111a04 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/queue/CloudQueueClientGB18030Test.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/queue/CloudQueueClientGB18030Test.java @@ -12,35 +12,50 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.queue; +package com.microsoft.azure.storage.queue; import static org.junit.Assert.*; import java.net.URISyntaxException; import java.util.EnumSet; +import org.junit.After; +import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) -public class CloudQueueClientGB18030Test extends QueueTestBase { +public class CloudQueueClientGB18030Test { // GB18030CharSet is "啊齄丂狛狜隣郎隣兀﨩ˊ▇█〞〡¦℡㈱‐ー﹡﹢﹫、〓ⅰⅹ⒈€㈠㈩ⅠⅫ! ̄ぁんァヶΑ︴АЯаяāɡㄅㄩ─╋︵﹄︻︱︳︴ⅰⅹɑɡ〇〾⿻⺁䜣€㐀㒣㕴㕵㙉㙊䵯䵰䶴䶵". - public static final String GB18030CharSet = new String(new char[] { 0x554A, 0x9F44, 0x4E02, 0x72DB, 0x72DC, 0xF9F1, - 0xF92C, 0xF9F1, 0xFA0C, 0xFA29, 0x02CA, 0x2587, 0x2588, 0x301E, 0x3021, 0xFFE4, 0x2121, 0x3231, 0x2010, - 0x30FC, 0xFE61, 0xFE62, 0xFE6B, 0x3001, 0x3013, 0x2170, 0x2179, 0x2488, 0x20AC, 0x3220, 0x3229, 0x2160, - 0x216B, 0xFF01, 0xFFE3, 0x3041, 0x3093, 0x30A1, 0x30F6, 0x0391, 0xFE34, 0x0410, 0x042F, 0x0430, 0x044F, - 0x0101, 0x0261, 0x3105, 0x3129, 0x2500, 0x254B, 0xFE35, 0xFE44, 0xFE3B, 0xFE31, 0xFE33, 0xFE34, 0x2170, - 0x2179, 0x0251, 0xE7C7, 0x0261, 0x3007, 0x303E, 0x2FFB, 0x2E81, 0xE843, 0x4723, 0xE864, 0x20AC, 0x3400, - 0x34A3, 0x3574, 0x3575, 0x3649, 0x364A, 0x4D6F, 0x4D70, 0x4DB4, 0x4DB5 }); + private static final String GB18030CharSet = new String(new char[] { 0x554A, 0x9F44, 0x4E02, 0x72DB, 0x72DC, + 0xF9F1, 0xF92C, 0xF9F1, 0xFA0C, 0xFA29, 0x02CA, 0x2587, 0x2588, 0x301E, 0x3021, 0xFFE4, 0x2121, 0x3231, + 0x2010, 0x30FC, 0xFE61, 0xFE62, 0xFE6B, 0x3001, 0x3013, 0x2170, 0x2179, 0x2488, 0x20AC, 0x3220, 0x3229, + 0x2160, 0x216B, 0xFF01, 0xFFE3, 0x3041, 0x3093, 0x30A1, 0x30F6, 0x0391, 0xFE34, 0x0410, 0x042F, 0x0430, + 0x044F, 0x0101, 0x0261, 0x3105, 0x3129, 0x2500, 0x254B, 0xFE35, 0xFE44, 0xFE3B, 0xFE31, 0xFE33, 0xFE34, + 0x2170, 0x2179, 0x0251, 0xE7C7, 0x0261, 0x3007, 0x303E, 0x2FFB, 0x2E81, 0xE843, 0x4723, 0xE864, 0x20AC, + 0x3400, 0x34A3, 0x3574, 0x3575, 0x3649, 0x364A, 0x4D6F, 0x4D70, 0x4DB4, 0x4DB5 }); + + private CloudQueue queue; + + @Before + public void queueClientGBTestMethodSetUp() throws URISyntaxException, StorageException { + queue = QueueTestHelper.getRandomQueueReference(); + queue.createIfNotExists(); + } + + @After + public void queueClientGBTestMethodTearDown() throws StorageException { + queue.deleteIfExists(); + } @Test - public void testGB18030TestForSingleMessage() throws URISyntaxException, StorageException { + public void testGB18030TestForSingleMessage() throws StorageException { String messageContent = GB18030CharSet; CloudQueueMessage cqm = new CloudQueueMessage(messageContent); queue.addMessage(cqm); @@ -70,7 +85,7 @@ public void testGB18030TestForSingleMessage() throws URISyntaxException, Storage } @Test - public void testGB18030TestForMultipleMessages() throws URISyntaxException, StorageException { + public void testGB18030TestForMultipleMessages() throws StorageException { int messageLength = 2; String[] messageContents = new String[messageLength]; for (int i = 0; i < messageLength; i++) { diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/queue/CloudQueueClientTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/queue/CloudQueueClientTests.java similarity index 84% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/queue/CloudQueueClientTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/queue/CloudQueueClientTests.java index 94c8d69eabece..bb0e1129a48f5 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/queue/CloudQueueClientTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/queue/CloudQueueClientTests.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.queue; +package com.microsoft.azure.storage.queue; import static org.junit.Assert.*; @@ -25,19 +25,20 @@ import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.LocationMode; -import com.microsoft.windowsazure.storage.ResultSegment; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.TestHelper; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.LocationMode; +import com.microsoft.azure.storage.ResultSegment; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.TestHelper; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; -public final class CloudQueueClientTests extends QueueTestBase { +public final class CloudQueueClientTests { @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) @Test public void testListQueuesSmallNumber() throws URISyntaxException, StorageException { + CloudQueueClient qClient = QueueTestHelper.createCloudQueueClient(); int initialCount = 0; String prefix = UUID.randomUUID().toString().toLowerCase(); for (CloudQueue queue : qClient.listQueues(prefix)) { @@ -83,6 +84,7 @@ public void testListQueuesSmallNumber() throws URISyntaxException, StorageExcept @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) @Test public void testListQueuesAndListQueuesSegmentedLargeNumber() throws URISyntaxException, StorageException { + CloudQueueClient qClient = QueueTestHelper.createCloudQueueClient(); int count = 0; String prefix = UUID.randomUUID().toString(); for (CloudQueue queue : qClient.listQueues(prefix)) { @@ -111,6 +113,7 @@ public void testListQueuesAndListQueuesSegmentedLargeNumber() throws URISyntaxEx @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) @Test public void testListQueuesSegmented() throws URISyntaxException, StorageException { + CloudQueueClient qClient = QueueTestHelper.createCloudQueueClient(); String prefix = "segment" + UUID.randomUUID().toString().substring(0, 8).toLowerCase(); HashMap metadata1 = new HashMap(); @@ -146,7 +149,8 @@ public void testListQueuesSegmented() throws URISyntaxException, StorageExceptio @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) @Test - public void testListQueuesEqual() throws URISyntaxException, StorageException { + public void testListQueuesEqual() throws StorageException { + CloudQueueClient qClient = QueueTestHelper.createCloudQueueClient(); int count1 = 0; for (CloudQueue queue : qClient.listQueues()) { assertNotNull(queue); @@ -169,15 +173,7 @@ public void testListQueuesEqual() throws URISyntaxException, StorageException { assertEquals(count1, count3); } - @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) - @Test - public void testTimeout() throws URISyntaxException, StorageException { - assertTrue(qClient.getTimeoutInMs() == 30 * 1000); - qClient.setTimeoutInMs(60 * 1000); - assertTrue(qClient.getTimeoutInMs() == 60 * 1000); - } - - static String AppendQueueName(URI baseURI, String queueName) throws URISyntaxException { + static String AppendQueueName(URI baseURI, String queueName) { if (baseURI == null) return queueName; @@ -193,8 +189,8 @@ static String AppendQueueName(URI baseURI, String queueName) throws URISyntaxExc @Category({ CloudTests.class }) @Test public void testGetServiceStats() throws StorageException { - CloudQueueClient qClient = createCloudQueueClient(); - qClient.setLocationMode(LocationMode.SECONDARY_ONLY); + CloudQueueClient qClient = QueueTestHelper.createCloudQueueClient(); + qClient.getDefaultRequestOptions().setLocationMode(LocationMode.SECONDARY_ONLY); TestHelper.verifyServiceStats(qClient.getServiceStats()); } } diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/queue/CloudQueueTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/queue/CloudQueueTests.java similarity index 53% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/queue/CloudQueueTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/queue/CloudQueueTests.java index 351a2049e129f..fdd05f4fb2f30 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/queue/CloudQueueTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/queue/CloudQueueTests.java @@ -12,11 +12,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.queue; +package com.microsoft.azure.storage.queue; import static org.junit.Assert.*; -import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URI; import java.net.URISyntaxException; @@ -31,29 +30,43 @@ import java.util.TimeZone; import java.util.UUID; -import javax.xml.stream.XMLStreamException; - +import org.junit.After; +import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.AuthenticationScheme; -import com.microsoft.windowsazure.storage.LocationMode; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.RetryNoRetry; -import com.microsoft.windowsazure.storage.StorageCredentialsSharedAccessSignature; -import com.microsoft.windowsazure.storage.StorageErrorCodeStrings; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; -import com.microsoft.windowsazure.storage.TestRunners.SlowTests; -import com.microsoft.windowsazure.storage.core.PathUtility; +import com.microsoft.azure.storage.AuthenticationScheme; +import com.microsoft.azure.storage.LocationMode; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.RetryNoRetry; +import com.microsoft.azure.storage.StorageCredentialsSharedAccessSignature; +import com.microsoft.azure.storage.StorageErrorCodeStrings; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.TestHelper; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.TestRunners.SlowTests; +import com.microsoft.azure.storage.core.PathUtility; /** * Queue Tests */ @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) -public class CloudQueueTests extends QueueTestBase { +public class CloudQueueTests { + + private CloudQueue queue; + + @Before + public void queueTestMethodSetUp() throws URISyntaxException, StorageException { + queue = QueueTestHelper.getRandomQueueReference(); + queue.createIfNotExists(); + } + + @After + public void queueTestMethodTearDown() throws StorageException { + queue.deleteIfExists(); + } /** * Get permissions from string @@ -88,132 +101,108 @@ public void testQueuePermissionsFromString() { @Category(SlowTests.class) @Test - public void testQueueGetSetPermissionTest() throws StorageException, URISyntaxException, InterruptedException { - String name = generateRandomQueueName(); - CloudQueue newQueue = qClient.getQueueReference(name); - newQueue.create(); - + public void testQueueGetSetPermissionTest() throws StorageException, InterruptedException { QueuePermissions expectedPermissions; QueuePermissions testPermissions; - try { - // Test new permissions. - expectedPermissions = new QueuePermissions(); - testPermissions = newQueue.downloadPermissions(); - assertQueuePermissionsEqual(expectedPermissions, testPermissions); - - // Test setting empty permissions. - newQueue.uploadPermissions(expectedPermissions); - Thread.sleep(30000); - testPermissions = newQueue.downloadPermissions(); - assertQueuePermissionsEqual(expectedPermissions, testPermissions); - - // Add a policy, check setting and getting. - SharedAccessQueuePolicy policy1 = new SharedAccessQueuePolicy(); - Calendar now = GregorianCalendar.getInstance(); - policy1.setSharedAccessStartTime(now.getTime()); - now.add(Calendar.MINUTE, 10); - policy1.setSharedAccessExpiryTime(now.getTime()); - - policy1.setPermissions(EnumSet.of(SharedAccessQueuePermissions.READ, - SharedAccessQueuePermissions.PROCESSMESSAGES, SharedAccessQueuePermissions.ADD, - SharedAccessQueuePermissions.UPDATE)); - expectedPermissions.getSharedAccessPolicies().put(UUID.randomUUID().toString(), policy1); - - newQueue.uploadPermissions(expectedPermissions); - Thread.sleep(30000); - testPermissions = newQueue.downloadPermissions(); - assertQueuePermissionsEqual(expectedPermissions, testPermissions); - } - finally { - // cleanup - newQueue.deleteIfExists(); - } + // Test new permissions. + expectedPermissions = new QueuePermissions(); + testPermissions = queue.downloadPermissions(); + assertQueuePermissionsEqual(expectedPermissions, testPermissions); + + // Test setting empty permissions. + queue.uploadPermissions(expectedPermissions); + Thread.sleep(30000); + testPermissions = queue.downloadPermissions(); + assertQueuePermissionsEqual(expectedPermissions, testPermissions); + + // Add a policy, check setting and getting. + SharedAccessQueuePolicy policy1 = new SharedAccessQueuePolicy(); + Calendar now = GregorianCalendar.getInstance(); + policy1.setSharedAccessStartTime(now.getTime()); + now.add(Calendar.MINUTE, 10); + policy1.setSharedAccessExpiryTime(now.getTime()); + + policy1.setPermissions(EnumSet.of(SharedAccessQueuePermissions.READ, + SharedAccessQueuePermissions.PROCESSMESSAGES, SharedAccessQueuePermissions.ADD, + SharedAccessQueuePermissions.UPDATE)); + expectedPermissions.getSharedAccessPolicies().put(UUID.randomUUID().toString(), policy1); + + queue.uploadPermissions(expectedPermissions); + Thread.sleep(30000); + testPermissions = queue.downloadPermissions(); + assertQueuePermissionsEqual(expectedPermissions, testPermissions); } @Category(SlowTests.class) @Test public void testQueueSAS() throws StorageException, URISyntaxException, InvalidKeyException, InterruptedException { - String name = generateRandomQueueName(); - CloudQueue newQueue = qClient.getQueueReference(name); - newQueue.create(); - newQueue.addMessage(new CloudQueueMessage("sas queue test")); - + queue.addMessage(new CloudQueueMessage("sas queue test")); QueuePermissions expectedPermissions; - try { - expectedPermissions = new QueuePermissions(); - // Add a policy, check setting and getting. - SharedAccessQueuePolicy policy1 = new SharedAccessQueuePolicy(); - Calendar now = GregorianCalendar.getInstance(); - now.add(Calendar.MINUTE, -15); - policy1.setSharedAccessStartTime(now.getTime()); - now.add(Calendar.MINUTE, 30); - policy1.setSharedAccessExpiryTime(now.getTime()); - String identifier = UUID.randomUUID().toString(); - - policy1.setPermissions(EnumSet.of(SharedAccessQueuePermissions.READ, - SharedAccessQueuePermissions.PROCESSMESSAGES, SharedAccessQueuePermissions.ADD, - SharedAccessQueuePermissions.UPDATE)); - expectedPermissions.getSharedAccessPolicies().put(identifier, policy1); - - newQueue.uploadPermissions(expectedPermissions); - Thread.sleep(30000); - - CloudQueueClient queueClientFromIdentifierSAS = getQueueClientForSas(newQueue, null, identifier); - CloudQueue identifierSasQueue = queueClientFromIdentifierSAS.getQueueReference(newQueue.getName()); - - identifierSasQueue.downloadAttributes(); - identifierSasQueue.exists(); - - identifierSasQueue.addMessage(new CloudQueueMessage("message"), 20, 0, null, null); - CloudQueueMessage message1 = identifierSasQueue.retrieveMessage(); - identifierSasQueue.deleteMessage(message1); - - CloudQueueClient queueClientFromPolicySAS = getQueueClientForSas(newQueue, policy1, null); - CloudQueue policySasQueue = queueClientFromPolicySAS.getQueueReference(newQueue.getName()); - policySasQueue.exists(); - policySasQueue.downloadAttributes(); - - policySasQueue.addMessage(new CloudQueueMessage("message"), 20, 0, null, null); - CloudQueueMessage message2 = policySasQueue.retrieveMessage(); - policySasQueue.deleteMessage(message2); - - // do not give the client and check that the new queue's client has the correct perms - CloudQueue queueFromUri = new CloudQueue(PathUtility.addToQuery(newQueue.getStorageUri(), - newQueue.generateSharedAccessSignature(null, "readperm")), null); - assertEquals(StorageCredentialsSharedAccessSignature.class.toString(), queueFromUri.getServiceClient() - .getCredentials().getClass().toString()); - - // pass in a client which will have different permissions and check the sas permissions are used - // and that the properties set in the old service client are passed to the new client - CloudQueueClient queueClient = policySasQueue.getServiceClient(); - - // set some arbitrary settings to make sure they are passed on - queueClient.setLocationMode(LocationMode.PRIMARY_THEN_SECONDARY); - queueClient.setTimeoutInMs(1000); - queueClient.setRetryPolicyFactory(new RetryNoRetry()); - - queueFromUri = new CloudQueue(PathUtility.addToQuery(newQueue.getStorageUri(), - newQueue.generateSharedAccessSignature(null, "readperm")), queueClient); - assertEquals(StorageCredentialsSharedAccessSignature.class.toString(), queueFromUri.getServiceClient() - .getCredentials().getClass().toString()); - - assertEquals(queueClient.getLocationMode(), queueFromUri.getServiceClient().getLocationMode()); - assertEquals(queueClient.getTimeoutInMs(), queueFromUri.getServiceClient().getTimeoutInMs()); - assertEquals(queueClient.getRetryPolicyFactory().getClass(), queueFromUri.getServiceClient() - .getRetryPolicyFactory().getClass()); - } - finally { - // cleanup - newQueue.deleteIfExists(); - } - } + expectedPermissions = new QueuePermissions(); + // Add a policy, check setting and getting. + SharedAccessQueuePolicy policy1 = new SharedAccessQueuePolicy(); + Calendar now = GregorianCalendar.getInstance(); + now.add(Calendar.MINUTE, -15); + policy1.setSharedAccessStartTime(now.getTime()); + now.add(Calendar.MINUTE, 30); + policy1.setSharedAccessExpiryTime(now.getTime()); + String identifier = UUID.randomUUID().toString(); + + policy1.setPermissions(EnumSet.of(SharedAccessQueuePermissions.READ, + SharedAccessQueuePermissions.PROCESSMESSAGES, SharedAccessQueuePermissions.ADD, + SharedAccessQueuePermissions.UPDATE)); + expectedPermissions.getSharedAccessPolicies().put(identifier, policy1); + + queue.uploadPermissions(expectedPermissions); + Thread.sleep(30000); + + CloudQueue identifierSasQueue = new CloudQueue(PathUtility.addToQuery(queue.getUri(), + queue.generateSharedAccessSignature(null, identifier))); + + identifierSasQueue.downloadAttributes(); + identifierSasQueue.exists(); + + identifierSasQueue.addMessage(new CloudQueueMessage("message"), 20, 0, null, null); + CloudQueueMessage message1 = identifierSasQueue.retrieveMessage(); + identifierSasQueue.deleteMessage(message1); - private CloudQueueClient getQueueClientForSas(CloudQueue queue, SharedAccessQueuePolicy policy, - String accessIdentifier) throws InvalidKeyException, StorageException { - String sasString = queue.generateSharedAccessSignature(policy, accessIdentifier); - return new CloudQueueClient(qClient.getEndpoint(), new StorageCredentialsSharedAccessSignature(sasString)); + CloudQueue policySasQueue = new CloudQueue(PathUtility.addToQuery(queue.getUri(), + queue.generateSharedAccessSignature(policy1, null))); + policySasQueue.exists(); + policySasQueue.downloadAttributes(); + + policySasQueue.addMessage(new CloudQueueMessage("message"), 20, 0, null, null); + CloudQueueMessage message2 = policySasQueue.retrieveMessage(); + policySasQueue.deleteMessage(message2); + + // do not give the client and check that the new queue's client has the correct perms + CloudQueue queueFromUri = new CloudQueue(PathUtility.addToQuery(queue.getStorageUri(), + queue.generateSharedAccessSignature(null, "readperm"))); + assertEquals(StorageCredentialsSharedAccessSignature.class.toString(), queueFromUri.getServiceClient() + .getCredentials().getClass().toString()); + + // pass in a client which will have different permissions and check the sas permissions are used + // and that the properties set in the old service client are passed to the new client + CloudQueueClient queueClient = policySasQueue.getServiceClient(); + + // set some arbitrary settings to make sure they are passed on + queueClient.getDefaultRequestOptions().setLocationMode(LocationMode.PRIMARY_THEN_SECONDARY); + queueClient.getDefaultRequestOptions().setTimeoutIntervalInMs(1000); + queueClient.getDefaultRequestOptions().setRetryPolicyFactory(new RetryNoRetry()); + + queueFromUri = new CloudQueue(PathUtility.addToQuery(queue.getStorageUri(), + queue.generateSharedAccessSignature(null, "readperm")), queueClient); + assertEquals(StorageCredentialsSharedAccessSignature.class.toString(), queueFromUri.getServiceClient() + .getCredentials().getClass().toString()); + + assertEquals(queueClient.getDefaultRequestOptions().getLocationMode(), queueFromUri.getServiceClient() + .getDefaultRequestOptions().getLocationMode()); + assertEquals(queueClient.getDefaultRequestOptions().getTimeoutIntervalInMs(), queueFromUri.getServiceClient() + .getDefaultRequestOptions().getTimeoutIntervalInMs()); + assertEquals(queueClient.getDefaultRequestOptions().getRetryPolicyFactory().getClass(), queueFromUri + .getServiceClient().getDefaultRequestOptions().getRetryPolicyFactory().getClass()); } static void assertQueuePermissionsEqual(QueuePermissions expected, QueuePermissions actual) { @@ -237,13 +226,16 @@ static void assertQueuePermissionsEqual(QueuePermissions expected, QueuePermissi @Test public void testQueueClientConstructor() throws URISyntaxException, StorageException { - String queueName = "queue"; + final CloudQueueClient qClient = TestHelper.createCloudQueueClient(); + final String queueName = QueueTestHelper.generateRandomQueueName(); + CloudQueue queue1 = new CloudQueue(queueName, qClient); assertEquals(queueName, queue1.getName()); assertTrue(queue1.getUri().toString().endsWith(queueName)); assertEquals(qClient, queue1.getServiceClient()); - CloudQueue queue2 = new CloudQueue(new URI(AppendQueueName(qClient.getEndpoint(), queueName)), qClient); + CloudQueue queue2 = new CloudQueue(new URI(QueueTestHelper.appendQueueName(qClient.getEndpoint(), queueName)), + qClient); assertEquals(queueName, queue2.getName()); assertEquals(qClient, queue2.getServiceClient()); @@ -254,7 +246,7 @@ public void testQueueClientConstructor() throws URISyntaxException, StorageExcep } @Test - public void testGetMetadata() throws URISyntaxException, StorageException { + public void testGetMetadata() throws StorageException { HashMap metadata = new HashMap(); metadata.put("ExistingMetadata", "ExistingMetadataValue"); queue.setMetadata(metadata); @@ -329,10 +321,9 @@ public void testUploadMetadataClearExisting() throws URISyntaxException, Storage @Test public void testUploadMetadataNotFound() throws URISyntaxException, StorageException { - String queueName = UUID.randomUUID().toString().toLowerCase(); - CloudQueue newQueue = qClient.getQueueReference(queueName); + final CloudQueue queue = QueueTestHelper.getRandomQueueReference(); try { - newQueue.uploadMetadata(); + queue.uploadMetadata(); fail(); } catch (StorageException e) { @@ -343,80 +334,93 @@ public void testUploadMetadataNotFound() throws URISyntaxException, StorageExcep @Test public void testQueueCreate() throws URISyntaxException, StorageException { - String queueName = UUID.randomUUID().toString().toLowerCase(); - CloudQueue queue = qClient.getQueueReference(queueName); - assertEquals(queueName, queue.getName()); + CloudQueue queue = QueueTestHelper.getRandomQueueReference(); OperationContext createQueueContext = new OperationContext(); - queue.create(null, createQueueContext); - assertEquals(createQueueContext.getLastResult().getStatusCode(), HttpURLConnection.HTTP_CREATED); - try { - HashMap metadata1 = new HashMap(); - metadata1.put("ExistingMetadata1", "ExistingMetadataValue1"); - queue.setMetadata(metadata1); - queue.create(); - fail(); - } - catch (StorageException e) { - assertTrue(e.getHttpStatusCode() == HttpURLConnection.HTTP_CONFLICT); + queue.create(null, createQueueContext); + assertEquals(createQueueContext.getLastResult().getStatusCode(), HttpURLConnection.HTTP_CREATED); - } + try { + HashMap metadata1 = new HashMap(); + metadata1.put("ExistingMetadata1", "ExistingMetadataValue1"); + queue.setMetadata(metadata1); + queue.create(); + fail(); + } + catch (StorageException e) { + assertTrue(e.getHttpStatusCode() == HttpURLConnection.HTTP_CONFLICT); - queue.downloadAttributes(); - OperationContext createQueueContext2 = new OperationContext(); - queue.create(null, createQueueContext2); - assertEquals(createQueueContext2.getLastResult().getStatusCode(), HttpURLConnection.HTTP_NO_CONTENT); + } - queue.delete(); + queue.downloadAttributes(); + OperationContext createQueueContext2 = new OperationContext(); + queue.create(null, createQueueContext2); + assertEquals(createQueueContext2.getLastResult().getStatusCode(), HttpURLConnection.HTTP_NO_CONTENT); + } + finally { + queue.delete(); + } } @Test public void testQueueCreateAlreadyExists() throws URISyntaxException, StorageException { - String queueName = UUID.randomUUID().toString().toLowerCase(); + final CloudQueueClient qClient = TestHelper.createCloudQueueClient(); + final String queueName = QueueTestHelper.generateRandomQueueName(); CloudQueue queue = qClient.getQueueReference(queueName); assertEquals(queueName, queue.getName()); - OperationContext createQueueContext1 = new OperationContext(); - queue.create(null, createQueueContext1); - assertEquals(createQueueContext1.getLastResult().getStatusCode(), HttpURLConnection.HTTP_CREATED); + try { + OperationContext createQueueContext1 = new OperationContext(); + queue.create(null, createQueueContext1); + assertEquals(createQueueContext1.getLastResult().getStatusCode(), HttpURLConnection.HTTP_CREATED); - OperationContext createQueueContext2 = new OperationContext(); - queue.create(null, createQueueContext2); - assertEquals(createQueueContext2.getLastResult().getStatusCode(), HttpURLConnection.HTTP_NO_CONTENT); + OperationContext createQueueContext2 = new OperationContext(); + queue.create(null, createQueueContext2); + assertEquals(createQueueContext2.getLastResult().getStatusCode(), HttpURLConnection.HTTP_NO_CONTENT); + } + finally { + queue.deleteIfExists(); + } } @Test public void testQueueCreateAfterDelete() throws URISyntaxException, StorageException { - - String queueName = UUID.randomUUID().toString().toLowerCase(); + final CloudQueueClient qClient = TestHelper.createCloudQueueClient(); + final String queueName = QueueTestHelper.generateRandomQueueName(); CloudQueue queue = qClient.getQueueReference(queueName); assertEquals(queueName, queue.getName()); - OperationContext createQueueContext1 = new OperationContext(); - assertTrue(queue.createIfNotExists(null, createQueueContext1)); - assertEquals(createQueueContext1.getLastResult().getStatusCode(), HttpURLConnection.HTTP_CREATED); - - assertTrue(queue.deleteIfExists()); try { - queue.create(); - fail("Queue CreateIfNotExists did not throw exception while trying to create a queue in BeingDeleted State"); + OperationContext createQueueContext1 = new OperationContext(); + assertTrue(queue.createIfNotExists(null, createQueueContext1)); + assertEquals(createQueueContext1.getLastResult().getStatusCode(), HttpURLConnection.HTTP_CREATED); + + assertTrue(queue.deleteIfExists()); + try { + queue.create(); + fail("Queue CreateIfNotExists did not throw exception while trying to create a queue in BeingDeleted State"); + } + catch (StorageException ex) { + assertEquals("Expected 409 Exception, QueueBeingDeleted not thrown", ex.getHttpStatusCode(), + HttpURLConnection.HTTP_CONFLICT); + assertEquals("Expected 409 Exception, QueueBeingDeleted not thrown", ex.getExtendedErrorInformation() + .getErrorCode(), StorageErrorCodeStrings.QUEUE_BEING_DELETED); + } } - catch (StorageException ex) { - assertEquals("Expected 409 Exception, QueueBeingDeleted not thrown", ex.getHttpStatusCode(), - HttpURLConnection.HTTP_CONFLICT); - assertEquals("Expected 409 Exception, QueueBeingDeleted not thrown", ex.getExtendedErrorInformation() - .getErrorCode(), StorageErrorCodeStrings.QUEUE_BEING_DELETED); + finally { + queue.deleteIfExists(); } } @Test public void testQueueCreateIfNotExists() throws URISyntaxException, StorageException { - String queueName = UUID.randomUUID().toString().toLowerCase(); + final CloudQueueClient qClient = TestHelper.createCloudQueueClient(); + final String queueName = QueueTestHelper.generateRandomQueueName(); CloudQueue queue = qClient.getQueueReference(queueName); - try { - assertEquals(queueName, queue.getName()); + assertEquals(queueName, queue.getName()); + try { OperationContext createQueueContext = new OperationContext(); assertTrue(queue.createIfNotExists(null, createQueueContext)); assertEquals(createQueueContext.getLastResult().getStatusCode(), HttpURLConnection.HTTP_CREATED); @@ -430,96 +434,115 @@ public void testQueueCreateIfNotExists() throws URISyntaxException, StorageExcep @Test public void testQueueCreateIfNotExistsAfterCreate() throws URISyntaxException, StorageException { - String queueName = UUID.randomUUID().toString().toLowerCase(); + final CloudQueueClient qClient = TestHelper.createCloudQueueClient(); + final String queueName = QueueTestHelper.generateRandomQueueName(); CloudQueue queue = qClient.getQueueReference(queueName); assertEquals(queueName, queue.getName()); - OperationContext createQueueContext1 = new OperationContext(); - assertTrue(queue.createIfNotExists(null, createQueueContext1)); + try { + OperationContext createQueueContext1 = new OperationContext(); + assertTrue(queue.createIfNotExists(null, createQueueContext1)); - OperationContext createQueueContext2 = new OperationContext(); - assertFalse(queue.createIfNotExists(null, createQueueContext2)); + OperationContext createQueueContext2 = new OperationContext(); + assertFalse(queue.createIfNotExists(null, createQueueContext2)); + } + finally { + queue.deleteIfExists(); + } } @Test public void testQueueCreateIfNotExistsAfterDelete() throws URISyntaxException, StorageException { - - String queueName = UUID.randomUUID().toString().toLowerCase(); + final CloudQueueClient qClient = TestHelper.createCloudQueueClient(); + final String queueName = QueueTestHelper.generateRandomQueueName(); CloudQueue queue = qClient.getQueueReference(queueName); assertEquals(queueName, queue.getName()); - OperationContext createQueueContext1 = new OperationContext(); - assertTrue(queue.createIfNotExists(null, createQueueContext1)); - assertEquals(createQueueContext1.getLastResult().getStatusCode(), HttpURLConnection.HTTP_CREATED); - - assertTrue(queue.deleteIfExists()); try { - queue.createIfNotExists(); - fail("Queue CreateIfNotExists did not throw exception while trying to create a queue in BeingDeleted State"); + + OperationContext createQueueContext1 = new OperationContext(); + assertTrue(queue.createIfNotExists(null, createQueueContext1)); + assertEquals(createQueueContext1.getLastResult().getStatusCode(), HttpURLConnection.HTTP_CREATED); + + assertTrue(queue.deleteIfExists()); + try { + queue.createIfNotExists(); + fail("Queue CreateIfNotExists did not throw exception while trying to create a queue in BeingDeleted State"); + } + catch (StorageException ex) { + assertEquals("Expected 409 Exception, QueueBeingDeleted not thrown", ex.getHttpStatusCode(), + HttpURLConnection.HTTP_CONFLICT); + assertEquals("Expected 409 Exception, QueueBeingDeleted not thrown", ex.getExtendedErrorInformation() + .getErrorCode(), StorageErrorCodeStrings.QUEUE_BEING_DELETED); + } } - catch (StorageException ex) { - assertEquals("Expected 409 Exception, QueueBeingDeleted not thrown", ex.getHttpStatusCode(), - HttpURLConnection.HTTP_CONFLICT); - assertEquals("Expected 409 Exception, QueueBeingDeleted not thrown", ex.getExtendedErrorInformation() - .getErrorCode(), StorageErrorCodeStrings.QUEUE_BEING_DELETED); + finally { + queue.deleteIfExists(); } } @Test public void testQueueDelete() throws URISyntaxException, StorageException { - String queueName = UUID.randomUUID().toString().toLowerCase(); + final CloudQueueClient qClient = TestHelper.createCloudQueueClient(); + final String queueName = QueueTestHelper.generateRandomQueueName(); CloudQueue queue = qClient.getQueueReference(queueName); assertEquals(queueName, queue.getName()); - OperationContext createQueueContext = new OperationContext(); - queue.create(null, createQueueContext); - assertEquals(createQueueContext.getLastResult().getStatusCode(), HttpURLConnection.HTTP_CREATED); + try { + OperationContext createQueueContext = new OperationContext(); + queue.create(null, createQueueContext); + assertEquals(createQueueContext.getLastResult().getStatusCode(), HttpURLConnection.HTTP_CREATED); - OperationContext deleteQueueContext = new OperationContext(); - queue.delete(null, deleteQueueContext); - assertEquals(deleteQueueContext.getLastResult().getStatusCode(), HttpURLConnection.HTTP_NO_CONTENT); + OperationContext deleteQueueContext = new OperationContext(); + queue.delete(null, deleteQueueContext); + assertEquals(deleteQueueContext.getLastResult().getStatusCode(), HttpURLConnection.HTTP_NO_CONTENT); - try { - queue.downloadAttributes(); - fail(); + try { + queue.downloadAttributes(); + fail(); + } + catch (StorageException ex) { + assertEquals("Expected 404 Exception", ex.getHttpStatusCode(), HttpURLConnection.HTTP_NOT_FOUND); + } } - catch (StorageException ex) { - assertEquals("Expected 404 Exception", ex.getHttpStatusCode(), HttpURLConnection.HTTP_NOT_FOUND); + finally { + queue.deleteIfExists(); } - - queue.delete(); } @Test public void testDeleteQueueIfExists() throws URISyntaxException, StorageException { - final String queueName = UUID.randomUUID().toString().toLowerCase(); - final CloudQueue queue = qClient.getQueueReference(queueName); + final CloudQueue queue = QueueTestHelper.getRandomQueueReference(); assertFalse(queue.deleteIfExists()); - final OperationContext createQueueContext = new OperationContext(); - queue.create(null, createQueueContext); - assertEquals(createQueueContext.getLastResult().getStatusCode(), HttpURLConnection.HTTP_CREATED); + try { + final OperationContext createQueueContext = new OperationContext(); + queue.create(null, createQueueContext); + assertEquals(createQueueContext.getLastResult().getStatusCode(), HttpURLConnection.HTTP_CREATED); - assertTrue(queue.deleteIfExists()); - assertFalse(queue.deleteIfExists()); + assertTrue(queue.deleteIfExists()); + assertFalse(queue.deleteIfExists()); - try { - queue.create(); - fail("Queue CreateIfNotExists did not throw exception while trying to create a queue in BeingDeleted State"); + try { + queue.create(); + fail("Queue CreateIfNotExists did not throw exception while trying to create a queue in BeingDeleted State"); + } + catch (StorageException ex) { + assertEquals("Expected 409 Exception, QueueBeingDeleted not thrown", ex.getHttpStatusCode(), + HttpURLConnection.HTTP_CONFLICT); + assertEquals("Expected 409 Exception, QueueBeingDeleted not thrown", ex.getExtendedErrorInformation() + .getErrorCode(), StorageErrorCodeStrings.QUEUE_BEING_DELETED); + } } - catch (StorageException ex) { - assertEquals("Expected 409 Exception, QueueBeingDeleted not thrown", ex.getHttpStatusCode(), - HttpURLConnection.HTTP_CONFLICT); - assertEquals("Expected 409 Exception, QueueBeingDeleted not thrown", ex.getExtendedErrorInformation() - .getErrorCode(), StorageErrorCodeStrings.QUEUE_BEING_DELETED); + finally { + queue.delete(); } } @Test public void testDeleteNonExistingQueue() throws URISyntaxException, StorageException { - final String queueName = UUID.randomUUID().toString().toLowerCase(); - final CloudQueue queue = qClient.getQueueReference(queueName); + final CloudQueue queue = QueueTestHelper.getRandomQueueReference(); final OperationContext existQueueContext1 = new OperationContext(); assertTrue(!queue.exists(null, existQueueContext1)); @@ -536,27 +559,28 @@ public void testDeleteNonExistingQueue() throws URISyntaxException, StorageExcep @Test public void testQueueExist() throws URISyntaxException, StorageException { - final String queueName = UUID.randomUUID().toString().toLowerCase(); - final CloudQueue queue = qClient.getQueueReference(queueName); + final CloudQueue queue = QueueTestHelper.getRandomQueueReference(); final OperationContext existQueueContext1 = new OperationContext(); assertTrue(!queue.exists(null, existQueueContext1)); assertEquals(existQueueContext1.getLastResult().getStatusCode(), HttpURLConnection.HTTP_NOT_FOUND); - final OperationContext createQueueContext = new OperationContext(); - queue.create(null, createQueueContext); - assertEquals(createQueueContext.getLastResult().getStatusCode(), HttpURLConnection.HTTP_CREATED); + try { + final OperationContext createQueueContext = new OperationContext(); + queue.create(null, createQueueContext); + assertEquals(createQueueContext.getLastResult().getStatusCode(), HttpURLConnection.HTTP_CREATED); - final OperationContext existQueueContext2 = new OperationContext(); - assertTrue(queue.exists(null, existQueueContext2)); - assertEquals(existQueueContext2.getLastResult().getStatusCode(), HttpURLConnection.HTTP_OK); + final OperationContext existQueueContext2 = new OperationContext(); + assertTrue(queue.exists(null, existQueueContext2)); + assertEquals(existQueueContext2.getLastResult().getStatusCode(), HttpURLConnection.HTTP_OK); + } + finally { + queue.deleteIfExists(); + } } @Test - public void testClearMessages() throws URISyntaxException, StorageException, UnsupportedEncodingException { - final CloudQueue queue = qClient.getQueueReference(UUID.randomUUID().toString().toLowerCase()); - queue.create(); - + public void testClearMessages() throws StorageException { CloudQueueMessage message1 = new CloudQueueMessage("messagetest1"); queue.addMessage(message1); @@ -584,15 +608,13 @@ public void testClearMessages() throws URISyntaxException, StorageException, Uns assertTrue(count == 0); } - public void testClearMessagesEmptyQueue() throws URISyntaxException, StorageException, UnsupportedEncodingException { - final CloudQueue queue = qClient.getQueueReference(UUID.randomUUID().toString().toLowerCase()); - queue.create(); + public void testClearMessagesEmptyQueue() throws StorageException { queue.clear(); queue.delete(); } - public void testClearMessagesNotFound() throws URISyntaxException, StorageException, UnsupportedEncodingException { - final CloudQueue queue = qClient.getQueueReference(UUID.randomUUID().toString().toLowerCase()); + public void testClearMessagesNotFound() throws StorageException, URISyntaxException { + final CloudQueue queue = QueueTestHelper.getRandomQueueReference(); try { queue.clear(); fail(); @@ -603,27 +625,17 @@ public void testClearMessagesNotFound() throws URISyntaxException, StorageExcept } @Test - public void testAddMessage() throws URISyntaxException, StorageException, UnsupportedEncodingException { - final String queueName = UUID.randomUUID().toString().toLowerCase(); - final CloudQueue queue = qClient.getQueueReference(queueName); - queue.create(); - + public void testAddMessage() throws StorageException { String msgContent = UUID.randomUUID().toString(); final CloudQueueMessage message = new CloudQueueMessage(msgContent); queue.addMessage(message); CloudQueueMessage msgFromRetrieve1 = queue.retrieveMessage(); assertEquals(message.getMessageContentAsString(), msgContent); assertEquals(msgFromRetrieve1.getMessageContentAsString(), msgContent); - - queue.delete(); } @Test - public void testAddMessageUnicode() throws URISyntaxException, StorageException, UnsupportedEncodingException { - final String queueName = UUID.randomUUID().toString().toLowerCase(); - final CloudQueue queue = qClient.getQueueReference(queueName); - queue.create(); - + public void testAddMessageUnicode() throws StorageException { ArrayList messages = new ArrayList(); messages.add("Le débat sur l'identité nationale, l'idée du président Nicolas Sarkozy de déchoir des personnes d'origine étrangère de la nationalité française ... certains cas et les récentes mesures prises contre les Roms ont choqué les experts, qui rendront leurs conclusions le 27 août."); messages.add("Ваш логин Yahoo! дает доступ к таким мощным инструментам связи, как электронная почта, отправка мгновенных сообщений, функции безопасности, в частности, антивирусные средства и блокировщик всплывающей рекламы, и избранное, например, фото и музыка в сети — все бесплат"); @@ -650,92 +662,67 @@ public void testAddMessageUnicode() throws URISyntaxException, StorageException, assertEquals(msg, readBack.getMessageContentAsString()); queue.deleteMessage(readBack); } - - queue.delete(); } @Test - public void testAddMessageLargeVisibilityDelay() throws URISyntaxException, StorageException, - UnsupportedEncodingException { - final String queueName = UUID.randomUUID().toString().toLowerCase(); - final CloudQueue queue = qClient.getQueueReference(queueName); - queue.create(); - + public void testAddMessageLargeVisibilityDelay() throws StorageException { String msgContent = UUID.randomUUID().toString(); final CloudQueueMessage message = new CloudQueueMessage(msgContent); queue.addMessage(message, 100, 50, null, null); CloudQueueMessage msgFromRetrieve1 = queue.retrieveMessage(); assertNull(msgFromRetrieve1); - - queue.delete(); } @Test - public void testDeleteMessageWithDifferentQueueInstance() throws URISyntaxException, StorageException, - UnsupportedEncodingException { - final String queueName = UUID.randomUUID().toString().toLowerCase(); + public void testDeleteMessageWithDifferentQueueInstance() throws StorageException, URISyntaxException { + final CloudQueueClient qClient = TestHelper.createCloudQueueClient(); + final String queueName = QueueTestHelper.generateRandomQueueName(); final CloudQueue queue1 = qClient.getQueueReference(queueName); - queue1.create(); - - String msgContent = UUID.randomUUID().toString(); - final CloudQueueMessage message = new CloudQueueMessage(msgContent); - queue1.addMessage(message); - CloudQueueMessage msgFromRetrieved = queue1.retrieveMessage(); + try { + queue1.create(); - final CloudQueue queue2 = qClient.getQueueReference(queueName); - queue2.deleteMessage(msgFromRetrieved); + String msgContent = UUID.randomUUID().toString(); + final CloudQueueMessage message = new CloudQueueMessage(msgContent); + queue1.addMessage(message); + CloudQueueMessage msgFromRetrieved = queue1.retrieveMessage(); - queue1.delete(); + final CloudQueue queue2 = qClient.getQueueReference(queueName); + queue2.deleteMessage(msgFromRetrieved); + } + finally { + queue1.deleteIfExists(); + } } @Test - public void testAddMessageToNonExistingQueue() throws URISyntaxException, StorageException, - UnsupportedEncodingException { - String queueName = UUID.randomUUID().toString().toLowerCase(); - CloudQueue newQueue = qClient.getQueueReference(queueName); + public void testAddMessageToNonExistingQueue() throws StorageException, URISyntaxException { + final CloudQueueClient qClient = TestHelper.createCloudQueueClient(); + final CloudQueue queue = qClient.getQueueReference(QueueTestHelper.generateRandomQueueName()); String messageContent = "messagetest"; CloudQueueMessage message1 = new CloudQueueMessage(messageContent); try { - newQueue.addMessage(message1); + queue.addMessage(message1); fail(); } catch (StorageException e) { assertTrue(e.getHttpStatusCode() == HttpURLConnection.HTTP_NOT_FOUND); - } } @Test - public void testQueueUnicodeAndXmlMessageTest() throws URISyntaxException, StorageException, - UnsupportedEncodingException { - final String queueName = UUID.randomUUID().toString().toLowerCase(); - final CloudQueue queue = qClient.getQueueReference(queueName); - queue.create(); - + public void testQueueUnicodeAndXmlMessageTest() throws StorageException { String msgContent = "好"; final CloudQueueMessage message = new CloudQueueMessage(msgContent); queue.addMessage(message); CloudQueueMessage msgFromRetrieve1 = queue.retrieveMessage(); assertEquals(message.getMessageContentAsString(), msgContent); assertEquals(msgFromRetrieve1.getMessageContentAsString(), msgContent); - //assertEquals(message.getMessageContentAsByte(), msgFromRetrieve1.getMessageContentAsByte()); - - queue.delete(); } @Test - public void testAddMessageLargeMessageInput() throws URISyntaxException, StorageException, - UnsupportedEncodingException { - final String queueName = UUID.randomUUID().toString().toLowerCase(); - final CloudQueue queue = qClient.getQueueReference(queueName); - assertEquals(queueName, queue.getName()); - - final OperationContext createQueueContext = new OperationContext(); - queue.create(null, createQueueContext); - assertEquals(createQueueContext.getLastResult().getStatusCode(), HttpURLConnection.HTTP_CREATED); - + public void testAddMessageLargeMessageInput() throws StorageException { final Random rand = new Random(); byte[] content = new byte[64 * 1024]; @@ -754,11 +741,7 @@ public void testAddMessageLargeMessageInput() throws URISyntaxException, Storage @Category(SlowTests.class) @Test - public void testAddMessageWithVisibilityTimeout() throws URISyntaxException, StorageException, - UnsupportedEncodingException, InterruptedException { - final String queueName = UUID.randomUUID().toString().toLowerCase(); - final CloudQueue queue = qClient.getQueueReference(queueName); - queue.create(); + public void testAddMessageWithVisibilityTimeout() throws StorageException, InterruptedException { queue.addMessage(new CloudQueueMessage("message"), 20, 0, null, null); CloudQueueMessage m1 = queue.retrieveMessage(); Date d1 = m1.getExpirationTime(); @@ -774,7 +757,7 @@ public void testAddMessageWithVisibilityTimeout() throws URISyntaxException, Sto } @Test - public void testAddMessageNullMessage() throws URISyntaxException, StorageException, UnsupportedEncodingException { + public void testAddMessageNullMessage() throws StorageException { try { queue.addMessage(null); fail(); @@ -784,16 +767,7 @@ public void testAddMessageNullMessage() throws URISyntaxException, StorageExcept } @Test - public void testAddMessageSpecialVisibilityTimeout() throws URISyntaxException, StorageException, - UnsupportedEncodingException { - final String queueName = UUID.randomUUID().toString().toLowerCase(); - final CloudQueue queue = qClient.getQueueReference(queueName); - assertEquals(queueName, queue.getName()); - - final OperationContext createQueueContext = new OperationContext(); - queue.create(null, createQueueContext); - assertEquals(createQueueContext.getLastResult().getStatusCode(), HttpURLConnection.HTTP_CREATED); - + public void testAddMessageSpecialVisibilityTimeout() throws StorageException { CloudQueueMessage message = new CloudQueueMessage("test"); queue.addMessage(message, 1, 0, null, null); queue.addMessage(message, 7 * 24 * 60 * 60, 0, null, null); @@ -840,34 +814,28 @@ public void testAddMessageSpecialVisibilityTimeout() throws URISyntaxException, } catch (final IllegalArgumentException e) { } - - queue.delete(); } @Test - public void testDeleteMessage() throws URISyntaxException, StorageException, UnsupportedEncodingException { - String queueName = UUID.randomUUID().toString().toLowerCase(); - CloudQueue newQueue = qClient.getQueueReference(queueName); - newQueue.create(); - + public void testDeleteMessage() throws StorageException { CloudQueueMessage message1 = new CloudQueueMessage("messagetest1"); - newQueue.addMessage(message1); + queue.addMessage(message1); CloudQueueMessage message2 = new CloudQueueMessage("messagetest2"); - newQueue.addMessage(message2); + queue.addMessage(message2); - for (CloudQueueMessage message : newQueue.retrieveMessages(32)) { + for (CloudQueueMessage message : queue.retrieveMessages(32)) { OperationContext deleteQueueContext = new OperationContext(); - newQueue.deleteMessage(message, null, deleteQueueContext); + queue.deleteMessage(message, null, deleteQueueContext); assertEquals(deleteQueueContext.getLastResult().getStatusCode(), HttpURLConnection.HTTP_NO_CONTENT); } - assertTrue(newQueue.retrieveMessage() == null); + assertTrue(queue.retrieveMessage() == null); } @Test - public void testQueueCreateAddingMetadata() throws URISyntaxException, StorageException { - final CloudQueue queue = qClient.getQueueReference(UUID.randomUUID().toString().toLowerCase()); + public void testQueueCreateAddingMetadata() throws StorageException, URISyntaxException { + final CloudQueue queue = QueueTestHelper.getRandomQueueReference(); final HashMap metadata = new HashMap(5); for (int i = 0; i < 5; i++) { @@ -877,13 +845,18 @@ public void testQueueCreateAddingMetadata() throws URISyntaxException, StorageEx queue.setMetadata(metadata); final OperationContext createQueueContext = new OperationContext(); - queue.create(null, createQueueContext); - assertEquals(createQueueContext.getLastResult().getStatusCode(), HttpURLConnection.HTTP_CREATED); + + try { + queue.create(null, createQueueContext); + assertEquals(createQueueContext.getLastResult().getStatusCode(), HttpURLConnection.HTTP_CREATED); + } + finally { + queue.deleteIfExists(); + } } @Test - public void testDeleteMessageNullMessage() throws URISyntaxException, StorageException, - UnsupportedEncodingException { + public void testDeleteMessageNullMessage() throws StorageException { try { queue.deleteMessage(null); fail(); @@ -894,42 +867,36 @@ public void testDeleteMessageNullMessage() throws URISyntaxException, StorageExc @Category(SlowTests.class) @Test - public void testRetrieveMessage() throws URISyntaxException, StorageException, UnsupportedEncodingException, - InterruptedException { - String queueName = UUID.randomUUID().toString().toLowerCase(); - CloudQueue newQueue = qClient.getQueueReference(queueName); - newQueue.create(); - newQueue.addMessage(new CloudQueueMessage("message"), 20, 0, null, null); + public void testRetrieveMessage() throws StorageException, InterruptedException { + queue.addMessage(new CloudQueueMessage("message"), 20, 0, null, null); OperationContext opContext = new OperationContext(); - CloudQueueMessage message1 = newQueue.retrieveMessage(10, null /*QueueRequestOptions*/, opContext); + CloudQueueMessage message1 = queue.retrieveMessage(10, null /*QueueRequestOptions*/, opContext); Date expirationTime1 = message1.getExpirationTime(); Date insertionTime1 = message1.getInsertionTime(); Date nextVisibleTime1 = message1.getNextVisibleTime(); assertEquals(HttpURLConnection.HTTP_OK, opContext.getLastResult().getStatusCode()); - newQueue.deleteMessage(message1); + queue.deleteMessage(message1); Thread.sleep(2000); - newQueue.addMessage(new CloudQueueMessage("message"), 20, 0, null, null); - CloudQueueMessage message2 = newQueue.retrieveMessage(); + queue.addMessage(new CloudQueueMessage("message"), 20, 0, null, null); + CloudQueueMessage message2 = queue.retrieveMessage(); Date expirationTime2 = message2.getExpirationTime(); Date insertionTime2 = message2.getInsertionTime(); Date nextVisibleTime2 = message2.getNextVisibleTime(); - newQueue.deleteMessage(message2); + queue.deleteMessage(message2); assertTrue(expirationTime1.before(expirationTime2)); assertTrue(insertionTime1.before(insertionTime2)); assertTrue(nextVisibleTime1.before(nextVisibleTime2)); } @Test - public void testRetrieveMessageNonExistingQueue() throws URISyntaxException, StorageException, - UnsupportedEncodingException { - String queueName = UUID.randomUUID().toString().toLowerCase(); - CloudQueue newQueue = qClient.getQueueReference(queueName); + public void testRetrieveMessageNonExistingQueue() throws StorageException, URISyntaxException { + final CloudQueue queue = QueueTestHelper.getRandomQueueReference(); try { - newQueue.retrieveMessage(); + queue.retrieveMessage(); fail(); } catch (StorageException e) { @@ -939,10 +906,8 @@ public void testRetrieveMessageNonExistingQueue() throws URISyntaxException, Sto } @Test - public void testRetrieveMessageInvalidInput() throws URISyntaxException, StorageException, - UnsupportedEncodingException { - final String queueName = UUID.randomUUID().toString().toLowerCase(); - final CloudQueue queue = qClient.getQueueReference(queueName); + public void testRetrieveMessageInvalidInput() throws StorageException, URISyntaxException { + final CloudQueue queue = QueueTestHelper.getRandomQueueReference(); try { queue.retrieveMessage(-1, null, null); @@ -960,25 +925,18 @@ public void testRetrieveMessageInvalidInput() throws URISyntaxException, Storage } @Test - public void testRetrieveMessagesFromEmptyQueue() throws URISyntaxException, StorageException, - UnsupportedEncodingException { - String queueName = UUID.randomUUID().toString().toLowerCase(); - CloudQueue newQueue = qClient.getQueueReference(queueName); - newQueue.create(); - - for (CloudQueueMessage m : newQueue.retrieveMessages(32)) { + public void testRetrieveMessagesFromEmptyQueue() throws StorageException { + for (CloudQueueMessage m : queue.retrieveMessages(32)) { assertTrue(m.getId() != null); assertTrue(m.getPopReceipt() == null); } } @Test - public void testRetrieveMessagesNonFound() throws URISyntaxException, StorageException, - UnsupportedEncodingException { - String queueName = UUID.randomUUID().toString().toLowerCase(); - CloudQueue newQueue = qClient.getQueueReference(queueName); + public void testRetrieveMessagesNonFound() throws StorageException, URISyntaxException { + final CloudQueue queue = QueueTestHelper.getRandomQueueReference(); try { - newQueue.retrieveMessages(1); + queue.retrieveMessages(1); fail(); } catch (StorageException e) { @@ -988,26 +946,21 @@ public void testRetrieveMessagesNonFound() throws URISyntaxException, StorageExc } @Test - public void testDequeueCountIncreases() throws URISyntaxException, StorageException, UnsupportedEncodingException, - InterruptedException { - String queueName = UUID.randomUUID().toString().toLowerCase(); - CloudQueue newQueue = qClient.getQueueReference(queueName); - newQueue.create(); - newQueue.addMessage(new CloudQueueMessage("message"), 20, 0, null, null); - CloudQueueMessage message1 = newQueue.retrieveMessage(1, null, null); + public void testDequeueCountIncreases() throws StorageException, InterruptedException { + queue.addMessage(new CloudQueueMessage("message"), 20, 0, null, null); + CloudQueueMessage message1 = queue.retrieveMessage(1, null, null); assertTrue(message1.getDequeueCount() == 1); for (int i = 2; i < 5; i++) { Thread.sleep(2000); - CloudQueueMessage message2 = newQueue.retrieveMessage(1, null, null); + CloudQueueMessage message2 = queue.retrieveMessage(1, null, null); assertTrue(message2.getDequeueCount() == i); } } @Test - public void testRetrieveMessageSpecialVisibilityTimeout() throws URISyntaxException, StorageException, - UnsupportedEncodingException { + public void testRetrieveMessageSpecialVisibilityTimeout() throws StorageException { try { queue.retrieveMessage(-1, null, null); @@ -1018,30 +971,21 @@ public void testRetrieveMessageSpecialVisibilityTimeout() throws URISyntaxExcept } @Test - public void testRetrieveMessages() throws URISyntaxException, StorageException, UnsupportedEncodingException { - String queueName = UUID.randomUUID().toString().toLowerCase(); - CloudQueue newQueue = qClient.getQueueReference(queueName); - newQueue.create(); - + public void testRetrieveMessages() throws StorageException { CloudQueueMessage message1 = new CloudQueueMessage("messagetest1"); - newQueue.addMessage(message1); + queue.addMessage(message1); CloudQueueMessage message2 = new CloudQueueMessage("messagetest2"); - newQueue.addMessage(message2); + queue.addMessage(message2); - for (CloudQueueMessage m : newQueue.retrieveMessages(32)) { + for (CloudQueueMessage m : queue.retrieveMessages(32)) { assertTrue(m.getId() != null); assertTrue(m.getPopReceipt() != null); } } @Test - public void testRetrieveMessagesInvalidInput() throws URISyntaxException, StorageException, - UnsupportedEncodingException { - final String queueName = UUID.randomUUID().toString().toLowerCase(); - final CloudQueue queue = qClient.getQueueReference(queueName); - queue.createIfNotExists(); - + public void testRetrieveMessagesInvalidInput() throws StorageException { for (int i = 0; i < 33; i++) { queue.addMessage(new CloudQueueMessage("test" + i)); } @@ -1069,53 +1013,36 @@ public void testRetrieveMessagesInvalidInput() throws URISyntaxException, Storag } catch (final IllegalArgumentException e) { } - - queue.delete(); } @Test - public void testPeekMessage() throws URISyntaxException, StorageException, UnsupportedEncodingException { - String queueName = UUID.randomUUID().toString().toLowerCase(); - CloudQueue newQueue = qClient.getQueueReference(queueName); - newQueue.create(); - + public void testPeekMessage() throws StorageException { CloudQueueMessage message1 = new CloudQueueMessage("messagetest1"); - newQueue.addMessage(message1); + queue.addMessage(message1); - CloudQueueMessage msg = newQueue.peekMessage(); + CloudQueueMessage msg = queue.peekMessage(); assertTrue(msg.getId() != null); assertTrue(msg.getPopReceipt() == null); - newQueue.delete(); + queue.delete(); } @Test - public void testPeekMessages() throws URISyntaxException, StorageException, UnsupportedEncodingException { - String queueName = UUID.randomUUID().toString().toLowerCase(); - CloudQueue newQueue = qClient.getQueueReference(queueName); - newQueue.create(); - + public void testPeekMessages() throws StorageException { CloudQueueMessage message1 = new CloudQueueMessage("messagetest1"); - newQueue.addMessage(message1); + queue.addMessage(message1); CloudQueueMessage message2 = new CloudQueueMessage("messagetest2"); - newQueue.addMessage(message2); + queue.addMessage(message2); - for (CloudQueueMessage m : newQueue.peekMessages(32)) { + for (CloudQueueMessage m : queue.peekMessages(32)) { assertTrue(m.getId() != null); assertTrue(m.getPopReceipt() == null); } - - newQueue.delete(); } @Test - public void testPeekMessagesInvalidInput() throws URISyntaxException, StorageException, - UnsupportedEncodingException { - final String queueName = UUID.randomUUID().toString().toLowerCase(); - final CloudQueue queue = qClient.getQueueReference(queueName); - queue.createIfNotExists(); - + public void testPeekMessagesInvalidInput() throws StorageException { for (int i = 0; i < 33; i++) { queue.addMessage(new CloudQueueMessage("test" + i)); } @@ -1143,17 +1070,13 @@ public void testPeekMessagesInvalidInput() throws URISyntaxException, StorageExc } catch (final IllegalArgumentException e) { } - - queue.delete(); } @Test - public void testPeekMessageNonExistingQueue() throws URISyntaxException, StorageException, - UnsupportedEncodingException { - String queueName = UUID.randomUUID().toString().toLowerCase(); - CloudQueue newQueue = qClient.getQueueReference(queueName); + public void testPeekMessageNonExistingQueue() throws StorageException, URISyntaxException { + CloudQueue queue = QueueTestHelper.getRandomQueueReference(); try { - newQueue.peekMessage(); + queue.peekMessage(); fail(); } catch (StorageException e) { @@ -1163,11 +1086,10 @@ public void testPeekMessageNonExistingQueue() throws URISyntaxException, Storage } @Test - public void testPeekMessagesNonFound() throws URISyntaxException, StorageException, UnsupportedEncodingException { - String queueName = UUID.randomUUID().toString().toLowerCase(); - CloudQueue newQueue = qClient.getQueueReference(queueName); + public void testPeekMessagesNonFound() throws StorageException, URISyntaxException { + CloudQueue queue = QueueTestHelper.getRandomQueueReference(); try { - newQueue.peekMessages(1); + queue.peekMessages(1); fail(); } catch (StorageException e) { @@ -1177,20 +1099,15 @@ public void testPeekMessagesNonFound() throws URISyntaxException, StorageExcepti } @Test - public void testPeekMessagesFromEmptyQueue() throws URISyntaxException, StorageException, - UnsupportedEncodingException { - String queueName = UUID.randomUUID().toString().toLowerCase(); - CloudQueue newQueue = qClient.getQueueReference(queueName); - newQueue.create(); - - for (CloudQueueMessage m : newQueue.peekMessages(32)) { + public void testPeekMessagesFromEmptyQueue() throws StorageException { + for (CloudQueueMessage m : queue.peekMessages(32)) { assertTrue(m.getId() != null); assertTrue(m.getPopReceipt() == null); } } @Test - public void testUpdateMessage() throws URISyntaxException, StorageException, UnsupportedEncodingException { + public void testUpdateMessage() throws StorageException { queue.clear(); @@ -1215,17 +1132,13 @@ public void testUpdateMessage() throws URISyntaxException, StorageException, Uns @Category(SlowTests.class) @Test - public void testUpdateMessageFullPass() throws URISyntaxException, StorageException, UnsupportedEncodingException, - InterruptedException { - String queueName = UUID.randomUUID().toString().toLowerCase(); - CloudQueue newQueue = qClient.getQueueReference(queueName); - newQueue.create(); + public void testUpdateMessageFullPass() throws StorageException, InterruptedException { CloudQueueMessage message = new CloudQueueMessage("message"); - newQueue.addMessage(message, 20, 0, null, null); - CloudQueueMessage message1 = newQueue.retrieveMessage(); + queue.addMessage(message, 20, 0, null, null); + CloudQueueMessage message1 = queue.retrieveMessage(); String popreceipt1 = message1.getPopReceipt(); Date NextVisibleTim1 = message1.getNextVisibleTime(); - newQueue.updateMessage(message1, 100, EnumSet.of(MessageUpdateFields.VISIBILITY), null, null); + queue.updateMessage(message1, 100, EnumSet.of(MessageUpdateFields.VISIBILITY), null, null); String popreceipt2 = message1.getPopReceipt(); Date NextVisibleTim2 = message1.getNextVisibleTime(); assertTrue(popreceipt2 != popreceipt1); @@ -1236,24 +1149,23 @@ public void testUpdateMessageFullPass() throws URISyntaxException, StorageExcept String newMesage = message.getMessageContentAsString() + "updated"; message.setMessageContent(newMesage); OperationContext oc = new OperationContext(); - newQueue.updateMessage(message1, 100, EnumSet.of(MessageUpdateFields.CONTENT), null, oc); + queue.updateMessage(message1, 100, EnumSet.of(MessageUpdateFields.CONTENT), null, oc); assertEquals(oc.getLastResult().getStatusCode(), HttpURLConnection.HTTP_NO_CONTENT); String popreceipt3 = message1.getPopReceipt(); Date NextVisibleTim3 = message1.getNextVisibleTime(); assertTrue(popreceipt3 != popreceipt2); assertTrue(NextVisibleTim2.before(NextVisibleTim3)); - assertTrue(newQueue.retrieveMessage() == null); + assertTrue(queue.retrieveMessage() == null); - newQueue.updateMessage(message1, 0, EnumSet.of(MessageUpdateFields.VISIBILITY), null, null); + queue.updateMessage(message1, 0, EnumSet.of(MessageUpdateFields.VISIBILITY), null, null); - CloudQueueMessage messageFromGet = newQueue.retrieveMessage(); + CloudQueueMessage messageFromGet = queue.retrieveMessage(); assertEquals(messageFromGet.getMessageContentAsString(), message1.getMessageContentAsString()); } @Test - public void testUpdateMessageWithContentChange() throws URISyntaxException, StorageException, - UnsupportedEncodingException { + public void testUpdateMessageWithContentChange() throws StorageException { CloudQueueMessage message1 = new CloudQueueMessage("messagetest1"); queue.addMessage(message1); @@ -1270,8 +1182,7 @@ public void testUpdateMessageWithContentChange() throws URISyntaxException, Stor } @Test - public void testUpdateMessageNullMessage() throws URISyntaxException, StorageException, - UnsupportedEncodingException { + public void testUpdateMessageNullMessage() throws StorageException { try { queue.updateMessage(null, 0); fail(); @@ -1281,12 +1192,7 @@ public void testUpdateMessageNullMessage() throws URISyntaxException, StorageExc } @Test - public void testUpdateMessageInvalidMessage() throws URISyntaxException, StorageException, - UnsupportedEncodingException { - final String queueName = UUID.randomUUID().toString().toLowerCase(); - final CloudQueue queue = qClient.getQueueReference(queueName); - queue.create(null, null); - + public void testUpdateMessageInvalidMessage() throws StorageException { CloudQueueMessage message = new CloudQueueMessage("test"); queue.addMessage(message, 1, 0, null, null); @@ -1301,11 +1207,7 @@ public void testUpdateMessageInvalidMessage() throws URISyntaxException, Storage } @Test - public void testGetApproximateMessageCount() throws URISyntaxException, StorageException, - UnsupportedEncodingException { - final String queueName = UUID.randomUUID().toString().toLowerCase(); - final CloudQueue queue = qClient.getQueueReference(queueName); - queue.create(); + public void testGetApproximateMessageCount() throws StorageException { assertTrue(queue.getApproximateMessageCount() == 0); queue.addMessage(new CloudQueueMessage("message1")); queue.addMessage(new CloudQueueMessage("message2")); @@ -1316,11 +1218,7 @@ public void testGetApproximateMessageCount() throws URISyntaxException, StorageE } @Test - public void testShouldEncodeMessage() throws URISyntaxException, StorageException { - final String queueName = UUID.randomUUID().toString().toLowerCase(); - final CloudQueue queue = qClient.getQueueReference(queueName); - queue.create(); - + public void testShouldEncodeMessage() throws StorageException { String msgContent = UUID.randomUUID().toString(); final CloudQueueMessage message = new CloudQueueMessage(msgContent); queue.setShouldEncodeMessage(true); @@ -1339,18 +1237,12 @@ public void testShouldEncodeMessage() throws URISyntaxException, StorageExceptio } @Test - public void testQueueDownloadAttributes() throws URISyntaxException, StorageException, - UnsupportedEncodingException, XMLStreamException { - final String queueName = UUID.randomUUID().toString().toLowerCase(); - - final CloudQueue queue1 = qClient.getQueueReference(queueName); - queue1.create(); - + public void testQueueDownloadAttributes() throws StorageException, URISyntaxException { final CloudQueueMessage message1 = new CloudQueueMessage("messagetest1"); - queue1.addMessage(message1); + queue.addMessage(message1); final CloudQueueMessage message2 = new CloudQueueMessage("messagetest2"); - queue1.addMessage(message2); + queue.addMessage(message2); final HashMap metadata = new HashMap(5); int sum = 5; @@ -1358,23 +1250,21 @@ public void testQueueDownloadAttributes() throws URISyntaxException, StorageExce metadata.put("key" + i, "value" + i); } - queue1.setMetadata(metadata); - queue1.uploadMetadata(); + queue.setMetadata(metadata); + queue.uploadMetadata(); - final CloudQueue queue2 = qClient.getQueueReference(queueName); + CloudQueueClient qClient = TestHelper.createCloudQueueClient(); + final CloudQueue queue2 = qClient.getQueueReference(queue.getName()); queue2.downloadAttributes(); assertEquals(sum, queue2.getMetadata().size()); - - queue1.delete(); } @Test - public void testQueueDownloadAttributesNotFound() throws URISyntaxException, StorageException { - String queueName = UUID.randomUUID().toString().toLowerCase(); - CloudQueue newQueue = qClient.getQueueReference(queueName); + public void testQueueDownloadAttributesNotFound() throws StorageException, URISyntaxException { + final CloudQueue queue = QueueTestHelper.getRandomQueueReference(); try { - newQueue.downloadAttributes(); + queue.downloadAttributes(); fail(); } catch (StorageException e) { @@ -1384,15 +1274,7 @@ public void testQueueDownloadAttributesNotFound() throws URISyntaxException, Sto } @Test - public void testQueueUpdateMetaData() throws URISyntaxException, StorageException { - final String queueName = UUID.randomUUID().toString().toLowerCase(); - final CloudQueue queue = qClient.getQueueReference(queueName); - assertEquals(queueName, queue.getName()); - - final OperationContext createQueueContext = new OperationContext(); - queue.create(null, createQueueContext); - assertEquals(createQueueContext.getLastResult().getStatusCode(), HttpURLConnection.HTTP_CREATED); - + public void testQueueUpdateMetaData() throws StorageException { final HashMap metadata = new HashMap(5); for (int i = 0; i < 5; i++) { metadata.put("key" + i, "value" + i); @@ -1403,7 +1285,7 @@ public void testQueueUpdateMetaData() throws URISyntaxException, StorageExceptio } @Test - public void testSASClientParse() throws StorageException, URISyntaxException, InvalidKeyException { + public void testSASClientParse() throws StorageException, InvalidKeyException, URISyntaxException { // Add a policy, check setting and getting. SharedAccessQueuePolicy policy1 = new SharedAccessQueuePolicy(); @@ -1434,11 +1316,10 @@ public void testSASClientParse() throws StorageException, URISyntaxException, In } @Test - public void testQueueSharedKeyLite() throws URISyntaxException, StorageException { + public void testQueueSharedKeyLite() throws StorageException, URISyntaxException { + CloudQueueClient qClient = TestHelper.createCloudQueueClient(); qClient.setAuthenticationScheme(AuthenticationScheme.SHAREDKEYLITE); - String queueName = UUID.randomUUID().toString().toLowerCase(); - CloudQueue queue = qClient.getQueueReference(queueName); - assertEquals(queueName, queue.getName()); + CloudQueue queue = qClient.getQueueReference(QueueTestHelper.generateRandomQueueName()); OperationContext createQueueContext = new OperationContext(); queue.create(null, createQueueContext); diff --git a/microsoft-azure-storage-test/src/com/microsoft/azure/storage/queue/QueueTestHelper.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/queue/QueueTestHelper.java new file mode 100644 index 0000000000000..a5ac14fc3c031 --- /dev/null +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/queue/QueueTestHelper.java @@ -0,0 +1,54 @@ +/** + * 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.queue; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.UUID; + +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.TestHelper; + +/** + * Queue Test Base + */ +public class QueueTestHelper extends TestHelper { + + public static String generateRandomQueueName() { + String queueName = "queue" + UUID.randomUUID().toString(); + return queueName.replace("-", ""); + } + + public static CloudQueue getRandomQueueReference() throws URISyntaxException, StorageException { + String queueName = generateRandomQueueName(); + CloudQueueClient qClient = createCloudQueueClient(); + CloudQueue queue = qClient.getQueueReference(queueName); + + return queue; + } + + static String appendQueueName(URI baseURI, String queueName) { + if (baseURI == null) + return queueName; + + String baseAddress = baseURI.toString(); + if (baseAddress.endsWith("/")) { + return baseAddress + queueName; + } + else { + return baseAddress + "/" + queueName; + } + } +} diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableBatchOperationTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableBatchOperationTests.java similarity index 87% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableBatchOperationTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableBatchOperationTests.java index 1047b87cf4e3d..a05062fc0ea10 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableBatchOperationTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableBatchOperationTests.java @@ -12,11 +12,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import static org.junit.Assert.*; import java.net.HttpURLConnection; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; @@ -25,21 +26,38 @@ import java.util.Random; import java.util.UUID; +import org.junit.After; +import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.LocationMode; -import com.microsoft.windowsazure.storage.RetryNoRetry; -import com.microsoft.windowsazure.storage.SecondaryTests; -import com.microsoft.windowsazure.storage.StorageErrorCodeStrings; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; -import com.microsoft.windowsazure.storage.core.SR; +import com.microsoft.azure.storage.LocationMode; +import com.microsoft.azure.storage.RetryNoRetry; +import com.microsoft.azure.storage.SecondaryTests; +import com.microsoft.azure.storage.StorageErrorCodeStrings; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.table.TableTestHelper.Class1; +import com.microsoft.azure.storage.table.TableTestHelper.Class2; @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) -public class TableBatchOperationTests extends TableTestBase { +public class TableBatchOperationTests { + + private CloudTable table; + + @Before + public void tableTestMethodSetUp() throws URISyntaxException, StorageException { + table = TableTestHelper.getRandomTableReference(); + table.createIfNotExists(); + } + + @After + public void tableTestMethodTearDown() throws StorageException { + table.deleteIfExists(); + } @Test public void testBatchAddAll() throws StorageException { @@ -60,7 +78,7 @@ public void testBatchAddAll() throws StorageException { // test to make sure we can't now add a query with addAll() ops.clear(); - Class1 ref = generateRandomEntity("jxscl_odata"); + Class1 ref = TableTestHelper.generateRandomEntity("jxscl_odata"); ops.add(TableOperation.retrieve(ref.partitionKey, ref.rowKey, ref.getClass())); try { batch.addAll(ops); @@ -102,7 +120,7 @@ public void testBatchAddAllIndex() throws StorageException { // test to make sure we can't now add a query with addAll() ops.clear(); - Class1 ref = generateRandomEntity("jxscl_odata"); + Class1 ref = TableTestHelper.generateRandomEntity("jxscl_odata"); ops.add(TableOperation.retrieve(ref.partitionKey, ref.rowKey, ref.getClass())); try { batch.addAll(0, ops); @@ -132,7 +150,7 @@ public void testBatchAddAllWithRetrieveShouldThrow() throws StorageException { TableBatchOperation batch = new TableBatchOperation(); // Insert entity to retrieve - Class1 baseEntity = generateRandomEntity("jxscl_odata"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(baseEntity), null, null); ops.add(TableOperation.retrieve(baseEntity.getPartitionKey(), baseEntity.getRowKey(), Class1.class)); @@ -147,11 +165,11 @@ public void testBatchAddAllWithRetrieveShouldThrow() throws StorageException { @Test @Category(SecondaryTests.class) - public void testBatchAddIndex() throws StorageException { + public void testBatchAddIndex() { TableBatchOperation batch = new TableBatchOperation(); // add a retrieve - Class1 ref = generateRandomEntity("jxscl_odata"); + Class1 ref = TableTestHelper.generateRandomEntity("jxscl_odata"); TableOperation queryOp = TableOperation.retrieve(ref.getPartitionKey(), ref.getRowKey(), ref.getClass()); batch.add(0, queryOp); @@ -160,7 +178,7 @@ public void testBatchAddIndex() throws StorageException { assertEquals(0, batch.size()); // should be able to add an entity with a different partition key - Class1 baseEntity = generateRandomEntity("jxscl_odata_2"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata_2"); TableOperation op = TableOperation.insert(baseEntity); batch.add(0, op); @@ -169,7 +187,7 @@ public void testBatchAddIndex() throws StorageException { assertEquals(0, batch.size()); // add a retrieve to the batch - ref = generateRandomEntity("jxscl_odata"); + ref = TableTestHelper.generateRandomEntity("jxscl_odata"); queryOp = TableOperation.retrieve(ref.getPartitionKey(), ref.getRowKey(), ref.getClass()); batch.add(0, queryOp); } @@ -186,7 +204,7 @@ public void testBatchRemoveAll() throws StorageException { assertEquals(0, batch.size()); // should be able to add an entity with a different partition key - Class1 baseEntity = generateRandomEntity("jxscl_odata_2"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata_2"); batch.insert(baseEntity); } @@ -203,7 +221,7 @@ public void testBatchRemoveRange() throws StorageException { assertEquals(0, batch.size()); // should be able to add an entity with a different partition key - Class1 baseEntity = generateRandomEntity("jxscl_odata_2"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata_2"); batch.insert(baseEntity); batch.removeRange(0, 1); @@ -212,7 +230,7 @@ public void testBatchRemoveRange() throws StorageException { batch.removeRange(0, ops.size() - 1); // should be not be able to add an entity with a different partition key - baseEntity = generateRandomEntity("jxscl_odata_2"); + baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata_2"); try { batch.insert(baseEntity); fail(SR.OPS_IN_BATCH_MUST_HAVE_SAME_PARTITION_KEY); @@ -224,18 +242,18 @@ public void testBatchRemoveRange() throws StorageException { batch.removeRange(0, 1); // should be able to add a retrieve to the batch - Class1 ref = generateRandomEntity("jxscl_odata"); + Class1 ref = TableTestHelper.generateRandomEntity("jxscl_odata"); TableOperation queryOp = TableOperation.retrieve(ref.getPartitionKey(), ref.getRowKey(), ref.getClass()); batch.add(queryOp); } @Test @Category(SecondaryTests.class) - public void testBatchRemove() throws StorageException { + public void testBatchRemove() { TableBatchOperation batch = new TableBatchOperation(); // add a retrieve - Class1 ref = generateRandomEntity("jxscl_odata"); + Class1 ref = TableTestHelper.generateRandomEntity("jxscl_odata"); TableOperation queryOp = TableOperation.retrieve(ref.getPartitionKey(), ref.getRowKey(), ref.getClass()); batch.add(queryOp); @@ -244,7 +262,7 @@ public void testBatchRemove() throws StorageException { assertEquals(0, batch.size()); // should be able to add an entity with a different partition key - Class1 baseEntity = generateRandomEntity("jxscl_odata_2"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata_2"); TableOperation op = TableOperation.insert(baseEntity); batch.add(op); @@ -253,17 +271,17 @@ public void testBatchRemove() throws StorageException { assertEquals(0, batch.size()); // should be able to add a retrieve to the batch - ref = generateRandomEntity("jxscl_odata"); + ref = TableTestHelper.generateRandomEntity("jxscl_odata"); queryOp = TableOperation.retrieve(ref.getPartitionKey(), ref.getRowKey(), ref.getClass()); batch.add(queryOp); } @Test - public void testBatchLockToPartitionKey() throws StorageException { + public void testBatchLockToPartitionKey() { try { TableBatchOperation batch = new TableBatchOperation(); - batch.insert(generateRandomEntity("jxscl_odata")); - batch.insert(generateRandomEntity("jxscl_odata2")); + batch.insert(TableTestHelper.generateRandomEntity("jxscl_odata")); + batch.insert(TableTestHelper.generateRandomEntity("jxscl_odata2")); } catch (IllegalArgumentException ex) { assertEquals(ex.getMessage(), SR.OPS_IN_BATCH_MUST_HAVE_SAME_PARTITION_KEY); @@ -271,12 +289,12 @@ public void testBatchLockToPartitionKey() throws StorageException { } @Test - public void testBatchRetrieveAndOneMoreOperationShouldThrow() throws StorageException { - Class1 ref2 = generateRandomEntity("jxscl_odata"); + public void testBatchRetrieveAndOneMoreOperationShouldThrow() { + Class1 ref2 = TableTestHelper.generateRandomEntity("jxscl_odata"); try { TableBatchOperation batch = new TableBatchOperation(); - batch.insert(generateRandomEntity("jxscl_odata")); + batch.insert(TableTestHelper.generateRandomEntity("jxscl_odata")); batch.retrieve(ref2.getPartitionKey(), ref2.getRowKey(), ref2.getClass()); fail(); } @@ -287,7 +305,7 @@ public void testBatchRetrieveAndOneMoreOperationShouldThrow() throws StorageExce try { TableBatchOperation batch = new TableBatchOperation(); batch.retrieve(ref2.getPartitionKey(), ref2.getRowKey(), ref2.getClass()); - batch.insert(generateRandomEntity("jxscl_odata")); + batch.insert(TableTestHelper.generateRandomEntity("jxscl_odata")); fail(); } catch (IllegalArgumentException ex) { @@ -296,7 +314,7 @@ public void testBatchRetrieveAndOneMoreOperationShouldThrow() throws StorageExce } @Test - public void testBatchAddNullShouldThrow() throws StorageException { + public void testBatchAddNullShouldThrow() { try { TableBatchOperation batch = new TableBatchOperation(); batch.add(null); @@ -308,7 +326,7 @@ public void testBatchAddNullShouldThrow() throws StorageException { } @Test - public void testBatchRetrieveWithNullResolverShouldThrow() throws StorageException { + public void testBatchRetrieveWithNullResolverShouldThrow() { try { TableBatchOperation batch = new TableBatchOperation(); batch.retrieve("foo", "blah", (EntityResolver) null); @@ -334,9 +352,9 @@ public void testEmptyBatchShouldThrow() throws StorageException { } @Test - public void testBatchMultiQueryShouldThrow() throws StorageException { - Class1 ref = generateRandomEntity("jxscl_odata"); - Class1 ref2 = generateRandomEntity("jxscl_odata"); + public void testBatchMultiQueryShouldThrow() { + Class1 ref = TableTestHelper.generateRandomEntity("jxscl_odata"); + Class1 ref2 = TableTestHelper.generateRandomEntity("jxscl_odata"); try { TableBatchOperation batch = new TableBatchOperation(); @@ -353,7 +371,7 @@ public void testBatchMultiQueryShouldThrow() throws StorageException { // don't need the category secondary as the request will fail before being sent public void testBatchSecondaryWriteShouldThrow() { // create batch with an insert - Class1 baseEntity = generateRandomEntity("jxscl_odata"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); TableOperation op = TableOperation.insert(baseEntity); TableBatchOperation batch = new TableBatchOperation(); @@ -377,7 +395,7 @@ public void testBatchSecondaryWriteShouldThrow() { @Category(SecondaryTests.class) public void testBatchSecondaryNoWrite() throws StorageException { // create and insert an entity - Class1 ref = generateRandomEntity("jxscl_odata"); + Class1 ref = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(ref)); // create a batch and add a query for this entity @@ -392,6 +410,7 @@ public void testBatchSecondaryNoWrite() throws StorageException { table.execute(batch, options, null); } + @SuppressWarnings("deprecation") @Test public void testBatchOver100Entities() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -407,7 +426,7 @@ private void testBatchOver100Entities(TableRequestOptions options) throws Storag TableBatchOperation batch = new TableBatchOperation(); try { for (int m = 0; m < 101; m++) { - batch.insert(generateRandomEntity("jxscl_odata")); + batch.insert(TableTestHelper.generateRandomEntity("jxscl_odata")); } table.execute(batch, options, null); @@ -422,6 +441,7 @@ private void testBatchOver100Entities(TableRequestOptions options) throws Storag } } + @SuppressWarnings("deprecation") @Test public void testBatchInsertEntityOver1MB() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -470,6 +490,7 @@ private void testBatchInsertEntityOver1MB(TableRequestOptions options) throws St } } + @SuppressWarnings("deprecation") @Test public void testBatchInsertEntityWithPropertyMoreThan255chars() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -519,8 +540,9 @@ private void testBatchInsertEntityWithPropertyMoreThan255chars(TableRequestOptio } } + @SuppressWarnings("deprecation") @Test - public void testBatchSizeOver4mb() throws StorageException { + public void testBatchSizeOver4mb() { TableRequestOptions options = new TableRequestOptions(); options.setTablePayloadFormat(TablePayloadFormat.AtomPub); @@ -530,7 +552,7 @@ public void testBatchSizeOver4mb() throws StorageException { testBatchSizeOver4mb(options); } - private void testBatchSizeOver4mb(TableRequestOptions options) throws StorageException { + private void testBatchSizeOver4mb(TableRequestOptions options) { TableBatchOperation batch = new TableBatchOperation(); byte[] datArr = new byte[1024 * 128]; Random rand = new Random(); @@ -561,6 +583,7 @@ private void testBatchSizeOver4mb(TableRequestOptions options) throws StorageExc } } + @SuppressWarnings("deprecation") @Test public void testBatchDeleteFail() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -576,10 +599,10 @@ private void testBatchDeleteFail(TableRequestOptions options) throws StorageExce TableBatchOperation batch = new TableBatchOperation(); // Insert entity to delete - Class1 baseEntity = generateRandomEntity("jxscl_odata"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(baseEntity), options, null); - Class1 updatedEntity = generateRandomEntity("jxscl_odata"); + Class1 updatedEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); updatedEntity.setPartitionKey(baseEntity.getPartitionKey()); updatedEntity.setRowKey(baseEntity.getRowKey()); updatedEntity.setEtag(baseEntity.getEtag()); @@ -600,6 +623,7 @@ private void testBatchDeleteFail(TableRequestOptions options) throws StorageExce } } + @SuppressWarnings("deprecation") @Test public void testBatchInsertFail() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -613,7 +637,7 @@ public void testBatchInsertFail() throws StorageException { private void testBatchInsertFail(TableRequestOptions options) throws StorageException { // insert entity - Class1 ref = generateRandomEntity("jxscl_odata"); + Class1 ref = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(ref), options, null); try { TableBatchOperation batch = new TableBatchOperation(); @@ -629,6 +653,7 @@ private void testBatchInsertFail(TableRequestOptions options) throws StorageExce } } + @SuppressWarnings("deprecation") @Test public void testBatchReplaceFail() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -644,10 +669,10 @@ private void testBatchReplaceFail(TableRequestOptions options) throws StorageExc TableBatchOperation batch = new TableBatchOperation(); // Insert entity to merge - Class1 baseEntity = generateRandomEntity("jxscl_odata"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(baseEntity), options, null); - Class1 updatedEntity = generateRandomEntity("jxscl_odata"); + Class1 updatedEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); updatedEntity.setPartitionKey(baseEntity.getPartitionKey()); updatedEntity.setRowKey(baseEntity.getRowKey()); updatedEntity.setEtag(baseEntity.getEtag()); @@ -668,6 +693,7 @@ private void testBatchReplaceFail(TableRequestOptions options) throws StorageExc } } + @SuppressWarnings("deprecation") @Test public void testBatchMergeFail() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -684,10 +710,10 @@ private void testBatchMergeFail(TableRequestOptions options) throws StorageExcep addInsertBatch(batch); // Insert entity to merge - Class1 baseEntity = generateRandomEntity("jxscl_odata"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(baseEntity), options, null); - Class1 updatedEntity = generateRandomEntity("jxscl_odata"); + Class1 updatedEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); updatedEntity.setPartitionKey(baseEntity.getPartitionKey()); updatedEntity.setRowKey(baseEntity.getRowKey()); updatedEntity.setEtag(baseEntity.getEtag()); @@ -710,6 +736,7 @@ private void testBatchMergeFail(TableRequestOptions options) throws StorageExcep } } + @SuppressWarnings("deprecation") @Test public void testBatchEmptyQuery() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -723,7 +750,7 @@ public void testBatchEmptyQuery() throws StorageException { private void testBatchEmptyQuery(TableRequestOptions options) throws StorageException { // insert entity - Class1 ref = generateRandomEntity("jxscl_odata"); + Class1 ref = TableTestHelper.generateRandomEntity("jxscl_odata"); TableBatchOperation batch = new TableBatchOperation(); batch.retrieve(ref.getPartitionKey(), ref.getRowKey(), ref.getClass()); @@ -735,6 +762,7 @@ private void testBatchEmptyQuery(TableRequestOptions options) throws StorageExce assertEquals(results.get(0).getHttpStatusCode(), HttpURLConnection.HTTP_NOT_FOUND); } + @SuppressWarnings("deprecation") @Test public void testBatchWithAllOperations() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -759,35 +787,35 @@ private void testBatchWithAllOperations(TableRequestOptions options) throws Stor { // insert entity to delete - Class1 delRef = generateRandomEntity("jxscl_odata"); + Class1 delRef = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(delRef), options, null); batch.delete(delRef); } { // Insert entity to replace - Class1 baseEntity = generateRandomEntity("jxscl_odata"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(baseEntity), options, null); addReplaceToBatch(baseEntity, batch); } { // Insert entity to insert or replace - Class1 baseEntity = generateRandomEntity("jxscl_odata"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(baseEntity), options, null); addInsertOrReplaceToBatch(baseEntity, batch); } { // Insert entity to merge - Class1 baseEntity = generateRandomEntity("jxscl_odata"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(baseEntity), options, null); addMergeToBatch(baseEntity, batch); } { // Insert entity to merge, no pre-existing entity - Class1 baseEntity = generateRandomEntity("jxscl_odata"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(baseEntity), options, null); addInsertOrMergeToBatch(baseEntity, batch); } @@ -817,6 +845,7 @@ private void testBatchWithAllOperations(TableRequestOptions options) throws Stor } + @SuppressWarnings("deprecation") @Test public void testBatchDelete() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -835,7 +864,7 @@ public void testBatchDelete() throws StorageException { } private void testBatchDelete(TableRequestOptions options) throws StorageException { - Class1 ref = generateRandomEntity("jxscl_odata"); + Class1 ref = TableTestHelper.generateRandomEntity("jxscl_odata"); // insert entity table.execute(TableOperation.insert(ref), options, null); @@ -857,6 +886,7 @@ private void testBatchDelete(TableRequestOptions options) throws StorageExceptio } } + @SuppressWarnings("deprecation") @Test public void testBatchRetrieve() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -880,7 +910,7 @@ public void testBatchRetrieve() throws StorageException { private void testBatchRetrieve(TableRequestOptions options) throws StorageException { // insert entity - Class1 ref = generateRandomEntity("jxscl_odata"); + Class1 ref = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(ref), options, null); TableBatchOperation batch = new TableBatchOperation(); @@ -900,6 +930,7 @@ private void testBatchRetrieve(TableRequestOptions options) throws StorageExcept table.execute(TableOperation.delete(ref), options, null); } + @SuppressWarnings("deprecation") @Test public void tableBatchRetrieveWithEntityResolver() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -923,7 +954,7 @@ public void tableBatchRetrieveWithEntityResolver() throws StorageException { private void tableBatchRetrieveWithEntityResolver(TableRequestOptions options) throws StorageException { // insert entity - Class1 randEnt = generateRandomEntity("jxscl_odata"); + Class1 randEnt = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(randEnt), options, null); TableBatchOperation batch = new TableBatchOperation(); @@ -953,6 +984,7 @@ public Class1 resolve(String partitionKey, String rowKey, Date timeStamp, assertTrue(Arrays.equals(ent.getD(), randEnt.getD())); } + @SuppressWarnings("deprecation") @Test public void testBatchInsert() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -979,7 +1011,7 @@ private void testBatchInsert(TableRequestOptions options) throws StorageExceptio addInsertBatch(batch, false); // set echo content to false // insert entity - Class1 ref = generateRandomEntity("jxscl_odata"); + Class1 ref = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(ref), options, null); batch.delete(ref); @@ -1001,6 +1033,7 @@ private void testBatchInsert(TableRequestOptions options) throws StorageExceptio assertEquals(iter.next().getHttpStatusCode(), HttpURLConnection.HTTP_NO_CONTENT); } + @SuppressWarnings("deprecation") @Test public void testBatchMerge() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -1023,12 +1056,12 @@ private void testBatchMerge(TableRequestOptions options) throws StorageException addInsertBatch(batch); // insert entity to delete - Class1 delRef = generateRandomEntity("jxscl_odata"); + Class1 delRef = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(delRef)); batch.delete(delRef); // Insert entity to merge - Class1 baseEntity = generateRandomEntity("jxscl_odata"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(baseEntity), options, null); addMergeToBatch(baseEntity, batch); @@ -1047,6 +1080,7 @@ private void testBatchMerge(TableRequestOptions options) throws StorageException assertEquals(iter.next().getHttpStatusCode(), HttpURLConnection.HTTP_NO_CONTENT); } + @SuppressWarnings("deprecation") @Test public void testBatchReplace() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -1069,12 +1103,12 @@ private void testBatchReplace(TableRequestOptions options) throws StorageExcepti addInsertBatch(batch); // insert entity to delete - Class1 delRef = generateRandomEntity("jxscl_odata"); + Class1 delRef = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(delRef), options, null); batch.delete(delRef); // Insert entity to replace - Class1 baseEntity = generateRandomEntity("jxscl_odata"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(baseEntity), options, null); addReplaceToBatch(baseEntity, batch); @@ -1093,6 +1127,7 @@ private void testBatchReplace(TableRequestOptions options) throws StorageExcepti assertEquals(iter.next().getHttpStatusCode(), HttpURLConnection.HTTP_NO_CONTENT); } + @SuppressWarnings("deprecation") @Test public void testBatchInsertOrMerge() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -1115,12 +1150,12 @@ private void testBatchInsertOrMerge(TableRequestOptions options) throws StorageE addInsertBatch(batch); // insert entity to delete - Class1 delRef = generateRandomEntity("jxscl_odata"); + Class1 delRef = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(delRef), options, null); batch.delete(delRef); // Insert entity to merge - Class1 baseEntity = generateRandomEntity("jxscl_odata"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(baseEntity), options, null); addInsertOrMergeToBatch(baseEntity, batch); @@ -1139,6 +1174,7 @@ private void testBatchInsertOrMerge(TableRequestOptions options) throws StorageE assertEquals(iter.next().getHttpStatusCode(), HttpURLConnection.HTTP_NO_CONTENT); } + @SuppressWarnings("deprecation") @Test public void testBatchInsertOrReplace() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -1161,12 +1197,12 @@ private void testBatchInsertOrReplace(TableRequestOptions options) throws Storag addInsertBatch(batch); // insert entity to delete - Class1 delRef = generateRandomEntity("jxscl_odata"); + Class1 delRef = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(delRef), options, null); batch.delete(delRef); // Insert entity to replace - Class1 baseEntity = generateRandomEntity("jxscl_odata"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(baseEntity), options, null); addInsertOrReplaceToBatch(baseEntity, batch); @@ -1185,6 +1221,7 @@ private void testBatchInsertOrReplace(TableRequestOptions options) throws Storag assertEquals(iter.next().getHttpStatusCode(), HttpURLConnection.HTTP_NO_CONTENT); } + @SuppressWarnings("deprecation") @Test public void testInsertBatch1() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -1202,6 +1239,7 @@ public void testInsertBatch1() throws StorageException { insertAndDeleteBatchWithX(1, options); } + @SuppressWarnings("deprecation") @Test public void testInsertBatch10() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -1219,6 +1257,7 @@ public void testInsertBatch10() throws StorageException { insertAndDeleteBatchWithX(10, options); } + @SuppressWarnings("deprecation") @Test public void testInsertBatch100() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -1236,6 +1275,7 @@ public void testInsertBatch100() throws StorageException { insertAndDeleteBatchWithX(100, options); } + @SuppressWarnings("deprecation") @Test public void testUpsertBatch1() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -1253,6 +1293,7 @@ public void testUpsertBatch1() throws StorageException { upsertAndDeleteBatchWithX(1, options); } + @SuppressWarnings("deprecation") @Test public void testUpsertBatch10() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -1270,6 +1311,7 @@ public void testUpsertBatch10() throws StorageException { upsertAndDeleteBatchWithX(10, options); } + @SuppressWarnings("deprecation") @Test public void testUpsertBatch100() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -1288,13 +1330,13 @@ public void testUpsertBatch100() throws StorageException { } private Class1 addInsertBatch(TableBatchOperation batch) { - Class1 ref = generateRandomEntity("jxscl_odata"); + Class1 ref = TableTestHelper.generateRandomEntity("jxscl_odata"); batch.insert(ref); return ref; } private Class1 addInsertBatch(TableBatchOperation batch, boolean echoContent) { - Class1 ref = generateRandomEntity("jxscl_odata"); + Class1 ref = TableTestHelper.generateRandomEntity("jxscl_odata"); batch.insert(ref, echoContent); return ref; } @@ -1345,7 +1387,7 @@ private void insertAndDeleteBatchWithX(int x, TableRequestOptions options) throw private void upsertAndDeleteBatchWithX(int x, TableRequestOptions options) throws StorageException { TableBatchOperation batch = new TableBatchOperation(); for (int m = 0; m < x; m++) { - addInsertOrMergeToBatch(generateRandomEntity("jxscl_odata"), batch); + addInsertOrMergeToBatch(TableTestHelper.generateRandomEntity("jxscl_odata"), batch); } TableBatchOperation delBatch = new TableBatchOperation(); @@ -1365,52 +1407,52 @@ private ArrayList allOpsList() throws StorageException { ArrayList ops = new ArrayList(); // insert - ops.add(TableOperation.insert(generateRandomEntity("jxscl_odata"))); + ops.add(TableOperation.insert(TableTestHelper.generateRandomEntity("jxscl_odata"))); { // Insert entity to delete - Class1 delRef = generateRandomEntity("jxscl_odata"); + Class1 delRef = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(delRef)); ops.add(TableOperation.delete(delRef)); } { // Insert entity to replace - Class1 baseEntity = generateRandomEntity("jxscl_odata"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(baseEntity)); ops.add(TableOperation.replace(createEntityToReplaceOrMerge(baseEntity))); } { // Insert entity to insert or replace - Class1 baseEntity = generateRandomEntity("jxscl_odata"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(baseEntity)); ops.add(TableOperation.insertOrReplace(createEntityToReplaceOrMerge(baseEntity))); } { // Insert or replace, no pre-existing entity - Class1 baseEntity = generateRandomEntity("jxscl_odata"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); ops.add(TableOperation.insertOrReplace(createEntityToReplaceOrMerge(baseEntity))); } { // Insert entity to merge - Class1 baseEntity = generateRandomEntity("jxscl_odata"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(baseEntity)); ops.add(TableOperation.merge(createEntityToReplaceOrMerge(baseEntity))); } { // Insert entity to insert or merge - Class1 baseEntity = generateRandomEntity("jxscl_odata"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); table.execute(TableOperation.insert(baseEntity)); ops.add(TableOperation.insertOrMerge(baseEntity)); } { // Insert or merge, no pre-existing entity - Class1 baseEntity = generateRandomEntity("jxscl_odata"); + Class1 baseEntity = TableTestHelper.generateRandomEntity("jxscl_odata"); ops.add(TableOperation.insertOrMerge(baseEntity)); } diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableClientTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableClientTests.java similarity index 76% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableClientTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableClientTests.java index 7462cd8d24fb9..f932fc9f6247a 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableClientTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableClientTests.java @@ -12,11 +12,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import static org.junit.Assert.*; -import java.io.IOException; import java.net.HttpURLConnection; import java.net.URISyntaxException; import java.security.InvalidKeyException; @@ -32,32 +31,36 @@ import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.AuthenticationScheme; -import com.microsoft.windowsazure.storage.LocationMode; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.RequestResult; -import com.microsoft.windowsazure.storage.ResultSegment; -import com.microsoft.windowsazure.storage.RetryContext; -import com.microsoft.windowsazure.storage.RetryExponentialRetry; -import com.microsoft.windowsazure.storage.RetryInfo; -import com.microsoft.windowsazure.storage.RetryLinearRetry; -import com.microsoft.windowsazure.storage.RetryPolicy; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.StorageLocation; -import com.microsoft.windowsazure.storage.TestHelper; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; -import com.microsoft.windowsazure.storage.TestRunners.SlowTests; +import com.microsoft.azure.storage.AuthenticationScheme; +import com.microsoft.azure.storage.LocationMode; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.RequestResult; +import com.microsoft.azure.storage.ResultSegment; +import com.microsoft.azure.storage.RetryContext; +import com.microsoft.azure.storage.RetryExponentialRetry; +import com.microsoft.azure.storage.RetryInfo; +import com.microsoft.azure.storage.RetryLinearRetry; +import com.microsoft.azure.storage.RetryPolicy; +import com.microsoft.azure.storage.StorageCredentialsSharedAccessSignature; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.StorageLocation; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.TestRunners.SlowTests; +import com.microsoft.azure.storage.core.PathUtility; +import com.microsoft.azure.storage.table.TableTestHelper.Class1; +import com.microsoft.azure.storage.table.TableTestHelper.Class2; /** * Table Client Tests */ -public class TableClientTests extends TableTestBase { +public class TableClientTests { + @SuppressWarnings("deprecation") @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) @Test - public void testListTablesSegmented() throws IOException, URISyntaxException, StorageException { + public void testListTablesSegmented() throws URISyntaxException, StorageException { TableRequestOptions options = new TableRequestOptions(); options.setTablePayloadFormat(TablePayloadFormat.AtomPub); @@ -73,9 +76,9 @@ public void testListTablesSegmented() throws IOException, URISyntaxException, St testListTablesSegmented(options); } - private void testListTablesSegmented(TableRequestOptions options) throws IOException, URISyntaxException, - StorageException { - String tableBaseName = generateRandomTableName(); + private void testListTablesSegmented(TableRequestOptions options) throws URISyntaxException, StorageException { + final CloudTableClient tClient = TableTestHelper.createCloudTableClient(); + String tableBaseName = TableTestHelper.generateRandomTableName(); ArrayList tables = new ArrayList(); for (int m = 0; m < 20; m++) { @@ -118,9 +121,10 @@ private void testListTablesSegmented(TableRequestOptions options) throws IOExcep } } + @SuppressWarnings("deprecation") @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) @Test - public void testListTablesSegmentedNoPrefix() throws IOException, URISyntaxException, StorageException { + public void testListTablesSegmentedNoPrefix() throws URISyntaxException, StorageException { TableRequestOptions options = new TableRequestOptions(); options.setTablePayloadFormat(TablePayloadFormat.AtomPub); @@ -130,9 +134,11 @@ public void testListTablesSegmentedNoPrefix() throws IOException, URISyntaxExcep testListTablesSegmentedNoPrefix(options); } - private void testListTablesSegmentedNoPrefix(TableRequestOptions options) throws IOException, URISyntaxException, + private void testListTablesSegmentedNoPrefix(TableRequestOptions options) throws URISyntaxException, StorageException { - String tableBaseName = generateRandomTableName(); + final CloudTableClient tClient = TableTestHelper.createCloudTableClient(); + String tableBaseName = TableTestHelper.generateRandomTableName(); + ArrayList tables = new ArrayList(); for (int m = 0; m < 20; m++) { String name = String.format("%s%s", tableBaseName, new DecimalFormat("#0000").format(m)); @@ -181,9 +187,10 @@ private void testListTablesSegmentedNoPrefix(TableRequestOptions options) throws } } + @SuppressWarnings("deprecation") @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) @Test - public void testListTablesWithIterator() throws IOException, URISyntaxException, StorageException { + public void testListTablesWithIterator() throws URISyntaxException, StorageException { TableRequestOptions options = new TableRequestOptions(); options.setTablePayloadFormat(TablePayloadFormat.AtomPub); @@ -193,9 +200,10 @@ public void testListTablesWithIterator() throws IOException, URISyntaxException, testListTablesWithIterator(options); } - private void testListTablesWithIterator(TableRequestOptions options) throws IOException, URISyntaxException, - StorageException { - String tableBaseName = generateRandomTableName(); + private void testListTablesWithIterator(TableRequestOptions options) throws URISyntaxException, StorageException { + final CloudTableClient tClient = TableTestHelper.createCloudTableClient(); + String tableBaseName = TableTestHelper.generateRandomTableName(); + ArrayList tables = new ArrayList(); for (int m = 0; m < 20; m++) { String name = String.format("%s%s", tableBaseName, new DecimalFormat("#0000").format(m)); @@ -253,11 +261,10 @@ private void testListTablesWithIterator(TableRequestOptions options) throws IOEx @Test public void testTableSASFromIdentifier() throws StorageException, URISyntaxException, InvalidKeyException, InterruptedException { - String name = generateRandomTableName(); - CloudTable table = tClient.getTableReference(name); - table.create(); - + CloudTable table = TableTestHelper.getRandomTableReference(); try { + table.create(); + TablePermissions expectedPermissions = new TablePermissions(); String identifier = UUID.randomUUID().toString(); // Add a policy, check setting and getting. @@ -279,7 +286,7 @@ public void testTableSASFromIdentifier() throws StorageException, URISyntaxExcep TableBatchOperation batch = new TableBatchOperation(); for (int j = 0; j < 100; j++) { - Class1 ent = generateRandomEntity("javatables_batch_" + Integer.toString(i)); + Class1 ent = TableTestHelper.generateRandomEntity("javatables_batch_" + Integer.toString(i)); ent.setRowKey(String.format("%06d", j)); batch.insert(ent); } @@ -287,12 +294,11 @@ public void testTableSASFromIdentifier() throws StorageException, URISyntaxExcep table.execute(batch); } - CloudTableClient tableClientFromIdentifierSAS = TableTestBase.getTableForSas(table, null, identifier, null, - null, null, null); - CloudTable tableFromIdentifierSAS = tableClientFromIdentifierSAS.getTableReference(table.getName()); + String sasString = table.generateSharedAccessSignature(null, identifier, null, null, null, null); + CloudTable tableFromIdentifierSAS = new CloudTable(PathUtility.addToQuery(table.getUri(), sasString)); { - Class1 randEnt = TableTestBase.generateRandomEntity(null); + Class1 randEnt = TableTestHelper.generateRandomEntity(null); TableQuery query = TableQuery.from(Class1.class).where( String.format("(PartitionKey eq '%s') and (RowKey ge '%s')", "javatables_batch_1", "000050")); @@ -377,15 +383,11 @@ public void testTableSASFromIdentifier() throws StorageException, URISyntaxExcep @Category({ SlowTests.class, DevFabricTests.class, DevStoreTests.class, CloudTests.class }) @Test - public void testTableSASFromPermission() throws StorageException, URISyntaxException, InvalidKeyException, - InterruptedException { - String name = generateRandomTableName(); - CloudTable table = tClient.getTableReference(name); - table.create(); - + public void testTableSASFromPermission() throws StorageException, URISyntaxException, InvalidKeyException { + CloudTable table = TableTestHelper.getRandomTableReference(); try { - TablePermissions expectedPermissions = new TablePermissions(); - String identifier = UUID.randomUUID().toString(); + table.create(); + // Add a policy, check setting and getting. SharedAccessTablePolicy policy1 = new SharedAccessTablePolicy(); Calendar now = GregorianCalendar.getInstance(); @@ -396,17 +398,13 @@ public void testTableSASFromPermission() throws StorageException, URISyntaxExcep policy1.setPermissions(EnumSet.of(SharedAccessTablePermissions.ADD, SharedAccessTablePermissions.QUERY, SharedAccessTablePermissions.UPDATE, SharedAccessTablePermissions.DELETE)); - expectedPermissions.getSharedAccessPolicies().put(identifier, policy1); - - table.uploadPermissions(expectedPermissions); - Thread.sleep(30000); // Insert 500 entities in Batches to query for (int i = 0; i < 5; i++) { TableBatchOperation batch = new TableBatchOperation(); for (int j = 0; j < 100; j++) { - Class1 ent = generateRandomEntity("javatables_batch_" + Integer.toString(i)); + Class1 ent = TableTestHelper.generateRandomEntity("javatables_batch_" + Integer.toString(i)); ent.setRowKey(String.format("%06d", j)); batch.insert(ent); } @@ -414,26 +412,26 @@ public void testTableSASFromPermission() throws StorageException, URISyntaxExcep table.execute(batch); } - CloudTableClient tableClientFromPermission = TableTestBase.getTableForSas(table, policy1, null, - "javatables_batch_0", "0", "javatables_batch_9", "9"); - CloudTable tableFromPermission = tableClientFromPermission.getTableReference(table.getName()); + String sasString = table.generateSharedAccessSignature(policy1, null, "javatables_batch_0", "0", + "javatables_batch_9", "9"); + CloudTable tableFromPermission = new CloudTable(PathUtility.addToQuery(table.getUri(), sasString)); - CloudTableClient tableClientFromPermissionJustPks = TableTestBase.getTableForSas(table, policy1, null, - "javatables_batch_0", null, "javatables_batch_9", null); - CloudTable tableFromPermissionJustPks = tableClientFromPermissionJustPks.getTableReference(table.getName()); + sasString = table.generateSharedAccessSignature(policy1, null, "javatables_batch_0", null, + "javatables_batch_9", null); + CloudTable tableFromPermissionJustPks = new CloudTable(PathUtility.addToQuery(table.getUri(), sasString)); { TableBatchOperation batchFromSAS = new TableBatchOperation(); for (int j = 1000; j < 1010; j++) { - Class1 ent = generateRandomEntity("javatables_batch_" + Integer.toString(0)); + Class1 ent = TableTestHelper.generateRandomEntity("javatables_batch_" + Integer.toString(0)); ent.setRowKey(String.format("%06d", j)); batchFromSAS.insert(ent); } tableFromPermission.execute(batchFromSAS); - Class1 randEnt = TableTestBase.generateRandomEntity(null); + Class1 randEnt = TableTestHelper.generateRandomEntity(null); TableQuery query = TableQuery.from(Class1.class).where( String.format("(PartitionKey eq '%s') and (RowKey ge '%s')", "javatables_batch_1", "000050")); @@ -530,12 +528,69 @@ public void testTableSASFromPermission() throws StorageException, URISyntaxExcep } } + @Category({ SlowTests.class, DevFabricTests.class, DevStoreTests.class, CloudTests.class }) + @Test + public void testTableSASPkRk() throws StorageException, URISyntaxException, InvalidKeyException { + CloudTable table = TableTestHelper.getRandomTableReference(); + try { + table.create(); + + // Add a policy, check setting and getting. + SharedAccessTablePolicy policy1 = new SharedAccessTablePolicy(); + Calendar now = GregorianCalendar.getInstance(); + now.add(Calendar.MINUTE, -10); + policy1.setSharedAccessStartTime(now.getTime()); + now.add(Calendar.MINUTE, 30); + policy1.setSharedAccessExpiryTime(now.getTime()); + + policy1.setPermissions(EnumSet.of(SharedAccessTablePermissions.ADD, SharedAccessTablePermissions.QUERY, + SharedAccessTablePermissions.UPDATE, SharedAccessTablePermissions.DELETE)); + + String sasString = table.generateSharedAccessSignature(policy1, null, "javatables_batch_0", "00", + "javatables_batch_1", "04"); + StorageCredentialsSharedAccessSignature sasCreds = new StorageCredentialsSharedAccessSignature(sasString); + CloudTable directTable = new CloudTable(PathUtility.addToQuery(table.getUri(), sasString)); + CloudTable transformedTable = new CloudTable(sasCreds.transformUri(table.getUri())); + + Class1 ent = new Class1("javatables_batch_0", "00"); + directTable.execute(TableOperation.insert(ent)); + + ent = new Class1("javatables_batch_0", "01"); + transformedTable.execute(TableOperation.insert(ent)); + + ent = new Class1("javatables_batch_2", "01"); + try { + directTable.execute(TableOperation.insert(ent)); + transformedTable.execute(TableOperation.insert(ent)); + } + catch (StorageException e) { + assertEquals(404, e.getHttpStatusCode()); + assertEquals("ResourceNotFound", e.getExtendedErrorInformation().getErrorCode()); + } + + ent = new Class1("javatables_batch_1", "05"); + try { + directTable.execute(TableOperation.insert(ent)); + transformedTable.execute(TableOperation.insert(ent)); + } + catch (StorageException e) { + assertEquals(404, e.getHttpStatusCode()); + assertEquals("ResourceNotFound", e.getExtendedErrorInformation().getErrorCode()); + } + + } + finally { + // cleanup + table.deleteIfExists(); + } + } + @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) @Test public void tableCreateAndAttemptCreateOnceExistsSharedKeyLite() throws StorageException, URISyntaxException { + final CloudTableClient tClient = TableTestHelper.createCloudTableClient(); tClient.setAuthenticationScheme(AuthenticationScheme.SHAREDKEYLITE); - String tableName = generateRandomTableName(); - CloudTable table = tClient.getTableReference(tableName); + CloudTable table = tClient.getTableReference(TableTestHelper.generateRandomTableName()); try { table.create(); assertTrue(table.exists()); @@ -590,8 +645,8 @@ private void testBackoffTimeOverflow(RetryPolicy retryPolicy, int maxAttempts) { @Category({ CloudTests.class }) @Test public void testGetServiceStats() throws StorageException { - CloudTableClient tClient = createCloudTableClient(); - tClient.setLocationMode(LocationMode.SECONDARY_ONLY); - TestHelper.verifyServiceStats(tClient.getServiceStats()); + CloudTableClient tClient = TableTestHelper.createCloudTableClient(); + tClient.getDefaultRequestOptions().setLocationMode(LocationMode.SECONDARY_ONLY); + TableTestHelper.verifyServiceStats(tClient.getServiceStats()); } } diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableEscapingTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableEscapingTests.java similarity index 91% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableEscapingTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableEscapingTests.java index 7c4f853157ba1..597d0a2273574 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableEscapingTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableEscapingTests.java @@ -12,25 +12,42 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import static org.junit.Assert.*; +import java.net.URISyntaxException; import java.util.UUID; +import org.junit.After; +import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.table.TableTestHelper.Class1; /** * Table Escaping Tests */ @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) -public class TableEscapingTests extends TableTestBase { +public class TableEscapingTests { + + private CloudTable table; + + @Before + public void tableTestMethodSetUp() throws URISyntaxException, StorageException { + table = TableTestHelper.getRandomTableReference(); + table.createIfNotExists(); + } + + @After + public void tableTestMethodTearDown() throws StorageException { + table.deleteIfExists(); + } @Test public void testEmptyString() throws StorageException { @@ -138,6 +155,7 @@ private void doEscapeTest(String data, boolean useBatch) throws StorageException doEscapeTest(data, useBatch, false); } + @SuppressWarnings("deprecation") private void doEscapeTest(String data, boolean useBatch, boolean includeInKey) throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -255,6 +273,7 @@ private void doEscapeTestHelper(String data, boolean useBatch, boolean includeIn } } + @SuppressWarnings("deprecation") private void doQueryEscapeTest(String data) throws StorageException { TableRequestOptions options = new TableRequestOptions(); diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableODataTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableODataTests.java similarity index 80% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableODataTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableODataTests.java index d744eda6c2f4d..9cb81348371e1 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableODataTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableODataTests.java @@ -12,10 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import static org.junit.Assert.*; +import java.net.URISyntaxException; import java.util.UUID; import org.junit.After; @@ -23,21 +24,28 @@ import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; -import com.microsoft.windowsazure.storage.table.TableRequestOptions.PropertyResolver; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.table.TableRequestOptions.PropertyResolver; +import com.microsoft.azure.storage.table.TableTestHelper.Class1; @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) -public class TableODataTests extends TableTestBase { +public class TableODataTests { TableRequestOptions options; DynamicTableEntity ent; + private CloudTable table; + @Before - public void tableODataTestsBeforeMethod() throws StorageException { - this.options = TableRequestOptions.applyDefaults(this.options, TableTestBase.tClient); + public void tableODataTestsBeforeMethod() throws StorageException, URISyntaxException { + table = TableTestHelper.getRandomTableReference(); + table.createIfNotExists(); + + final CloudTableClient tClient = TableTestHelper.createCloudTableClient(); + this.options = TableRequestOptions.applyDefaults(this.options, tClient); this.options.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata); // Insert Entity @@ -55,10 +63,11 @@ public void tableODataTestsBeforeMethod() throws StorageException { @After public void tableODataTestsAfterMethod() throws StorageException { table.execute(TableOperation.delete(ent), options, null); + table.deleteIfExists(); } @Test - public void testTableOperationRetrieveJsonNoMetadataFail() throws StorageException { + public void testTableOperationRetrieveJsonNoMetadataFail() { // set custom property resolver this.options.setPropertyResolver(new CustomPropertyResolver()); @@ -73,7 +82,7 @@ public void testTableOperationRetrieveJsonNoMetadataFail() throws StorageExcepti } @Test - public void testTableOperationRetrieveJsonNoMetadataResolverFail() throws StorageException { + public void testTableOperationRetrieveJsonNoMetadataResolverFail() { // set custom property resolver which throws this.options.setPropertyResolver(new ThrowingPropertyResolver()); diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableOperationTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableOperationTests.java similarity index 95% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableOperationTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableOperationTests.java index ef239ee2edda7..902db20a572e1 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableOperationTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableOperationTests.java @@ -12,31 +12,52 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import static org.junit.Assert.*; import java.net.HttpURLConnection; +import java.net.URISyntaxException; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.UUID; +import org.junit.After; +import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.table.TableRequestOptions.PropertyResolver; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.table.TableRequestOptions.PropertyResolver; +import com.microsoft.azure.storage.table.TableTestHelper.Class1; +import com.microsoft.azure.storage.table.TableTestHelper.Class2; +import com.microsoft.azure.storage.table.TableTestHelper.EmptyClass; +import com.microsoft.azure.storage.table.TableTestHelper.EmptyClassDynamic; +import com.microsoft.azure.storage.table.TableTestHelper.class1class2PropertyResolver; /** * Table Operation Tests */ @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) -public class TableOperationTests extends TableTestBase { +public class TableOperationTests { + + private CloudTable table; + + @Before + public void tableTestMethodSetUp() throws URISyntaxException, StorageException { + table = TableTestHelper.getRandomTableReference(); + table.createIfNotExists(); + } + + @After + public void tableTestMethodTearDown() throws StorageException { + table.deleteIfExists(); + } @Test public void testPropertyCacheDisable() { @@ -57,7 +78,7 @@ public void testPropertyCacheDisable() { } @Test - public void testRetrieveWithNullResolver() throws StorageException { + public void testRetrieveWithNullResolver() { try { TableOperation.retrieve("foo", "blah", (EntityResolver) null); } @@ -67,8 +88,9 @@ public void testRetrieveWithNullResolver() throws StorageException { } } + @SuppressWarnings("deprecation") @Test - public void testInsertEntityWithoutPartitionKeyRowKey() throws StorageException { + public void testInsertEntityWithoutPartitionKeyRowKey() { TableRequestOptions options = new TableRequestOptions(); options.setTablePayloadFormat(TablePayloadFormat.AtomPub); @@ -78,7 +100,7 @@ public void testInsertEntityWithoutPartitionKeyRowKey() throws StorageException testInsertEntityWithoutPartitionKeyRowKey(options); } - private void testInsertEntityWithoutPartitionKeyRowKey(TableRequestOptions options) throws StorageException { + private void testInsertEntityWithoutPartitionKeyRowKey(TableRequestOptions options) { EmptyClass ref = new EmptyClass(); ref.setPartitionKey("jxscl_odata"); @@ -107,6 +129,7 @@ private void testInsertEntityWithoutPartitionKeyRowKey(TableRequestOptions optio } } + @SuppressWarnings("deprecation") @Test public void testInsertEntityWithPropertyMoreThan255chars() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -142,6 +165,7 @@ private void testInsertEntityWithPropertyMoreThan255chars(TableRequestOptions op } } + @SuppressWarnings("deprecation") @Test public void testInsertEntityOver1MB() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -175,6 +199,7 @@ private void testInsertEntityOver1MB(TableRequestOptions options) throws Storage } } + @SuppressWarnings("deprecation") @Test public void testInsertEntityWithNumericProperty() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -186,6 +211,7 @@ public void testInsertEntityWithNumericProperty() throws StorageException { testInsertEntityWithNumericProperty(options); } + @SuppressWarnings("deprecation") private void testInsertEntityWithNumericProperty(TableRequestOptions options) throws StorageException { DynamicTableEntity ref = new DynamicTableEntity(); @@ -220,6 +246,7 @@ private void testInsertEntityWithNumericProperty(TableRequestOptions options) th } } + @SuppressWarnings("deprecation") @Test public void testDeleteFail() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -280,6 +307,7 @@ private void testDeleteFail(TableRequestOptions options) throws StorageException } } + @SuppressWarnings("deprecation") @Test public void testMergeFail() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -348,6 +376,7 @@ private void testMergeFail(TableRequestOptions options) throws StorageException } } + @SuppressWarnings("deprecation") @Test public void testInsertFail() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -383,6 +412,7 @@ private void testInsertFail(TableRequestOptions options) throws StorageException } } + @SuppressWarnings("deprecation") @Test public void testReplaceFail() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -454,6 +484,7 @@ private void testReplaceFail(TableRequestOptions options) throws StorageExceptio } } + @SuppressWarnings("deprecation") @Test public void testEmptyRetrieve() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -481,6 +512,7 @@ private void testEmptyRetrieve(TableRequestOptions options) throws StorageExcept assertEquals(res.getHttpStatusCode(), HttpURLConnection.HTTP_NOT_FOUND); } + @SuppressWarnings("deprecation") @Test public void testInsertEmptyEntity() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -508,6 +540,7 @@ private void testInsertEmptyEntity(TableRequestOptions options) throws StorageEx assertEquals(HttpURLConnection.HTTP_NO_CONTENT, res.getHttpStatusCode()); } + @SuppressWarnings("deprecation") @Test public void testDelete() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -545,6 +578,7 @@ private void testDelete(TableRequestOptions options) throws StorageException { assertTrue(res2.getResult() == null); } + @SuppressWarnings("deprecation") @Test public void testInsertOrMerge() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -630,6 +664,7 @@ private void testInsertOrMerge(TableRequestOptions options, boolean usePropertyR assertEquals(secondEntity.getO(), retrievedEntity.getProperties().get("O").getValueAsString()); } + @SuppressWarnings("deprecation") @Test public void testInsertOrReplace() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -701,6 +736,7 @@ private void testInsertOrReplace(TableRequestOptions options) throws StorageExce assertEquals(secondEntity.getO(), retrievedEntity.getProperties().get("O").getValueAsString()); } + @SuppressWarnings("deprecation") @Test public void testMerge() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -782,6 +818,7 @@ private void testMerge(TableRequestOptions options, boolean usePropertyResolver) assertEquals(secondEntity.getO(), mergedEntity.getProperties().get("O").getValueAsString()); } + @SuppressWarnings("deprecation") @Test public void testReplace() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -847,6 +884,7 @@ private void testReplace(TableRequestOptions options) throws StorageException { assertTrue(retrievedEntity.getProperties().get("D") == null); } + @SuppressWarnings("deprecation") @Test public void testInsert() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -886,6 +924,7 @@ private void testInsert(TableRequestOptions options) throws StorageException { assertEquals(HttpURLConnection.HTTP_NO_CONTENT, res.getHttpStatusCode()); } + @SuppressWarnings("deprecation") @Test public void testRetrieveWithoutEntityResolver() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -947,6 +986,7 @@ private void testRetrieveWithoutEntityResolver(TableRequestOptions options, bool } } + @SuppressWarnings("deprecation") @Test public void testRetrieveWithEntityResolver() throws StorageException { TableRequestOptions options = new TableRequestOptions(); @@ -1025,4 +1065,4 @@ public Class1 resolve(String partitionKey, String rowKey, Date timeStamp, TableServiceEntity.setReflectedEntityCacheDisabled(false); } } -} \ No newline at end of file +} diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableQueryTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableQueryTests.java similarity index 89% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableQueryTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableQueryTests.java index 139ba1c19aedf..d63beca3e954e 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableQueryTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableQueryTests.java @@ -12,51 +12,55 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import static org.junit.Assert.*; -import java.io.IOException; import java.net.HttpURLConnection; import java.net.URISyntaxException; -import java.security.InvalidKeyException; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.UUID; +import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.ResponseReceivedEvent; -import com.microsoft.windowsazure.storage.ResultSegment; -import com.microsoft.windowsazure.storage.StorageEvent; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.table.TableQuery.QueryComparisons; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.ResponseReceivedEvent; +import com.microsoft.azure.storage.ResultSegment; +import com.microsoft.azure.storage.StorageEvent; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.table.TableQuery.QueryComparisons; +import com.microsoft.azure.storage.table.TableTestHelper.Class1; +import com.microsoft.azure.storage.table.TableTestHelper.ComplexEntity; /** * Table Query Tests */ @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) -public class TableQueryTests extends TableTestBase { +public class TableQueryTests { + + private static CloudTable table; @BeforeClass - public static void setup() throws URISyntaxException, StorageException, InvalidKeyException { - TableTestBase.setup(); + public static void setup() throws URISyntaxException, StorageException { + table = TableTestHelper.getRandomTableReference(); + table.createIfNotExists(); // Insert 500 entities in Batches to query for (int i = 0; i < 5; i++) { TableBatchOperation batch = new TableBatchOperation(); for (int j = 0; j < 100; j++) { - Class1 ent = generateRandomEntity("javatables_batch_" + Integer.toString(i)); + Class1 ent = TableTestHelper.generateRandomEntity("javatables_batch_" + Integer.toString(i)); ent.setRowKey(String.format("%06d", j)); batch.insert(ent); } @@ -65,8 +69,13 @@ public static void setup() throws URISyntaxException, StorageException, InvalidK } } + @AfterClass + public static void teardown() throws StorageException { + table.deleteIfExists(); + } + @Test - public void testQueryWithNullClassType() throws StorageException { + public void testQueryWithNullClassType() { try { TableQuery.from(null); } @@ -76,7 +85,7 @@ public void testQueryWithNullClassType() throws StorageException { } @Test - public void testQueryWithInvalidTakeCount() throws StorageException { + public void testQueryWithInvalidTakeCount() { try { TableQuery.from(TableServiceEntity.class).take(0); } @@ -92,8 +101,9 @@ public void testQueryWithInvalidTakeCount() throws StorageException { } } + @SuppressWarnings("deprecation") @Test - public void testTableInvalidQuery() throws StorageException, InterruptedException, IOException, URISyntaxException { + public void testTableInvalidQuery() throws StorageException { TableRequestOptions options = new TableRequestOptions(); options.setTablePayloadFormat(TablePayloadFormat.AtomPub); @@ -103,8 +113,7 @@ public void testTableInvalidQuery() throws StorageException, InterruptedExceptio testTableInvalidQuery(options); } - private void testTableInvalidQuery(TableRequestOptions options) throws StorageException, IOException, - URISyntaxException { + private void testTableInvalidQuery(TableRequestOptions options) throws StorageException { TableQuery query = TableQuery.from(Class1.class).where( String.format("(PartitionKey ) and (RowKey ge '%s')", "000050")); @@ -120,6 +129,7 @@ private void testTableInvalidQuery(TableRequestOptions options) throws StorageEx } } + @SuppressWarnings("deprecation") @Test public void testQueryOnSupportedTypes() throws StorageException, InterruptedException { TableRequestOptions options = new TableRequestOptions(); @@ -277,7 +287,7 @@ private void testQueryOnSupportedTypes(TableRequestOptions options, boolean useP } private void executeQueryAndAssertResults(String filter, int expectedResults, TableRequestOptions options, - boolean usePropertyResolver) throws StorageException { + boolean usePropertyResolver) { // instantiate class to use property resolver ComplexEntity ent = new ComplexEntity(); if (usePropertyResolver) { @@ -294,8 +304,9 @@ private void executeQueryAndAssertResults(String filter, int expectedResults, Ta assertEquals(expectedResults, count); } + @SuppressWarnings("deprecation") @Test - public void testTableQueryIterateTwice() throws StorageException { + public void testTableQueryIterateTwice() { TableRequestOptions options = new TableRequestOptions(); options.setTablePayloadFormat(TablePayloadFormat.AtomPub); @@ -311,9 +322,9 @@ public void testTableQueryIterateTwice() throws StorageException { testTableQueryIterateTwice(options); } - private void testTableQueryIterateTwice(TableRequestOptions options) throws StorageException { + private void testTableQueryIterateTwice(TableRequestOptions options) { // Create entity to check against - Class1 randEnt = TableTestBase.generateRandomEntity(null); + Class1 randEnt = TableTestHelper.generateRandomEntity(null); final Iterable result = table.execute(TableQuery.from(DynamicTableEntity.class).take(50), options, null); @@ -357,8 +368,9 @@ private void testTableQueryIterateTwice(TableRequestOptions options) throws Stor } } + @SuppressWarnings("deprecation") @Test - public void testTableQueryWithDynamicEntity() throws StorageException { + public void testTableQueryWithDynamicEntity() { TableRequestOptions options = new TableRequestOptions(); options.setTablePayloadFormat(TablePayloadFormat.AtomPub); @@ -374,9 +386,9 @@ public void testTableQueryWithDynamicEntity() throws StorageException { testTableQueryWithDynamicEntity(options); } - private void testTableQueryWithDynamicEntity(TableRequestOptions options) throws StorageException { + private void testTableQueryWithDynamicEntity(TableRequestOptions options) { // Create entity to check against - Class1 randEnt = TableTestBase.generateRandomEntity(null); + Class1 randEnt = TableTestHelper.generateRandomEntity(null); final Iterable result = table.execute(TableQuery.from(DynamicTableEntity.class), options, null); @@ -391,8 +403,9 @@ private void testTableQueryWithDynamicEntity(TableRequestOptions options) throws } } + @SuppressWarnings("deprecation") @Test - public void testTableQueryWithProjection() throws StorageException { + public void testTableQueryWithProjection() { TableRequestOptions options = new TableRequestOptions(); options.setTablePayloadFormat(TablePayloadFormat.AtomPub); @@ -411,10 +424,9 @@ public void testTableQueryWithProjection() throws StorageException { testTableQueryWithProjection(options, true); } - private void testTableQueryWithProjection(TableRequestOptions options, boolean usePropertyResolver) - throws StorageException { + private void testTableQueryWithProjection(TableRequestOptions options, boolean usePropertyResolver) { // Create entity to check against - Class1 randEnt = TableTestBase.generateRandomEntity(null); + Class1 randEnt = TableTestHelper.generateRandomEntity(null); if (usePropertyResolver) { options.setPropertyResolver(randEnt); @@ -438,8 +450,9 @@ private void testTableQueryWithProjection(TableRequestOptions options, boolean u } } + @SuppressWarnings("deprecation") @Test - public void testSelectOnlySendsReservedColumnsOnce() throws StorageException { + public void testSelectOnlySendsReservedColumnsOnce() { TableRequestOptions options = new TableRequestOptions(); options.setTablePayloadFormat(TablePayloadFormat.AtomPub); @@ -458,10 +471,9 @@ public void testSelectOnlySendsReservedColumnsOnce() throws StorageException { testSelectOnlySendsReservedColumnsOnce(options, true); } - private void testSelectOnlySendsReservedColumnsOnce(TableRequestOptions options, boolean usePropertyResolver) - throws StorageException { + private void testSelectOnlySendsReservedColumnsOnce(TableRequestOptions options, boolean usePropertyResolver) { // Create entity to use property resolver - Class1 randEnt = TableTestBase.generateRandomEntity(null); + Class1 randEnt = TableTestHelper.generateRandomEntity(null); if (usePropertyResolver) { options.setPropertyResolver(randEnt); @@ -495,8 +507,9 @@ public void eventOccurred(ResponseReceivedEvent eventArg) { } } + @SuppressWarnings("deprecation") @Test - public void testTableQueryWithReflection() throws StorageException { + public void testTableQueryWithReflection() { TableRequestOptions options = new TableRequestOptions(); options.setTablePayloadFormat(TablePayloadFormat.AtomPub); @@ -515,10 +528,9 @@ public void testTableQueryWithReflection() throws StorageException { testTableQueryWithReflection(options, true); } - private void testTableQueryWithReflection(TableRequestOptions options, boolean usePropertyResolver) - throws StorageException { + private void testTableQueryWithReflection(TableRequestOptions options, boolean usePropertyResolver) { // Create entity to check against - Class1 randEnt = TableTestBase.generateRandomEntity(null); + Class1 randEnt = TableTestHelper.generateRandomEntity(null); if (usePropertyResolver) { options.setPropertyResolver(randEnt); @@ -535,8 +547,9 @@ private void testTableQueryWithReflection(TableRequestOptions options, boolean u } } + @SuppressWarnings("deprecation") @Test - public void testTableQueryWithEntityResolver() throws StorageException { + public void testTableQueryWithEntityResolver() { TableRequestOptions options = new TableRequestOptions(); options.setTablePayloadFormat(TablePayloadFormat.AtomPub); @@ -555,10 +568,9 @@ public void testTableQueryWithEntityResolver() throws StorageException { testTableQueryWithEntityResolver(options, true); } - private void testTableQueryWithEntityResolver(TableRequestOptions options, boolean usePropertyResolver) - throws StorageException { + private void testTableQueryWithEntityResolver(TableRequestOptions options, boolean usePropertyResolver) { // Create entity to check against - Class1 randEnt = TableTestBase.generateRandomEntity(null); + Class1 randEnt = TableTestHelper.generateRandomEntity(null); if (usePropertyResolver) { options.setPropertyResolver(randEnt); @@ -588,8 +600,9 @@ public Class1 resolve(String partitionKey, String rowKey, Date timeStamp, } } + @SuppressWarnings("deprecation") @Test - public void testTableQueryWithTake() throws StorageException, IOException, URISyntaxException { + public void testTableQueryWithTake() throws StorageException { TableRequestOptions options = new TableRequestOptions(); options.setTablePayloadFormat(TablePayloadFormat.AtomPub); @@ -608,10 +621,10 @@ public void testTableQueryWithTake() throws StorageException, IOException, URISy testTableQueryWithTake(options, true); } - private void testTableQueryWithTake(TableRequestOptions options, boolean usePropertyResolver) throws IOException, - URISyntaxException, StorageException { + private void testTableQueryWithTake(TableRequestOptions options, boolean usePropertyResolver) + throws StorageException { // Create entity to check against - Class1 randEnt = TableTestBase.generateRandomEntity(null); + Class1 randEnt = TableTestHelper.generateRandomEntity(null); if (usePropertyResolver) { options.setPropertyResolver(randEnt); @@ -633,8 +646,9 @@ private void testTableQueryWithTake(TableRequestOptions options, boolean useProp assertEquals(count, 25); } + @SuppressWarnings("deprecation") @Test - public void testTableQueryWithFilter() throws StorageException { + public void testTableQueryWithFilter() { TableRequestOptions options = new TableRequestOptions(); options.setTablePayloadFormat(TablePayloadFormat.AtomPub); @@ -653,9 +667,8 @@ public void testTableQueryWithFilter() throws StorageException { testTableQueryWithFilter(options, true); } - private void testTableQueryWithFilter(TableRequestOptions options, boolean usePropertyResolver) - throws StorageException { - Class1 randEnt = TableTestBase.generateRandomEntity(null); + private void testTableQueryWithFilter(TableRequestOptions options, boolean usePropertyResolver) { + Class1 randEnt = TableTestHelper.generateRandomEntity(null); if (usePropertyResolver) { options.setPropertyResolver(randEnt); @@ -678,8 +691,9 @@ private void testTableQueryWithFilter(TableRequestOptions options, boolean usePr assertEquals(count, 50); } + @SuppressWarnings("deprecation") @Test - public void testTableQueryWithContinuation() throws StorageException { + public void testTableQueryWithContinuation() { TableRequestOptions options = new TableRequestOptions(); options.setTablePayloadFormat(TablePayloadFormat.AtomPub); @@ -698,9 +712,8 @@ public void testTableQueryWithContinuation() throws StorageException { testTableQueryWithContinuation(options, true); } - private void testTableQueryWithContinuation(TableRequestOptions options, boolean usePropertyResolver) - throws StorageException { - Class1 randEnt = TableTestBase.generateRandomEntity(null); + private void testTableQueryWithContinuation(TableRequestOptions options, boolean usePropertyResolver) { + Class1 randEnt = TableTestHelper.generateRandomEntity(null); if (usePropertyResolver) { options.setPropertyResolver(randEnt); diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableSerializerTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableSerializerTests.java similarity index 80% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableSerializerTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableSerializerTests.java index c0fe577cadd1c..cb11758f92cd9 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableSerializerTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableSerializerTests.java @@ -12,30 +12,83 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import static org.junit.Assert.*; -import java.io.IOException; +import java.io.ByteArrayInputStream; +import java.io.StringReader; import java.net.URISyntaxException; import java.util.UUID; +import javax.xml.stream.XMLStreamException; + +import org.junit.After; +import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.table.TableTestHelper.Class1; +import com.microsoft.azure.storage.table.TableTestHelper.ComplexEntity; +import com.microsoft.azure.storage.table.TableTestHelper.IgnoreOnGetter; +import com.microsoft.azure.storage.table.TableTestHelper.IgnoreOnGetterAndSetter; +import com.microsoft.azure.storage.table.TableTestHelper.IgnoreOnSetter; +import com.microsoft.azure.storage.table.TableTestHelper.InvalidStoreAsEntity; +import com.microsoft.azure.storage.table.TableTestHelper.StoreAsEntity; +import com.microsoft.azure.storage.table.TableTestHelper.StrangeDoubles; /** * Table Serializer Tests */ @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) -public class TableSerializerTests extends TableTestBase { +public class TableSerializerTests { + + private CloudTable table; + + @Before + public void tableTestMethodSetUp() throws URISyntaxException, StorageException { + table = TableTestHelper.getRandomTableReference(); + table.createIfNotExists(); + } + + @After + public void tableTestMethodTearDown() throws StorageException { + table.deleteIfExists(); + } + + /** + * In some versions of Java, when more than 64000 XmlReaders are created with the same factory, bizarre + * error messages are thrown on every subsequent attempt to make an XmlReader: “Message: JAXP00010001: The parser + * has encountered more than "64000" entity expansions in this document; this is the limit imposed by the JDK.” This + * is an issue with our library as high concurrency, or even simply long running processes, will have every service + * request which must read a result fail after 64000 readers have been made. This tests that our workaround is + * functioning correctly. The JDK bug applies to, at least, versions 6u65 and 7u45 and will be fixed in future + * versions. + * + * @see Oracle JDK Bug + * @throws XMLStreamException + */ + @Test + public void testStaxEntityExpansionExceptionHandling() throws XMLStreamException { + String testXML = "javasdk"; + + for (int i = 0; i < 64001; i++) { + ByteArrayInputStream stream = new ByteArrayInputStream(testXML.getBytes()); + DeserializationHelper.createXMLStreamReaderFromStream(stream); + } + + for (int i = 0; i < 64001; i++) { + StringReader reader = new StringReader(testXML); + DeserializationHelper.createXMLStreamReaderFromReader(reader); + } + } @Test - public void testIgnoreAnnotation() throws IOException, URISyntaxException, StorageException { + public void testIgnoreAnnotation() throws StorageException { // Ignore On Getter IgnoreOnGetter ignoreGetter = new IgnoreOnGetter(); ignoreGetter.setPartitionKey("jxscl_odata"); @@ -80,7 +133,7 @@ public void testIgnoreAnnotation() throws IOException, URISyntaxException, Stora } @Test - public void testStoreAsAnnotation() throws IOException, URISyntaxException, StorageException { + public void testStoreAsAnnotation() throws StorageException { StoreAsEntity ref = new StoreAsEntity(); ref.setPartitionKey("jxscl_odata"); ref.setRowKey(UUID.randomUUID().toString()); @@ -105,7 +158,7 @@ public void testStoreAsAnnotation() throws IOException, URISyntaxException, Stor } @Test - public void testInvalidStoreAsAnnotation() throws IOException, URISyntaxException, StorageException { + public void testInvalidStoreAsAnnotation() throws StorageException { InvalidStoreAsEntity ref = new InvalidStoreAsEntity(); ref.setPartitionKey("jxscl_odata"); ref.setRowKey(UUID.randomUUID().toString()); @@ -121,8 +174,9 @@ public void testInvalidStoreAsAnnotation() throws IOException, URISyntaxExceptio assertEquals(retrievedStoreAsRef.getStoreAsString(), null); } + @SuppressWarnings("deprecation") @Test - public void testComplexEntityInsert() throws StorageException, IOException, URISyntaxException { + public void testComplexEntityInsert() throws StorageException { TableRequestOptions options = new TableRequestOptions(); options.setTablePayloadFormat(TablePayloadFormat.AtomPub); @@ -141,8 +195,8 @@ public void testComplexEntityInsert() throws StorageException, IOException, URIS testComplexEntityInsert(options, true); } - private void testComplexEntityInsert(TableRequestOptions options, boolean usePropertyResolver) throws IOException, - URISyntaxException, StorageException { + private void testComplexEntityInsert(TableRequestOptions options, boolean usePropertyResolver) + throws StorageException { ComplexEntity ref = new ComplexEntity(); ref.setPartitionKey("jxscl_odata"); ref.setRowKey(UUID.randomUUID().toString()); @@ -161,8 +215,9 @@ private void testComplexEntityInsert(TableRequestOptions options, boolean usePro ref.assertEquality(retrievedComplexRef); } + @SuppressWarnings("deprecation") @Test - public void testDoubles() throws StorageException, IOException, URISyntaxException { + public void testDoubles() throws StorageException { TableRequestOptions options = new TableRequestOptions(); options.setTablePayloadFormat(TablePayloadFormat.AtomPub); @@ -201,8 +256,9 @@ private void testDoubles(TableRequestOptions options, boolean usePropertyResolve ref.assertEquality(retrievedComplexRef); } + @SuppressWarnings("deprecation") @Test - public void testWhitespaceTest() throws StorageException, IOException, URISyntaxException { + public void testWhitespaceTest() throws StorageException { TableRequestOptions options = new TableRequestOptions(); options.setTablePayloadFormat(TablePayloadFormat.AtomPub); @@ -243,8 +299,9 @@ private void testWhitespaceTest(TableRequestOptions options, boolean useProperty assertEquals(((Class1) res.getResult()).getA(), ref.getA()); } + @SuppressWarnings("deprecation") @Test - public void testWhitespaceOnEmptyKeysTest() throws StorageException, IOException, URISyntaxException { + public void testWhitespaceOnEmptyKeysTest() throws StorageException { TableRequestOptions options = new TableRequestOptions(); options.setTablePayloadFormat(TablePayloadFormat.AtomPub); @@ -288,8 +345,9 @@ private void testWhitespaceOnEmptyKeysTest(TableRequestOptions options, boolean table.execute(TableOperation.delete(ref), options, null); } + @SuppressWarnings("deprecation") @Test - public void testNewLineTest() throws StorageException, IOException, URISyntaxException { + public void testNewLineTest() throws StorageException { TableRequestOptions options = new TableRequestOptions(); options.setTablePayloadFormat(TablePayloadFormat.AtomPub); @@ -330,8 +388,9 @@ private void testNewLineTest(TableRequestOptions options, boolean usePropertyRes assertEquals(((Class1) res.getResult()).getA(), ref.getA()); } + @SuppressWarnings("deprecation") @Test - public void testNulls() throws StorageException, IOException, URISyntaxException { + public void testNulls() throws StorageException { TableRequestOptions options = new TableRequestOptions(); options.setTablePayloadFormat(TablePayloadFormat.AtomPub); @@ -350,8 +409,7 @@ public void testNulls() throws StorageException, IOException, URISyntaxException testNulls(options, true); } - private void testNulls(TableRequestOptions options, boolean usePropertyResolver) throws IOException, - URISyntaxException, StorageException { + private void testNulls(TableRequestOptions options, boolean usePropertyResolver) throws StorageException { ComplexEntity ref = new ComplexEntity(); ref.setPartitionKey("jxscl_odata"); ref.setRowKey(UUID.randomUUID().toString()); diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableTestBase.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableTestHelper.java similarity index 93% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableTestBase.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableTestHelper.java index 41956ffaf63ec..713365371f314 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableTestBase.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableTestHelper.java @@ -12,51 +12,40 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import static org.junit.Assert.*; import java.net.URISyntaxException; -import java.security.InvalidKeyException; import java.util.Arrays; import java.util.Date; import java.util.UUID; -import org.junit.AfterClass; -import org.junit.BeforeClass; - -import com.microsoft.windowsazure.storage.StorageCredentialsSharedAccessSignature; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.TestBase; -import com.microsoft.windowsazure.storage.table.TableRequestOptions.PropertyResolver; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.TestHelper; +import com.microsoft.azure.storage.table.TableRequestOptions.PropertyResolver; /** * Table Test Base */ -public class TableTestBase extends TestBase { - - protected static CloudTableClient tClient; - protected static String testSuiteTableName = generateRandomTableName(); - protected static CloudTable table; - - @BeforeClass - public static void setup() throws URISyntaxException, StorageException, InvalidKeyException { - tClient = createCloudTableClient(); - testSuiteTableName = generateRandomTableName(); +public class TableTestHelper extends TestHelper { - table = tClient.getTableReference(testSuiteTableName); - table.create(); + public static String generateRandomTableName() { + String tableName = "table" + UUID.randomUUID().toString().toLowerCase(); + return tableName.replace("-", ""); } - @AfterClass - public static void teardown() throws StorageException, URISyntaxException { - CloudTable table = tClient.getTableReference(testSuiteTableName); - table.delete(); + public static String generateRandomQueueName() { + String queueName = "queue" + UUID.randomUUID().toString(); + return queueName.replace("-", ""); } - public static String generateRandomTableName() { - String tableName = "table" + UUID.randomUUID().toString(); - return tableName.replace("-", ""); + public static CloudTable getRandomTableReference() throws URISyntaxException, StorageException { + String tableName = generateRandomTableName(); + CloudTableClient tClient = createCloudTableClient(); + CloudTable table = tClient.getTableReference(tableName); + + return table; } public static Class1 generateRandomEntity(String pk) { @@ -71,17 +60,6 @@ public static Class1 generateRandomEntity(String pk) { return ref; } - public static CloudTableClient getTableForSas(CloudTable table, SharedAccessTablePolicy policy, - String accessIdentifier, String startPk, String startRk, String endPk, String endRk) - throws InvalidKeyException, StorageException { - String sasString = table - .generateSharedAccessSignature(policy, accessIdentifier, startPk, startRk, endPk, endRk); - CloudTableClient client = new CloudTableClient(tClient.getEndpoint(), - new StorageCredentialsSharedAccessSignature(sasString)); - client.setTablePayloadFormat(tClient.getTablePayloadFormat()); - return client; - } - public static class Class1 extends TableServiceEntity implements PropertyResolver { public String A; @@ -96,6 +74,10 @@ public Class1() { // empty ctor } + public Class1(String pk, String rk) { + super(pk, rk); + } + public synchronized String getA() { return this.A; } @@ -248,7 +230,7 @@ public EdmType propertyResolver(String pk, String rk, String key, String value) } } - class class1class2PropertyResolver implements PropertyResolver { + public static class class1class2PropertyResolver implements PropertyResolver { @Override public EdmType propertyResolver(String pk, String rk, String key, String value) { diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableTests.java similarity index 59% rename from microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableTests.java rename to microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableTests.java index 584656bf23c9d..50dcd8e8e4a94 100644 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/table/TableTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/table/TableTests.java @@ -13,11 +13,11 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import static org.junit.Assert.*; -import java.io.IOException; +import java.net.URI; import java.net.URISyntaxException; import java.security.InvalidKeyException; import java.util.Calendar; @@ -31,18 +31,72 @@ import org.junit.Test; import org.junit.experimental.categories.Category; -import com.microsoft.windowsazure.storage.LocationMode; -import com.microsoft.windowsazure.storage.RetryNoRetry; -import com.microsoft.windowsazure.storage.StorageCredentialsSharedAccessSignature; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.TestRunners.CloudTests; -import com.microsoft.windowsazure.storage.TestRunners.DevFabricTests; -import com.microsoft.windowsazure.storage.TestRunners.DevStoreTests; -import com.microsoft.windowsazure.storage.TestRunners.SlowTests; -import com.microsoft.windowsazure.storage.core.PathUtility; +import com.microsoft.azure.storage.CloudStorageAccount; +import com.microsoft.azure.storage.LocationMode; +import com.microsoft.azure.storage.RetryNoRetry; +import com.microsoft.azure.storage.StorageCredentials; +import com.microsoft.azure.storage.StorageCredentialsAccountAndKey; +import com.microsoft.azure.storage.StorageCredentialsSharedAccessSignature; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.TestRunners.CloudTests; +import com.microsoft.azure.storage.TestRunners.DevFabricTests; +import com.microsoft.azure.storage.TestRunners.DevStoreTests; +import com.microsoft.azure.storage.TestRunners.SlowTests; +import com.microsoft.azure.storage.core.PathUtility; +import com.microsoft.azure.storage.table.TableTestHelper.Class1; @Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class }) -public class TableTests extends TableTestBase { +public class TableTests { + + @Test + public void testIsUsePathStyleUri() throws InvalidKeyException, URISyntaxException, StorageException { + // normal account + StorageCredentials creds = new StorageCredentialsAccountAndKey("testAccountName", + "/g6UPBuy0ypCpAbYTL6/KA+dI/7gyoWvLFYmah3IviUP1jykOHHOlA=="); + CloudStorageAccount account = new CloudStorageAccount(creds); + testIsUsePathStyleUri(creds, account.getTableEndpoint().toString(), false); + + // normal account with path + creds = new StorageCredentialsAccountAndKey("testAccountName", + "/g6UPBuy0ypCpAbYTL6/KA+dI/7gyoWvLFYmah3IviUP1jykOHHOlA=="); + account = new CloudStorageAccount(creds); + testIsUsePathStyleUri(creds, account.getTableEndpoint().toString() + "/mytable", false); + + // custom endpoint + creds = new StorageCredentialsAccountAndKey("testAccountName", + "/g6UPBuy0ypCpAbYTL6/KA+dI/7gyoWvLFYmah3IviUP1jykOHHOlA=="); + testIsUsePathStyleUri(creds, "http://www.contoso.com", false); + + // dev store + account = CloudStorageAccount.getDevelopmentStorageAccount(); + testIsUsePathStyleUri(account.getCredentials(), account.getTableEndpoint().toString(), true); + + // dev store with proxy + account = CloudStorageAccount.getDevelopmentStorageAccount(new URI("http://ipv4.fiddler")); + testIsUsePathStyleUri(account.getCredentials(), account.getTableEndpoint().toString(), true); + + // custom endpoints ipv4 with path-style (internal test) + creds = new StorageCredentialsAccountAndKey("testAccountName", + "/g6UPBuy0ypCpAbYTL6/KA+dI/7gyoWvLFYmah3IviUP1jykOHHOlA=="); + testIsUsePathStyleUri(creds, "http://93.184.216.119/testAccountName", true); + } + + private static void testIsUsePathStyleUri(StorageCredentials creds, String tableEndpoint, boolean usePathStyleUris) + throws URISyntaxException, InvalidKeyException, StorageException { + CloudTableClient tableClient = new CloudTableClient(new URI(tableEndpoint), creds); + assertEquals(usePathStyleUris, tableClient.isUsePathStyleUris()); + + CloudTable table = tableClient.getTableReference("mytable"); + assertEquals(tableEndpoint + "/mytable", table.getUri().toString()); + + String sasToken = table.generateSharedAccessSignature(null, "fakeIdentifier", null, null, null, null); + tableClient = new CloudTableClient(new URI(tableEndpoint), + new StorageCredentialsSharedAccessSignature(sasToken)); + assertEquals(usePathStyleUris, tableClient.isUsePathStyleUris()); + + table = new CloudTable(table.getUri(), tableClient); + assertEquals(tableEndpoint + "/mytable", table.getUri().toString()); + } /** * Get permissions from string @@ -74,22 +128,25 @@ public void testTablePermissionsFromString() { assertEquals(EnumSet.of(SharedAccessTablePermissions.UPDATE), policy.getPermissions()); } + @SuppressWarnings("deprecation") @Test - public void testTableCreateAndAttemptCreateOnceExists() throws StorageException, IOException, URISyntaxException { - CloudTableClient tClient = createCloudTableClient(); + public void testTableCreateAndAttemptCreateOnceExists() throws StorageException, URISyntaxException { + + CloudTableClient tClient = TableTestHelper.createCloudTableClient(); - tClient.setTablePayloadFormat(TablePayloadFormat.AtomPub); + tClient.getDefaultRequestOptions().setTablePayloadFormat(TablePayloadFormat.AtomPub); testTableCreateAndAttemptCreateOnceExists(tClient); - tClient.setTablePayloadFormat(TablePayloadFormat.Json); + tClient.getDefaultRequestOptions().setTablePayloadFormat(TablePayloadFormat.Json); testTableCreateAndAttemptCreateOnceExists(tClient); } private void testTableCreateAndAttemptCreateOnceExists(CloudTableClient tClient) throws StorageException, URISyntaxException { - String tableName = generateRandomTableName(); + String tableName = TableTestHelper.generateRandomTableName(); + CloudTable table = tClient.getTableReference(tableName); - tClient.setTablePayloadFormat(TablePayloadFormat.Json); + tClient.getDefaultRequestOptions().setTablePayloadFormat(TablePayloadFormat.Json); try { table.create(); assertTrue(table.exists()); @@ -109,19 +166,22 @@ private void testTableCreateAndAttemptCreateOnceExists(CloudTableClient tClient) } } + @SuppressWarnings("deprecation") @Test - public void testTableCreateExistsAndDelete() throws StorageException, IOException, URISyntaxException { - CloudTableClient tClient = createCloudTableClient(); + public void testTableCreateExistsAndDelete() throws StorageException, URISyntaxException { + + CloudTableClient tClient = TableTestHelper.createCloudTableClient(); - tClient.setTablePayloadFormat(TablePayloadFormat.AtomPub); + tClient.getDefaultRequestOptions().setTablePayloadFormat(TablePayloadFormat.AtomPub); testTableCreateExistsAndDelete(tClient); - tClient.setTablePayloadFormat(TablePayloadFormat.Json); + tClient.getDefaultRequestOptions().setTablePayloadFormat(TablePayloadFormat.Json); testTableCreateExistsAndDelete(tClient); } private void testTableCreateExistsAndDelete(CloudTableClient tClient) throws StorageException, URISyntaxException { - String tableName = generateRandomTableName(); + String tableName = TableTestHelper.generateRandomTableName(); + CloudTable table = tClient.getTableReference(tableName); try { assertTrue(table.createIfNotExists()); @@ -134,19 +194,22 @@ private void testTableCreateExistsAndDelete(CloudTableClient tClient) throws Sto } } + @SuppressWarnings("deprecation") @Test - public void testTableCreateIfNotExists() throws StorageException, IOException, URISyntaxException { - CloudTableClient tClient = createCloudTableClient(); + public void testTableCreateIfNotExists() throws StorageException, URISyntaxException { - tClient.setTablePayloadFormat(TablePayloadFormat.AtomPub); + CloudTableClient tClient = TableTestHelper.createCloudTableClient(); + + tClient.getDefaultRequestOptions().setTablePayloadFormat(TablePayloadFormat.AtomPub); testTableCreateIfNotExists(tClient); - tClient.setTablePayloadFormat(TablePayloadFormat.Json); + tClient.getDefaultRequestOptions().setTablePayloadFormat(TablePayloadFormat.Json); testTableCreateIfNotExists(tClient); } private void testTableCreateIfNotExists(CloudTableClient tClient) throws StorageException, URISyntaxException { - String tableName = generateRandomTableName(); + String tableName = TableTestHelper.generateRandomTableName(); + CloudTable table = tClient.getTableReference(tableName); try { assertTrue(table.createIfNotExists()); @@ -159,19 +222,22 @@ private void testTableCreateIfNotExists(CloudTableClient tClient) throws Storage } } + @SuppressWarnings("deprecation") @Test - public void testTableDeleteIfExists() throws StorageException, IOException, URISyntaxException { - CloudTableClient tClient = createCloudTableClient(); + public void testTableDeleteIfExists() throws StorageException, URISyntaxException { + + CloudTableClient tClient = TableTestHelper.createCloudTableClient(); - tClient.setTablePayloadFormat(TablePayloadFormat.AtomPub); + tClient.getDefaultRequestOptions().setTablePayloadFormat(TablePayloadFormat.AtomPub); testTableDeleteIfExists(tClient); - tClient.setTablePayloadFormat(TablePayloadFormat.Json); + tClient.getDefaultRequestOptions().setTablePayloadFormat(TablePayloadFormat.Json); testTableDeleteIfExists(tClient); } private void testTableDeleteIfExists(CloudTableClient tClient) throws StorageException, URISyntaxException { - String tableName = generateRandomTableName(); + String tableName = TableTestHelper.generateRandomTableName(); + CloudTable table = tClient.getTableReference(tableName); assertFalse(table.deleteIfExists()); @@ -182,20 +248,23 @@ private void testTableDeleteIfExists(CloudTableClient tClient) throws StorageExc assertFalse(table.deleteIfExists()); } + @SuppressWarnings("deprecation") @Test - public void testTableDeleteWhenExistAndNotExists() throws StorageException, IOException, URISyntaxException { - CloudTableClient tClient = createCloudTableClient(); + public void testTableDeleteWhenExistAndNotExists() throws StorageException, URISyntaxException { + + CloudTableClient tClient = TableTestHelper.createCloudTableClient(); - tClient.setTablePayloadFormat(TablePayloadFormat.AtomPub); + tClient.getDefaultRequestOptions().setTablePayloadFormat(TablePayloadFormat.AtomPub); testTableDeleteWhenExistAndNotExists(tClient); - tClient.setTablePayloadFormat(TablePayloadFormat.Json); + tClient.getDefaultRequestOptions().setTablePayloadFormat(TablePayloadFormat.Json); testTableDeleteWhenExistAndNotExists(tClient); } private void testTableDeleteWhenExistAndNotExists(CloudTableClient tClient) throws StorageException, URISyntaxException { - String tableName = generateRandomTableName(); + String tableName = TableTestHelper.generateRandomTableName(); + CloudTable table = tClient.getTableReference(tableName); try { @@ -218,19 +287,21 @@ private void testTableDeleteWhenExistAndNotExists(CloudTableClient tClient) thro } } + @SuppressWarnings("deprecation") @Test - public void testTableDoesTableExist() throws StorageException, IOException, URISyntaxException { - CloudTableClient tClient = createCloudTableClient(); + public void testTableDoesTableExist() throws StorageException, URISyntaxException { - tClient.setTablePayloadFormat(TablePayloadFormat.AtomPub); + CloudTableClient tClient = TableTestHelper.createCloudTableClient(); + + tClient.getDefaultRequestOptions().setTablePayloadFormat(TablePayloadFormat.AtomPub); testTableDoesTableExist(tClient); - tClient.setTablePayloadFormat(TablePayloadFormat.Json); + tClient.getDefaultRequestOptions().setTablePayloadFormat(TablePayloadFormat.Json); testTableDoesTableExist(tClient); } private void testTableDoesTableExist(CloudTableClient tClient) throws StorageException, URISyntaxException { - String tableName = generateRandomTableName(); + String tableName = TableTestHelper.generateRandomTableName(); CloudTable table = tClient.getTableReference(tableName); try { @@ -244,22 +315,24 @@ private void testTableDoesTableExist(CloudTableClient tClient) throws StorageExc } } + @SuppressWarnings("deprecation") @Category(SlowTests.class) @Test - public void testTableGetSetPermissionTest() throws StorageException, IOException, URISyntaxException, - InterruptedException { - CloudTableClient tClient = createCloudTableClient(); + public void testTableGetSetPermissionTest() throws StorageException, URISyntaxException, InterruptedException { + + CloudTableClient tClient = TableTestHelper.createCloudTableClient(); - tClient.setTablePayloadFormat(TablePayloadFormat.AtomPub); + tClient.getDefaultRequestOptions().setTablePayloadFormat(TablePayloadFormat.AtomPub); testTableGetSetPermissionTest(tClient); - tClient.setTablePayloadFormat(TablePayloadFormat.Json); + tClient.getDefaultRequestOptions().setTablePayloadFormat(TablePayloadFormat.Json); testTableGetSetPermissionTest(tClient); } private void testTableGetSetPermissionTest(CloudTableClient tClient) throws StorageException, URISyntaxException, InterruptedException { - String tableName = generateRandomTableName(); + String tableName = TableTestHelper.generateRandomTableName(); + CloudTable table = tClient.getTableReference(tableName); table.create(); @@ -301,23 +374,24 @@ private void testTableGetSetPermissionTest(CloudTableClient tClient) throws Stor } } + @SuppressWarnings("deprecation") @Category(SlowTests.class) @Test - public void testTableSas() throws StorageException, IOException, URISyntaxException, InvalidKeyException, - InterruptedException { - CloudTableClient tClient = createCloudTableClient(); + public void testTableSas() throws StorageException, URISyntaxException, InvalidKeyException, InterruptedException { + + CloudTableClient tClient = TableTestHelper.createCloudTableClient(); - tClient.setTablePayloadFormat(TablePayloadFormat.AtomPub); + tClient.getDefaultRequestOptions().setTablePayloadFormat(TablePayloadFormat.AtomPub); testTableSas(tClient); - tClient.setTablePayloadFormat(TablePayloadFormat.Json); + tClient.getDefaultRequestOptions().setTablePayloadFormat(TablePayloadFormat.Json); testTableSas(tClient); } private void testTableSas(CloudTableClient tClient) throws InvalidKeyException, URISyntaxException, StorageException, InterruptedException { // use capital letters to make sure SAS signature converts name to lower case correctly - String name = "CAPS" + generateRandomTableName(); + String name = "CAPS" + TableTestHelper.generateRandomTableName(); CloudTable table = tClient.getTableReference(name); table.create(); @@ -343,7 +417,7 @@ private void testTableSas(CloudTableClient tClient) throws InvalidKeyException, TableBatchOperation batch = new TableBatchOperation(); for (int j = 0; j < 100; j++) { - Class1 ent = generateRandomEntity("javatables_batch_" + Integer.toString(i)); + Class1 ent = TableTestHelper.generateRandomEntity("javatables_batch_" + Integer.toString(i)); ent.setRowKey(String.format("%06d", j)); batch.insert(ent); } @@ -351,8 +425,10 @@ private void testTableSas(CloudTableClient tClient) throws InvalidKeyException, table.execute(batch); } - CloudTableClient tableClientFromPermission = TableTestBase.getTableForSas(table, policy1, null, - "javatables_batch_0", "0", "javatables_batch_9", "9"); + String sasString = table.generateSharedAccessSignature(policy1, null, "javatables_batch_0", "0", + "javatables_batch_9", "9"); + CloudTableClient tableClientFromPermission = new CloudTableClient(tClient.getEndpoint(), + new StorageCredentialsSharedAccessSignature(sasString)); CloudTable policySasTable = tableClientFromPermission.getTableReference(name); policySasTable.exists(); @@ -360,7 +436,7 @@ private void testTableSas(CloudTableClient tClient) throws InvalidKeyException, // do not give the client and check that the new table's client has the correct perms CloudTable tableFromUri = new CloudTable(PathUtility.addToQuery(table.getStorageUri(), table .generateSharedAccessSignature((SharedAccessTablePolicy) null, identifier, "javatables_batch_0", "0", - "javatables_batch_9", "9")), null); + "javatables_batch_9", "9"))); assertEquals(StorageCredentialsSharedAccessSignature.class.toString(), tableFromUri.getServiceClient() .getCredentials().getClass().toString()); @@ -369,10 +445,10 @@ private void testTableSas(CloudTableClient tClient) throws InvalidKeyException, CloudTableClient tableClient = policySasTable.getServiceClient(); // set some arbitrary settings to make sure they are passed on - tableClient.setLocationMode(LocationMode.PRIMARY_THEN_SECONDARY); - tableClient.setTimeoutInMs(1000); - tableClient.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata); - tableClient.setRetryPolicyFactory(new RetryNoRetry()); + tableClient.getDefaultRequestOptions().setLocationMode(LocationMode.PRIMARY_THEN_SECONDARY); + tableClient.getDefaultRequestOptions().setTimeoutIntervalInMs(1000); + tableClient.getDefaultRequestOptions().setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata); + tableClient.getDefaultRequestOptions().setRetryPolicyFactory(new RetryNoRetry()); tableFromUri = new CloudTable(PathUtility.addToQuery(table.getStorageUri(), table .generateSharedAccessSignature((SharedAccessTablePolicy) null, identifier, "javatables_batch_0", "0", @@ -380,11 +456,14 @@ private void testTableSas(CloudTableClient tClient) throws InvalidKeyException, assertEquals(StorageCredentialsSharedAccessSignature.class.toString(), tableFromUri.getServiceClient() .getCredentials().getClass().toString()); - assertEquals(tableClient.getLocationMode(), tableFromUri.getServiceClient().getLocationMode()); - assertEquals(tableClient.getTimeoutInMs(), tableFromUri.getServiceClient().getTimeoutInMs()); - assertEquals(tableClient.getTablePayloadFormat(), tableFromUri.getServiceClient().getTablePayloadFormat()); - assertEquals(tableClient.getRetryPolicyFactory().getClass(), tableFromUri.getServiceClient() - .getRetryPolicyFactory().getClass()); + assertEquals(tableClient.getDefaultRequestOptions().getLocationMode(), tableFromUri.getServiceClient() + .getDefaultRequestOptions().getLocationMode()); + assertEquals(tableClient.getDefaultRequestOptions().getTimeoutIntervalInMs(), tableFromUri.getServiceClient() + .getDefaultRequestOptions().getTimeoutIntervalInMs()); + assertEquals(tableClient.getDefaultRequestOptions().getTablePayloadFormat(), tableFromUri.getServiceClient() + .getDefaultRequestOptions().getTablePayloadFormat()); + assertEquals(tableClient.getDefaultRequestOptions().getRetryPolicyFactory().getClass(), tableFromUri + .getServiceClient().getDefaultRequestOptions().getRetryPolicyFactory().getClass()); } private static void assertTablePermissionsEqual(TablePermissions expected, TablePermissions actual) { diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/AccessCondition.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/AccessCondition.java similarity index 97% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/AccessCondition.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/AccessCondition.java index a65aa51a34bf6..377788bb56342 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/AccessCondition.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/AccessCondition.java @@ -12,13 +12,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import java.net.HttpURLConnection; import java.util.Date; -import com.microsoft.windowsazure.storage.core.BaseRequest; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.core.BaseRequest; +import com.microsoft.azure.storage.core.Utility; /** * Represents a set of access conditions to be used for operations against the storage services. @@ -232,9 +232,8 @@ else if (this.ifMatchHeaderType.equals(Constants.HeaderConstants.IF_NONE_MATCH)) } if (this.ifModifiedSinceDate != null) { - // The IfModifiedSince has a special helper in HttpURLConnection, use it instead of manually setting the - // header. - request.setIfModifiedSince(this.ifModifiedSinceDate.getTime()); + request.setRequestProperty(Constants.HeaderConstants.IF_MODIFIED_SINCE, + Utility.getGMTTime(this.ifModifiedSinceDate)); } if (this.ifUnmodifiedSinceDate != null) { diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/AuthenticationScheme.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/AuthenticationScheme.java similarity index 95% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/AuthenticationScheme.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/AuthenticationScheme.java index e8f538a06859e..fd4ae5d4785d6 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/AuthenticationScheme.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/AuthenticationScheme.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; /** * Specifies the authentication scheme used to sign HTTP requests. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/BaseEvent.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/BaseEvent.java similarity index 80% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/BaseEvent.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/BaseEvent.java index 34f7b69964580..73fcd92534f32 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/BaseEvent.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/BaseEvent.java @@ -12,10 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; - -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.RequestResult; +package com.microsoft.azure.storage; /** * Represents an event. @@ -34,7 +31,7 @@ public abstract class BaseEvent { private final OperationContext opContext; /** - * A {@link RequestResult} object that represents the last request result. + * A {@link RequestResult} object that represents the current request result. */ private final RequestResult requestResult; @@ -58,6 +55,9 @@ public BaseEvent(final OperationContext opContext, final Object connectionObject } /** + * Gets a connection object. Currently only java.net.HttpURLConnection is supported as a + * connection object. + * * @return the connectionObject */ public Object getConnectionObject() { @@ -65,6 +65,9 @@ public Object getConnectionObject() { } /** + * Gets a 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. + * * @return the opContext */ public OperationContext getOpContext() { @@ -72,7 +75,9 @@ public OperationContext getOpContext() { } /** - * @return A {@link RequestResult} object that represents the current request result. + * Gets a {@link RequestResult} object that represents the current request result. + * + * @return the {@link RequestResult} object */ public RequestResult getRequestResult() { return this.requestResult; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/CloudStorageAccount.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/CloudStorageAccount.java similarity index 87% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/CloudStorageAccount.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/CloudStorageAccount.java index b5623943b42d3..d79b1a158267a 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/CloudStorageAccount.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/CloudStorageAccount.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import java.net.URI; import java.net.URISyntaxException; @@ -21,14 +21,17 @@ import java.util.HashMap; import java.util.Map.Entry; -import com.microsoft.windowsazure.storage.blob.CloudBlobClient; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.Utility; -import com.microsoft.windowsazure.storage.queue.CloudQueueClient; -import com.microsoft.windowsazure.storage.table.CloudTableClient; +import com.microsoft.azure.storage.blob.CloudBlobClient; +import com.microsoft.azure.storage.blob.CloudBlobContainer; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.StorageCredentialsHelper; +import com.microsoft.azure.storage.core.Utility; +import com.microsoft.azure.storage.queue.CloudQueueClient; +import com.microsoft.azure.storage.table.CloudTable; +import com.microsoft.azure.storage.table.CloudTableClient; /** - * Represents a Windows Azure storage account. + * Represents a Microsoft Azure storage account. */ public final class CloudStorageAccount { /** @@ -61,6 +64,17 @@ public final class CloudStorageAccount { */ private static final String DEFAULT_ENDPOINTS_PROTOCOL_NAME = "DefaultEndpointsProtocol"; + /** + * The format string for the primary endpoint. + */ + private static final String DEVELOPMENT_STORAGE_PRIMARY_ENDPOINT_FORMAT = "%s://%s:%s/%s"; + + /** + * The format string for the secondary endpoint + */ + private static final String DEVELOPMENT_STORAGE_SECONDARY_ENDPOINT_FORMAT = DEVELOPMENT_STORAGE_PRIMARY_ENDPOINT_FORMAT + + SECONDARY_LOCATION_ACCOUNT_SUFFIX; + /** * The setting name for specifying a development storage proxy Uri. */ @@ -86,18 +100,6 @@ public final class CloudStorageAccount { */ private static final String SECONDARY_ENDPOINT_FORMAT = "%s://%s%s.%s"; - /** - * The credentials string used to test for the development storage credentials. - */ - private static final String DEVSTORE_CREDENTIALS_IN_STRING = CloudStorageAccount.ACCOUNT_NAME_NAME + "=" - + CloudStorageAccount.DEVSTORE_ACCOUNT_NAME + ";" + CloudStorageAccount.ACCOUNT_KEY_NAME + "=" - + CloudStorageAccount.DEVSTORE_ACCOUNT_KEY; - - /** - * A CloudStorageAccount that represents the development storage account. - */ - private static CloudStorageAccount devStoreAccount; - /** * Represents the root queue DNS name. */ @@ -253,28 +255,28 @@ private static StorageUri getDefaultTableStorageUri(final String scheme, final S } /** - * Returns a {@link CloudStorageAccount} object that represents the development storage credentials. + * Returns a {@link CloudStorageAccount} object that represents the development storage credentials. Secondary + * endpoints are enabled by default. * * @return A {@link CloudStorageAccount} object for the development storage credentials. */ public static CloudStorageAccount getDevelopmentStorageAccount() { - if (devStoreAccount == null) { - try { - devStoreAccount = getDevelopmentStorageAccount(new URI("http://127.0.0.1")); - } - catch (final URISyntaxException e) { - // this wont happen since we know the uri above. - } + try { + return getDevelopmentStorageAccount(null); + } + catch (final URISyntaxException e) { + // this wont happen since we know the standard dev store uri is valid + return null; } - return devStoreAccount; } /** * Returns a {@link CloudStorageAccount} object that represents the development storage credentials, using the - * specified proxy URI. + * specified proxy URI. Secondary endpoints are enabled by default. * * @param proxyUri - * A java.net.URI object that represents the proxy endpoint to use. + * A java.net.URI object that represents the proxy endpoint to use. Specifying + * null will use the default http://127.0.0.1. * * @return A {@link CloudStorageAccount} object for the development storage credentials. * @@ -282,25 +284,55 @@ public static CloudStorageAccount getDevelopmentStorageAccount() { * If the resource URI is invalid. */ public static CloudStorageAccount getDevelopmentStorageAccount(final URI proxyUri) throws URISyntaxException { + String scheme; + String host; if (proxyUri == null) { - return getDevelopmentStorageAccount(); + scheme = "http"; + host = "127.0.0.1"; } + else { + scheme = proxyUri.getScheme(); + host = proxyUri.getHost(); + } + + StorageCredentials credentials = new StorageCredentialsAccountAndKey(DEVSTORE_ACCOUNT_NAME, + DEVSTORE_ACCOUNT_KEY); + + URI blobPrimaryEndpoint = new URI(String.format(DEVELOPMENT_STORAGE_PRIMARY_ENDPOINT_FORMAT, scheme, host, + "10000", DEVSTORE_ACCOUNT_NAME)); + URI queuePrimaryEndpoint = new URI(String.format(DEVELOPMENT_STORAGE_PRIMARY_ENDPOINT_FORMAT, scheme, host, + "10001", DEVSTORE_ACCOUNT_NAME)); + URI tablePrimaryEndpoint = new URI(String.format(DEVELOPMENT_STORAGE_PRIMARY_ENDPOINT_FORMAT, scheme, host, + "10002", DEVSTORE_ACCOUNT_NAME)); + + URI blobSecondaryEndpoint = new URI(String.format(DEVELOPMENT_STORAGE_SECONDARY_ENDPOINT_FORMAT, scheme, host, + "10000", DEVSTORE_ACCOUNT_NAME)); + URI queueSecondaryEndpoint = new URI(String.format(DEVELOPMENT_STORAGE_SECONDARY_ENDPOINT_FORMAT, scheme, host, + "10001", DEVSTORE_ACCOUNT_NAME)); + URI tableSecondaryEndpoint = new URI(String.format(DEVELOPMENT_STORAGE_SECONDARY_ENDPOINT_FORMAT, scheme, host, + "10002", DEVSTORE_ACCOUNT_NAME)); + + CloudStorageAccount account = new CloudStorageAccount(credentials, new StorageUri(blobPrimaryEndpoint, + blobSecondaryEndpoint), new StorageUri(queuePrimaryEndpoint, queueSecondaryEndpoint), new StorageUri( + tablePrimaryEndpoint, tableSecondaryEndpoint)); - String prefix = proxyUri.getScheme().concat("://"); - prefix = prefix.concat(proxyUri.getHost()); + account.isDevStoreAccount = true; - return new CloudStorageAccount( - new StorageCredentialsAccountAndKey(DEVSTORE_ACCOUNT_NAME, DEVSTORE_ACCOUNT_KEY), new StorageUri( - new URI(prefix.concat(":10000/devstoreaccount1"))), new StorageUri(new URI( - prefix.concat(":10001/devstoreaccount1"))), new StorageUri(new URI( - prefix.concat(":10002/devstoreaccount1")))); + return account; } /** * Parses a connection string and returns a cloud storage account created from the connection string. *

- * Note this method is not supported for shared access signature credentials as they do not contain the required - * endpoint configuration parameters. + * The connection string should be in the Azure + * connection string format. + *

+ * Note that while a connection string may include a SAS token, it is often easier to use the + * {@link CloudBlobContainer#CloudBlobContainer(URI)}, {@link CloudBlobContainer#CloudQueue(URI)}, + * {@link CloudTable#CloudBlobContainer(URI)} constructors directly. To do this, create a + * {@link StorageCredentialsSharedAccessSignature#StorageCredentialsSharedAccessSignature(String)} object with your + * SAS token, use the {@link StorageCredentialsSharedAccessSignature#transformUri(URI)} method on the container, + * queue, or table URI, and then use that URI to construct the object. * * @param connectionString * A String that represents the connection string to parse. @@ -361,19 +393,16 @@ public static CloudStorageAccount parse(final String connectionString) throws UR private static CloudStorageAccount tryConfigureDevStore(final HashMap settings) throws URISyntaxException { if (settings.containsKey(USE_DEVELOPMENT_STORAGE_NAME)) { - final String useDevStoreSetting = settings.get(USE_DEVELOPMENT_STORAGE_NAME); - URI devStoreProxyUri = null; - - if (!Boolean.parseBoolean(useDevStoreSetting)) { + if (!Boolean.parseBoolean(settings.get(USE_DEVELOPMENT_STORAGE_NAME))) { throw new IllegalArgumentException(SR.INVALID_CONNECTION_STRING_DEV_STORE_NOT_TRUE); } + URI devStoreProxyUri = null; if (settings.containsKey(DEVELOPMENT_STORAGE_PROXY_URI_NAME)) { devStoreProxyUri = new URI(settings.get(DEVELOPMENT_STORAGE_PROXY_URI_NAME)); } return getDevelopmentStorageAccount(devStoreProxyUri); - } else { return null; @@ -470,25 +499,29 @@ else if (isExplicitBlobEndpoint || isExplicitQueueEndpoint || isExplicitTableEnd /** * Internal flag storing true if the blob endpoint was created using default settings. False if the caller specified - * the - * blob endpoint explicitly. + * the blob endpoint explicitly. */ private boolean isBlobEndpointDefault = false; /** * Internal flag storing true if the queue endpoint was created using default settings. False if the caller - * specified the - * blob endpoint explicitly. + * specified the queue endpoint explicitly. */ private boolean isQueueEndpointDefault = false; /** * Internal flag storing true if the table endpoint was created using default settings. False if the caller - * specified the - * blob endpoint explicitly. + * specified the table endpoint explicitly. */ private boolean isTableEndpointDefault = false; + /** + * Internal flag storing true if this is a dev store account created by one of the getDevelopmentStorageAccount + * methods, either called directly or by parsing a connection string with the UseDevelopmentStorage flag. False + * otherwise. + */ + private boolean isDevStoreAccount = false; + /** * Creates an instance of the CloudStorageAccount class using the specified account credentials. *

@@ -636,7 +669,7 @@ public CloudBlobClient createCloudBlobClient() { throw new IllegalArgumentException(SR.MISSING_CREDENTIALS); } - if (!this.credentials.canCredentialsSignRequest()) { + if (!StorageCredentialsHelper.canCredentialsSignRequest(this.credentials)) { throw new IllegalArgumentException(SR.CREDENTIALS_CANNOT_SIGN_REQUEST); } return new CloudBlobClient(this.getBlobStorageUri(), this.getCredentials()); @@ -656,7 +689,7 @@ public CloudQueueClient createCloudQueueClient() { throw new IllegalArgumentException(SR.MISSING_CREDENTIALS); } - if (!this.credentials.canCredentialsSignRequest()) { + if (!StorageCredentialsHelper.canCredentialsSignRequest(this.credentials)) { throw new IllegalArgumentException(SR.CREDENTIALS_CANNOT_SIGN_REQUEST); } return new CloudQueueClient(this.getQueueStorageUri(), this.getCredentials()); @@ -676,7 +709,7 @@ public CloudTableClient createCloudTableClient() { throw new IllegalArgumentException(SR.MISSING_CREDENTIALS); } - if (!this.credentials.canCredentialsSignRequest()) { + if (!StorageCredentialsHelper.canCredentialsSignRequest(this.credentials)) { throw new IllegalArgumentException(SR.CREDENTIALS_CANNOT_SIGN_REQUEST); } return new CloudTableClient(this.getTableStorageUri(), this.getCredentials()); @@ -826,20 +859,12 @@ public String toString(final boolean exportSecrets) { } final ArrayList retVals = new ArrayList(); - if (this == devStoreAccount) { - retVals.add(String.format("%s=true", USE_DEVELOPMENT_STORAGE_NAME)); - } - else if (this.credentials != null && DEVSTORE_ACCOUNT_NAME.equals(this.credentials.getAccountName()) - && this.credentials.toString(true).equals(CloudStorageAccount.DEVSTORE_CREDENTIALS_IN_STRING) - && this.getBlobStorageUri() != null && this.getTableStorageUri() != null - && this.getQueueStorageUri() != null - && this.getBlobEndpoint().getHost().equals(this.getQueueEndpoint().getHost()) - && this.getQueueEndpoint().getHost().equals(this.getTableEndpoint().getHost()) - && this.getBlobEndpoint().getScheme().equals(this.getQueueEndpoint().getScheme()) - && this.getQueueEndpoint().getScheme().equals(this.getTableEndpoint().getScheme())) { + if (this.isDevStoreAccount) { retVals.add(String.format("%s=true", USE_DEVELOPMENT_STORAGE_NAME)); - retVals.add(String.format("%s=%s://%s/", DEVELOPMENT_STORAGE_PROXY_URI_NAME, this.getBlobEndpoint() - .getScheme(), this.getBlobEndpoint().getHost())); + if (!this.getBlobEndpoint().toString().equals("http://127.0.0.1:10000/devstoreaccount1")) { + retVals.add(String.format("%s=%s://%s/", DEVELOPMENT_STORAGE_PROXY_URI_NAME, this.getBlobEndpoint() + .getScheme(), this.getBlobEndpoint().getHost())); + } } else { boolean addDefault = false; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/Constants.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/Constants.java similarity index 97% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/Constants.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/Constants.java index 3a9129e701e03..2288fba935d73 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/Constants.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/Constants.java @@ -12,10 +12,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; /** - * Defines constants for use with blob operations, HTTP headers, and query strings. + * RESERVED FOR INTERNAL USE. Contains storage constants. */ public final class Constants { /** @@ -93,14 +93,6 @@ public static class AnalyticsConstants { */ public static final String MAX_AGE_IN_SECONDS_ELEMENT = "MaxAgeInSeconds"; - /** - * The XML element for the Metrics - * - * @deprecated use {@link #HOUR_METRICS_ELEMENT} instead. - */ - @Deprecated - public static final String METRICS_ELEMENT = "Metrics"; - /** * The XML element for the Minute Metrics */ @@ -438,12 +430,12 @@ public static class HeaderConstants { /** * Specifies the value to use for UserAgent header. */ - public static final String USER_AGENT_PREFIX = "WA-Storage"; + public static final String USER_AGENT_PREFIX = "Azure-Storage"; /** * Specifies the value to use for UserAgent header. */ - public static final String USER_AGENT_VERSION = "0.6.0"; + public static final String USER_AGENT_VERSION = "0.7.0"; /** * The default type for content-type and accept @@ -618,7 +610,7 @@ public static class QueryConstants { } /** - * The master Windows Azure Storage header prefix. + * The master Microsoft Azure Storage header prefix. */ public static final String PREFIX_FOR_STORAGE_HEADER = "x-ms-"; @@ -677,11 +669,6 @@ public static class QueryConstants { */ public static final String COPY_STATUS_ELEMENT = "CopyStatus"; - /** - * Default client side timeout, in milliseconds, for all service clients. - */ - public static final int DEFAULT_TIMEOUT_IN_MS = 90 * 1000; - /** * XML element for delimiters. */ diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/CorsHttpMethods.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/CorsHttpMethods.java similarity index 94% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/CorsHttpMethods.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/CorsHttpMethods.java index 77959edd4169a..4f7bd3f4f5bd6 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/CorsHttpMethods.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/CorsHttpMethods.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; /** * HTTP Methods that are supported by CORS. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/CorsProperties.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/CorsProperties.java similarity index 97% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/CorsProperties.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/CorsProperties.java index 3d0ace1fdb93d..d4009d9567934 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/CorsProperties.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/CorsProperties.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import java.util.ArrayList; import java.util.List; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/CorsRule.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/CorsRule.java similarity index 98% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/CorsRule.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/CorsRule.java index 4660dca1ee283..1e66db69cfb3d 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/CorsRule.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/CorsRule.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import java.util.ArrayList; import java.util.EnumSet; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/Credentials.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/Credentials.java similarity index 82% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/Credentials.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/Credentials.java index acfd2a1d8c810..16cfd2ef13782 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/Credentials.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/Credentials.java @@ -15,10 +15,10 @@ /** * */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; -import com.microsoft.windowsazure.storage.core.Base64; -import com.microsoft.windowsazure.storage.core.SR; +import com.microsoft.azure.storage.core.Base64; +import com.microsoft.azure.storage.core.SR; /** * Represents the credentials used to sign a request against the storage services. @@ -39,11 +39,6 @@ public final class Credentials { */ private String keyName; - /** - * Stores the account name whose key is used to sign requests. - */ - private String signingAccountName; - /** * Creates an instance of the Credentials class, using the specified storage account name and access * key; the specified access key is in the form of a byte array. @@ -65,7 +60,6 @@ public Credentials(final String accountName, final byte[] key) { this.accountName = accountName; this.key = new StorageKey(key); - this.signingAccountName = accountName; } /** @@ -109,14 +103,6 @@ public String getAccountName() { return this.accountName; } - /** - * Returns the account name whose key is used to sign requests. - * Internal use only. - */ - public String getSigningAccountName() { - return this.signingAccountName; - } - /** * Returns the name of the access key to be used when signing the request. * Internal use only. @@ -144,16 +130,6 @@ protected void setAccountName(final String accountName) { this.accountName = accountName; } - /** - * Sets the account name whose key is used to sign requests. - * - * @param signingAccountName - * A String that represents the account name whose key is used to sign requests. - */ - protected void setSigningAccountName(final String signingAccountName) { - this.signingAccountName = signingAccountName; - } - /** * Sets the name of the access key to be used when signing the request. * diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/DoesServiceRequest.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/DoesServiceRequest.java similarity index 95% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/DoesServiceRequest.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/DoesServiceRequest.java index 1dfdfa2ed1edc..776b73534dbca 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/DoesServiceRequest.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/DoesServiceRequest.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import java.lang.annotation.Documented; import java.lang.annotation.Retention; diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/GeoReplicationStats.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/GeoReplicationStats.java new file mode 100644 index 0000000000000..2e5f7a5b18a91 --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/GeoReplicationStats.java @@ -0,0 +1,79 @@ +/** + * 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; + +import java.util.Date; + +/** + * Class representing the geo-replication stats. + */ +public class GeoReplicationStats { + + /** + * Specifies the geo replication status + */ + private GeoReplicationStatus status; + + /** + * Specifies the last sync time + */ + private Date lastSyncTime; + + /** + * Default constructor + */ + GeoReplicationStats() { + // no op + } + + /** + * Gets the last sync time. All primary writes preceding this value are guaranteed to be available for read + * operations. Primary writes following this point in time may or may not be available for reads. + * + * @return the lastSyncTime. + */ + public Date getLastSyncTime() { + return lastSyncTime; + } + + /** + * Gets the {@link GeoReplicationStatus} status. + * + * @return the status + */ + public GeoReplicationStatus getStatus() { + return status; + } + + /** + * Sets the last sync time. + * + * @param lastSyncTime + * the lastSyncTime to set + */ + void setLastSyncTime(Date lastSyncTime) { + this.lastSyncTime = lastSyncTime; + } + + /** + * Sets the geo-replication status. + * + * @param status + * the status to set + */ + void setStatus(GeoReplicationStatus status) { + this.status = status; + } +} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/GeoReplicationStats.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/GeoReplicationStatus.java similarity index 56% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/GeoReplicationStats.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/GeoReplicationStatus.java index 1843c6270a923..4639d14db3878 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/GeoReplicationStats.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/GeoReplicationStatus.java @@ -12,17 +12,30 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; -import java.util.Date; - -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; /** - * Class representing the geo-replication stats. + * Enumeration representing the state of geo-replication in a service. */ -public class GeoReplicationStats { +public enum GeoReplicationStatus { + + /** + * Status of geo-replication is unavailable. + */ + UNAVAILABLE, + + /** + * Geo-replication is live. + */ + LIVE, + + /** + * Data is being bootstrapped from primary to secondary. + */ + BOOTSTRAP; /** * Gets a {@link GeoReplicationStatus} from a string. @@ -32,7 +45,7 @@ public class GeoReplicationStats { * @return * A {@link GeoReplicationStatus} enumeration. */ - public static GeoReplicationStatus getGeoReplicationStatus(String geoReplicationStatus) { + protected static GeoReplicationStatus parse(String geoReplicationStatus) { if (geoReplicationStatus != null) { if (geoReplicationStatus.equals(Constants.GEO_UNAVAILABLE_VALUE)) { return GeoReplicationStatus.UNAVAILABLE; @@ -47,43 +60,4 @@ else if (geoReplicationStatus.equals(Constants.GEO_BOOTSTRAP_VALUE)) { throw new IllegalArgumentException(String.format(Utility.LOCALE_US, SR.INVALID_GEO_REPLICATION_STATUS, geoReplicationStatus)); } - - private GeoReplicationStatus status; - - private Date lastSyncTime; - - GeoReplicationStats() { - - } - - /** - * @return the lastSyncTime. All primary writes preceding this value are guaranteed to be available for read - * operations. Primary writes following this point in time may or may not be available for reads. - */ - public Date getLastSyncTime() { - return lastSyncTime; - } - - /** - * @return the status - */ - public GeoReplicationStatus getStatus() { - return status; - } - - /** - * @param lastSyncTime - * the lastSyncTime to set - */ - void setLastSyncTime(Date lastSyncTime) { - this.lastSyncTime = lastSyncTime; - } - - /** - * @param status - * the status to set - */ - void setStatus(GeoReplicationStatus status) { - this.status = status; - } } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/LocationMode.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/LocationMode.java similarity index 96% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/LocationMode.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/LocationMode.java index 9e0539868a74a..2f393d37f2ae1 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/LocationMode.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/LocationMode.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; /** * Specifies the location mode used to decide which location the request should be sent to. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/LoggingOperations.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/LoggingOperations.java similarity index 95% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/LoggingOperations.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/LoggingOperations.java index e8e09aacce669..bcd1a830b994f 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/LoggingOperations.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/LoggingOperations.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; /** * diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/LoggingProperties.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/LoggingProperties.java similarity index 98% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/LoggingProperties.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/LoggingProperties.java index 00576bbafcb98..75511423a5580 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/LoggingProperties.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/LoggingProperties.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import java.util.EnumSet; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/MetricsLevel.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/MetricsLevel.java similarity index 95% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/MetricsLevel.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/MetricsLevel.java index 6933b1b1e9ed9..cf1a3b9ad025b 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/MetricsLevel.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/MetricsLevel.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; /** * Enumeration representing the state of metrics collection in a service. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/MetricsProperties.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/MetricsProperties.java similarity index 93% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/MetricsProperties.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/MetricsProperties.java index 8ca986c55c48d..23872ec49fdda 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/MetricsProperties.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/MetricsProperties.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; /** * Represents the metrics properties for the analytics service. @@ -26,7 +26,7 @@ public final class MetricsProperties { /** * A {@link MetricsLevel} level used to enable Metric and API logging */ - private MetricsLevel metricsLevel = com.microsoft.windowsazure.storage.MetricsLevel.DISABLED; + private MetricsLevel metricsLevel = com.microsoft.azure.storage.MetricsLevel.DISABLED; /** * The Retention policy for the Metrics data. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/OperationContext.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/OperationContext.java similarity index 85% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/OperationContext.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/OperationContext.java index 3372259b568bd..b0164ed6f0961 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/OperationContext.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/OperationContext.java @@ -12,9 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; -import java.net.HttpURLConnection; import java.util.ArrayList; import java.util.HashMap; import java.util.UUID; @@ -146,11 +145,6 @@ public final class OperationContext { */ private StorageEventMultiCaster> retryingEventHandler = new StorageEventMultiCaster>(); - /** - * Reserved for internal use. Represents the current request object, which is used in continuation. - */ - private HttpURLConnection currentRequestObject; - /** * Creates an instance of the OperationContext class. */ @@ -160,6 +154,8 @@ public OperationContext() { } /** + * Get the client side trace ID. + * * @return the clientRequestID */ public String getClientRequestID() { @@ -167,23 +163,15 @@ public String getClientRequestID() { } /** + * Gets the operation latency, in milliseconds, from the client's perspective. This may include any potential + * retries. + * * @return the clientTimeInMs */ public long getClientTimeInMs() { return this.clientTimeInMs; } - /** - * Reserved for internal use. - * - * @return the currentRequestObject - * @deprecated Deprecated as of 0.6.0. - */ - @Deprecated - public HttpURLConnection getCurrentRequestObject() { - return this.currentRequestObject; - } - /** * Returns the last request result encountered for the operation. * @@ -213,6 +201,8 @@ public org.slf4j.Logger getLogger() { } /** + * Gets any additional headers for the request, for example, for proxy or logging information. + * * @return the userHeaders */ public HashMap getUserHeaders() { @@ -252,6 +242,9 @@ public synchronized void appendRequestResult(RequestResult requestResult) { } /** + * Gets a global event multi-caster that is triggered before sending a request. It allows event listeners to be + * dynamically added and removed. + * * @return the globalSendingRequestEventHandler */ public static StorageEventMultiCaster> getGlobalSendingRequestEventHandler() { @@ -259,6 +252,9 @@ public static StorageEventMultiCaster> getGlobalResponseReceivedEventHandler() { @@ -266,6 +262,9 @@ public static StorageEventMultiCaster> getGlobalRequestCompletedEventHandler() { @@ -273,6 +272,9 @@ public static StorageEventMultiCaster> getGlobalRetryingEventHandler() { @@ -280,6 +282,9 @@ public static StorageEventMultiCaster } /** + * Gets an event multi-caster that is triggered before sending a request. It allows event listeners to be + * dynamically added and removed. + * * @return the sendingRequestEventHandler */ public StorageEventMultiCaster> getSendingRequestEventHandler() { @@ -287,6 +292,9 @@ public StorageEventMultiCaster> getResponseReceivedEventHandler() { @@ -294,6 +302,9 @@ public StorageEventMultiCaster> getRequestCompletedEventHandler() { @@ -301,6 +312,9 @@ public StorageEventMultiCaster> getRetryingEventHandler() { @@ -308,13 +322,12 @@ public StorageEventMultiCaster> getRe } /** - * Initializes the OperationContext in order to begin processing a new operation. All operation specific information - * is erased. + * Reserved for internal use. Initializes the OperationContext in order to begin processing a new operation. All + * operation specific information is erased. */ public void initialize() { this.setClientTimeInMs(0); this.requestResults.clear(); - this.setCurrentRequestObject(null); } /** @@ -330,6 +343,8 @@ public boolean isLoggingEnabled() { } /** + * Set the client side trace ID. + * * @param clientRequestID * the clientRequestID to set */ @@ -338,6 +353,9 @@ public void setClientRequestID(final String clientRequestID) { } /** + * Reserved for internal use. Represents the operation latency, in milliseconds, from the client's perspective. This + * may include any potential retries. + * * @param clientTimeInMs * the clientTimeInMs to set */ @@ -345,18 +363,6 @@ public void setClientTimeInMs(final long clientTimeInMs) { this.clientTimeInMs = clientTimeInMs; } - /** - * Reserved for internal use. - * - * @param currentRequestObject - * the currentRequestObject to set - * @deprecated Deprecated as of 0.6.0. - */ - @Deprecated - public void setCurrentRequestObject(final HttpURLConnection currentRequestObject) { - this.currentRequestObject = currentRequestObject; - } - /** * Sets the {@link org.slf4j.Logger} for this operation. * @@ -368,6 +374,8 @@ public void setLogger(final org.slf4j.Logger logger) { } /** + * Sets any additional headers for the request, for example, for proxy or logging information. + * * @param userHeaders * the userHeaders to set */ @@ -386,6 +394,8 @@ public void setLoggingEnabled(boolean loggingEnabled) { } /** + * Sets a global event multi-caster that is triggered before sending a request. + * * @param globalSendingRequestEventHandler * the globalSendingRequestEventHandler to set */ @@ -395,6 +405,8 @@ public static void setGlobalSendingRequestEventHandler( } /** + * Sets a global event multi-caster that is triggered when a response is received. + * * @param globalResponseReceivedEventHandler * the globalResponseReceivedEventHandler to set */ @@ -404,6 +416,8 @@ public static void setGlobalResponseReceivedEventHandler( } /** + * Sets a global event multi-caster that is triggered when a request is completed. + * * @param globalRequestCompletedEventHandler * the globalRequestCompletedEventHandler to set */ @@ -413,6 +427,8 @@ public static void setGlobalRequestCompletedEventHandler( } /** + * Sets a global event multi-caster that is triggered when a request is retried. + * * @param globalRetryingEventHandler * the globalRetryingEventHandler to set */ @@ -422,6 +438,8 @@ public static void setGlobalRetryingEventHandler( } /** + * Sets an event multi-caster that is triggered before sending a request. + * * @param sendingRequestEventHandler * the sendingRequestEventHandler to set */ @@ -431,6 +449,8 @@ public void setSendingRequestEventHandler( } /** + * Sets an event multi-caster that is triggered when a response is received. + * * @param responseReceivedEventHandler * the responseReceivedEventHandler to set */ @@ -440,6 +460,8 @@ public void setResponseReceivedEventHandler( } /** + * Sets an event multi-caster that is triggered when a request is completed. + * * @param requestCompletedEventHandler * the requestCompletedEventHandler to set */ @@ -449,6 +471,8 @@ public void setRequestCompletedEventHandler( } /** + * Sets an event multi-caster that is triggered when a request is retried. + * * @param retryingEventHandler * the retryingEventHandler to set */ diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/Permissions.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/Permissions.java similarity index 97% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/Permissions.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/Permissions.java index bc1854d534eff..4471a784a2f36 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/Permissions.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/Permissions.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage; import java.util.HashMap; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RequestCompletedEvent.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/RequestCompletedEvent.java similarity index 54% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RequestCompletedEvent.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/RequestCompletedEvent.java index d8614b80820ea..d2e47a39f30d4 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RequestCompletedEvent.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/RequestCompletedEvent.java @@ -12,15 +12,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; - -import com.microsoft.windowsazure.storage.core.BaseEvent; +package com.microsoft.azure.storage; /** * Represents an event that is fired when a request is completed. */ public final class RequestCompletedEvent extends BaseEvent { + /** + * Creates an instance of the BaseEvent class that is fired when a request is completed. + * + * @param opContext + * An {@link OperationContext} object that 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. + * @param connectionObject + * Represents a connection object. Currently only java.net.HttpURLConnection is supported as + * a connection object. + * @param requestResult + * A {@link RequestResult} object that represents the current request result. + */ public RequestCompletedEvent(OperationContext opContext, Object connectionObject, RequestResult requestResult) { super(opContext, connectionObject, requestResult); } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RequestOptions.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/RequestOptions.java similarity index 69% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RequestOptions.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/RequestOptions.java index 35a832024aab4..67750c0a6ae3e 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RequestOptions.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/RequestOptions.java @@ -15,11 +15,11 @@ /** * */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import java.util.Date; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.core.Utility; /** * Represents the options to use while processing a given request. @@ -80,41 +80,39 @@ public RequestOptions(final RequestOptions other) { * * @param options * The input options to copy from when applying defaults - * @param client - * the service client to populate from */ - protected static final RequestOptions applyBaseDefaultsInternal(RequestOptions modifiedOptions, - final ServiceClient client) { - return applyBaseDefaultsInternal(modifiedOptions, client, true); + protected static final RequestOptions applyBaseDefaultsInternal(final RequestOptions modifiedOptions) { + Utility.assertNotNull("modifiedOptions", modifiedOptions); + if (modifiedOptions.getRetryPolicyFactory() == null) { + modifiedOptions.setRetryPolicyFactory(new RetryExponentialRetry()); + } + + if (modifiedOptions.getLocationMode() == null) { + modifiedOptions.setLocationMode(LocationMode.PRIMARY_ONLY); + } + + return modifiedOptions; } /** - * Populates the default timeout, retry policy, and location mode from client if they are null. - * - * @param options - * The input options to copy from when applying defaults - * @param client - * the service client to populate from - * @param setStartTime - * whether to initialize the startTimeInMs field, or not + * Populates any null fields in the first requestOptions object with values from the second requestOptions object. */ - protected static final RequestOptions applyBaseDefaultsInternal(RequestOptions modifiedOptions, - final ServiceClient client, final boolean setStartTime) { - Utility.assertNotNull("modifiedOptions", modifiedOptions); + protected static final RequestOptions populateRequestOptions(RequestOptions modifiedOptions, + final RequestOptions clientOptions, final boolean setStartTime) { if (modifiedOptions.getRetryPolicyFactory() == null) { - modifiedOptions.setRetryPolicyFactory(client.getRetryPolicyFactory()); + modifiedOptions.setRetryPolicyFactory(clientOptions.getRetryPolicyFactory()); } - if (modifiedOptions.getTimeoutIntervalInMs() == null) { - modifiedOptions.setTimeoutIntervalInMs(client.getTimeoutInMs()); + if (modifiedOptions.getLocationMode() == null) { + modifiedOptions.setLocationMode(clientOptions.getLocationMode()); } - if (modifiedOptions.getLocationMode() == null) { - modifiedOptions.setLocationMode(client.getLocationMode()); + if (modifiedOptions.getTimeoutIntervalInMs() == null) { + modifiedOptions.setTimeoutIntervalInMs(clientOptions.getTimeoutIntervalInMs()); } if (modifiedOptions.getMaximumExecutionTimeInMs() == null) { - modifiedOptions.setMaximumExecutionTimeInMs(client.getMaximumExecutionTimeInMs()); + modifiedOptions.setMaximumExecutionTimeInMs(clientOptions.getMaximumExecutionTimeInMs()); } if (modifiedOptions.getMaximumExecutionTimeInMs() != null @@ -127,7 +125,8 @@ protected static final RequestOptions applyBaseDefaultsInternal(RequestOptions m } /** - * Returns the retry policy to use for this request. + * Gets the retry policy to use for this request. For more information about the retry policy defaults, see + * {@link #setRetryPolicyFactory(RetryPolicyFactory)}. * * @return An {@link RetryPolicyFactory} object that represents the current retry policy. * @@ -141,7 +140,7 @@ public final RetryPolicyFactory getRetryPolicyFactory() { } /** - * Returns the timeout value for this request. For more information about the timeout, see + * Returns the timeout value for this request. For more information about the timeout defaults, see * {@link #setTimeoutIntervalInMs(Integer)}. * * @return The current timeout value, in milliseconds, for this request. @@ -151,7 +150,8 @@ public final Integer getTimeoutIntervalInMs() { } /** - * Gets the default location mode for this request. + * Gets the default location mode for this request. For more information about location mode, see + * {@link #setLocationMode(LocationMode)}. * * @return A {@link LocationMode} object that represents the location mode for this request. */ @@ -160,7 +160,7 @@ public final LocationMode getLocationMode() { } /** - * Returns the maximum execution time for this request. For more information about maximum execution time, see + * Gets the maximum execution time for this request. For more information about maximum execution time defaults, see * {@link #setMaximumExecutionTimeInMs(Integer)}. * * @return The current maximum execution time, in milliseconds, for this request. @@ -170,6 +170,8 @@ public Integer getMaximumExecutionTimeInMs() { } /** + * RESERVED FOR INTERNAL USE. + * * Returns the time at which this operation expires. This is computed by adding the time the operation begins and * the maximum execution time and will be null if maximum execution time is null. For more information about maximum * execution time, see {@link #setMaximumExecutionTimeInMs(Integer)}. @@ -182,6 +184,11 @@ public Long getOperationExpiryTimeInMs() { /** * Sets the RetryPolicyFactory object to use for this request. + *

+ * The default RetryPolicyFactory is set in the client and is by default {@link RetryExponentialRetry}. You can + * change the RetryPolicyFactory on this request by setting this property. You can also change the value on the + * {@link ServiceClient#getDefaultRequestOptions()} object so that all subsequent requests made via the service + * client will use that RetryPolicyFactory. * * @param retryPolicyFactory * the RetryPolicyFactory object to use when making service requests. @@ -201,13 +208,11 @@ public final void setRetryPolicyFactory(final RetryPolicyFactory retryPolicyFact * The server timeout interval begins at the time that the complete request has been received by the service, and * the server begins processing the response. If the timeout interval elapses before the response is returned to the * client, the operation times out. The timeout interval resets with each retry, if the request is retried. - * - * The default timeout interval for a request is the timeout set in the client (by default 90 seconds). You can - * change the timeout interval on this request by setting this property. You can also change the value at - * {@link ServiceClient#setTimeoutInMs(int)} so that all subsequent requests made via the service client will use - * the new timeout interval. - * - * If you are downloading a large blob, you should increase the value of the timeout beyond the default value. + *

+ * The default server timeout is set in the client and is by default null, indicating no server timeout. You can + * change the server timeout on this request by setting this property. You can also change the value on the + * {@link ServiceClient#getDefaultRequestOptions()} object so that all subsequent requests made via the service + * client will use that server timeout. * * @param timeoutInMs * The timeout, in milliseconds, to use for this request. @@ -218,6 +223,11 @@ public final void setTimeoutIntervalInMs(final Integer timeoutIntervalInMs) { /** * Sets the {@link LocationMode} for this request. + *

+ * The default {@link LocationMode} is set in the client and is by default {@link LocationMode#PRIMARY_ONLY}. You + * can change the {@link LocationMode} on this request by setting this property. You can also change the value on + * the {@link ServiceClient#getDefaultRequestOptions()} object so that all subsequent requests made via the service + * client will use that {@link LocationMode}. * * @param locationMode * the locationMode to set @@ -233,10 +243,10 @@ public final void setLocationMode(final LocationMode locationMode) { * execution time is checked intermittently while uploading data, downloading data, and before executing retries. * The service will continue to upload, download, and retry until the maximum execution time is reached. At that * time, any partial uploads or downloads will be cancelled and an exception will be thrown. - * + *

* The default maximum execution is set in the client and is by default null, indicating no maximum time. You can - * change the maximum execution time on this request by setting this property. You can also change the value at - * {@link ServiceClient#setMaximumExecutionTimeInMs(Integer)} so that all subsequent requests made via the service + * change the maximum execution time on this request by setting this property. You can also change the value on the + * {@link ServiceClient#getDefaultRequestOptions()} object so that all subsequent requests made via the service * client will use the maximum execution time. * * @param maximumExecutionTimeInMs @@ -247,6 +257,12 @@ public void setMaximumExecutionTimeInMs(Integer maximumExecutionTimeInMs) { } /** + * RESERVED FOR INTERNAL USE. + * + * Returns the time at which this operation expires. This is computed by adding the time the operation begins and + * the maximum execution time and will be null if maximum execution time is null. For more information about maximum + * execution time, see {@link #setMaximumExecutionTimeInMs(Integer)}. + * * @param operationExpiryTime * the operationExpiryTime to set */ diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RequestResult.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/RequestResult.java similarity index 99% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RequestResult.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/RequestResult.java index 5b127c19b96a6..0cca268a5cda5 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RequestResult.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/RequestResult.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import java.util.Date; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ResponseReceivedEvent.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/ResponseReceivedEvent.java similarity index 54% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ResponseReceivedEvent.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/ResponseReceivedEvent.java index 695cb49af68f8..ae0d1d8bd7d98 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ResponseReceivedEvent.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/ResponseReceivedEvent.java @@ -12,15 +12,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; - -import com.microsoft.windowsazure.storage.core.BaseEvent; +package com.microsoft.azure.storage; /** * Represents an event that is fired when a response is received. */ public final class ResponseReceivedEvent extends BaseEvent { + /** + * Creates an instance of the BaseEvent class that is fired when a response is received. + * + * @param opContext + * An {@link OperationContext} object that 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. + * @param connectionObject + * Represents a connection object. Currently only java.net.HttpURLConnection is supported as + * a connection object. + * @param requestResult + * A {@link RequestResult} object that represents the current request result. + */ public ResponseReceivedEvent(OperationContext opContext, Object connectionObject, RequestResult requestResult) { super(opContext, connectionObject, requestResult); } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ResultContinuation.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/ResultContinuation.java similarity index 76% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ResultContinuation.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/ResultContinuation.java index 630e6e3ee60e2..6a38a9d2007a3 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ResultContinuation.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/ResultContinuation.java @@ -12,9 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; -import com.microsoft.windowsazure.storage.blob.CloudBlobDirectory; +import com.microsoft.azure.storage.blob.CloudBlobDirectory; /** * Represents a continuation token for listing operations. Continuation tokens are used in methods that return a @@ -27,27 +27,27 @@ public final class ResultContinuation { private String nextMarker; /** - * Gets or sets the NextPartitionKey for TableServiceEntity enumeration operations. + * Represents the next partition key for TableServiceEntity enumeration operations. */ private String nextPartitionKey; /** - * Gets or sets the NextRowKey for TableServiceEntity enumeration operations. + * Represents the next row key for TableServiceEntity enumeration operations. */ private String nextRowKey; /** - * Gets or sets the NextTableName for Table enumeration operations. + * Represents the next table name for Table enumeration operations. */ private String nextTableName; /** - * Gets or sets the type of the continuation token. + * Represents the type of the continuation token. */ private ResultContinuationType continuationType; /** - * Gets the location that the token applies to. + * Represents the location that the token applies to. */ private StorageLocation targetLocation; @@ -59,6 +59,8 @@ public ResultContinuation() { } /** + * Gets the type of the continuation token. + * * @return the continuationType */ public ResultContinuationType getContinuationType() { @@ -66,6 +68,8 @@ public ResultContinuationType getContinuationType() { } /** + * Gets the next marker for continuing results of listing operations. + * * @return the nextMarker */ public String getNextMarker() { @@ -73,6 +77,8 @@ public String getNextMarker() { } /** + * Gets the next partition key for TableServiceEntity enumeration operations. + * * @return the nextPartitionKey */ public String getNextPartitionKey() { @@ -80,6 +86,8 @@ public String getNextPartitionKey() { } /** + * Gets the next row key for TableServiceEntity enumeration operations. + * * @return the nextRowKey */ public String getNextRowKey() { @@ -87,6 +95,8 @@ public String getNextRowKey() { } /** + * Gets the next table name for Table enumeration operations. + * * @return the nextTableName */ public String getNextTableName() { @@ -94,6 +104,8 @@ public String getNextTableName() { } /** + * Gets the location that the token applies to. + * * @return the targetLocation */ public StorageLocation getTargetLocation() { @@ -111,6 +123,8 @@ public boolean hasContinuation() { } /** + * Sets the type of the continuation token. + * * @param continuationType * the continuationType to set */ @@ -119,6 +133,8 @@ public void setContinuationType(final ResultContinuationType continuationType) { } /** + * Sets the next marker for continuing results of listing operations. + * * @param nextMarker * the nextMarker to set */ @@ -127,6 +143,8 @@ public void setNextMarker(final String nextMarker) { } /** + * Sets the next partition key for TableServiceEntity enumeration operations. + * * @param nextPartitionKey * the nextPartitionKey to set */ @@ -135,6 +153,8 @@ public void setNextPartitionKey(final String nextPartitionKey) { } /** + * Sets the next row key for TableServiceEntity enumeration operations. + * * @param nextRowKey * the nextRowKey to set */ @@ -143,6 +163,8 @@ public void setNextRowKey(final String nextRowKey) { } /** + * Sets the next table name for Table enumeration operations. + * * @param nextTableName * the nextTableName to set */ @@ -151,6 +173,8 @@ public void setNextTableName(final String nextTableName) { } /** + * Sets the location that the token applies to. + * * @param targetLocation * the targetLocation to set */ diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ResultContinuationType.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/ResultContinuationType.java similarity index 96% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ResultContinuationType.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/ResultContinuationType.java index 8f51f1bb31f81..0304caa4be9c1 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ResultContinuationType.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/ResultContinuationType.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; /** * Specifies the type of a continuation token. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ResultSegment.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/ResultSegment.java similarity index 98% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ResultSegment.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/ResultSegment.java index 8cbd59ba7fd81..f652c2adab47b 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ResultSegment.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/ResultSegment.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import java.util.ArrayList; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryContext.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/RetryContext.java similarity index 84% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryContext.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/RetryContext.java index 9677c9efb572a..9a39951d2c7e6 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryContext.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/RetryContext.java @@ -12,9 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.core.Utility; /** * Represents the context for a retry of a request made against the storage services. @@ -31,14 +31,14 @@ public final class RetryContext { private final LocationMode locationMode; /** - * Gets the number of retries for the given operation. + * The number of retries for the given operation. */ - public final int currentRetryCount; + private final int currentRetryCount; /** - * Gets the last request's results. + * The last request's results. */ - public final RequestResult lastRequestResult; + private final RequestResult lastRequestResult; public RetryContext(int currentRetryCount, RequestResult lastRequestResult, StorageLocation nextLocation, LocationMode locationMode) { @@ -49,6 +49,8 @@ public RetryContext(int currentRetryCount, RequestResult lastRequestResult, Stor } /** + * Gets the number of retries for the given operation. + * * @return the currentRetryCount */ public int getCurrentRetryCount() { @@ -56,6 +58,8 @@ public int getCurrentRetryCount() { } /** + * Gets the last request's results. + * * @return the lastRequestResult */ public RequestResult getLastRequestResult() { @@ -63,6 +67,8 @@ public RequestResult getLastRequestResult() { } /** + * Gets the location mode for subsequent retries. + * * @return the locationMode */ public LocationMode getLocationMode() { @@ -70,6 +76,8 @@ public LocationMode getLocationMode() { } /** + * Gets the location that the next retry should target. + * * @return the nextLocation */ public StorageLocation getNextLocation() { diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryExponentialRetry.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/RetryExponentialRetry.java similarity index 96% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryExponentialRetry.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/RetryExponentialRetry.java index f0949a0501fe5..bc6569f2c1849 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryExponentialRetry.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/RetryExponentialRetry.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import java.net.HttpURLConnection; import java.util.Random; @@ -21,8 +21,8 @@ * Represents a retry policy that performs a specified number of retries, using a randomized exponential backoff scheme * to determine the interval between retries. * - * This class extends the {@link com.microsoft.windowsazure.storage.RetryPolicy} class and implements the - * {@link com.microsoft.windowsazure.storage.RetryPolicyFactory} interface. + * This class extends the {@link com.microsoft.azure.storage.RetryPolicy} class and implements the + * {@link com.microsoft.azure.storage.RetryPolicyFactory} interface. */ public final class RetryExponentialRetry extends RetryPolicy implements RetryPolicyFactory { diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryInfo.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/RetryInfo.java similarity index 83% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryInfo.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/RetryInfo.java index b93473056b5ac..447f44ad226d0 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryInfo.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/RetryInfo.java @@ -12,9 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.core.Utility; /** * Represents the context for a retry of a request made against the storage services. @@ -22,17 +22,17 @@ public class RetryInfo { /** - * Gets the location that the next retry should target. + * The location that the next retry should target. */ private StorageLocation targetLocation; /** - * Gets or sets the location mode for subsequent retries. + * The location mode for subsequent retries. */ private LocationMode updatedLocationMode; /** - * Gets the interval in ms until the next retry. The minimum back-off interval is 3 seconds. + * The interval in ms until the next retry. The minimum back-off interval is 3 seconds. */ private int retryInterval = 3000; @@ -57,6 +57,8 @@ public RetryInfo(RetryContext retryContext) { } /** + * Gets the interval in ms until the next retry. The minimum back-off interval is 3 seconds. + * * @return the retryInterval */ public int getRetryInterval() { @@ -64,6 +66,8 @@ public int getRetryInterval() { } /** + * Gets the location that the next retry should target. + * * @return the targetLocation */ public final StorageLocation getTargetLocation() { @@ -71,6 +75,8 @@ public final StorageLocation getTargetLocation() { } /** + * Gets the location mode for subsequent retries. + * * @return the updatedLocationMode */ public LocationMode getUpdatedLocationMode() { @@ -78,6 +84,8 @@ public LocationMode getUpdatedLocationMode() { } /** + * Sets the interval in ms until the next retry. The minimum back-off interval is 3 seconds. + * * @param retryInterval * the retryInterval to set */ @@ -86,6 +94,8 @@ public void setRetryInterval(int retryInterval) { } /** + * Sets the location that the next retry should target. + * * @param targetLocation * the targetLocation to set */ @@ -94,6 +104,8 @@ public void setTargetLocation(StorageLocation targetLocation) { } /** + * Sets the location mode for subsequent retries. + * * @param updatedLocationMode * the updatedLocationMode to set */ diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryLinearRetry.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/RetryLinearRetry.java similarity index 98% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryLinearRetry.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/RetryLinearRetry.java index 3830494f2e1ed..3c32552306452 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryLinearRetry.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/RetryLinearRetry.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import java.net.HttpURLConnection; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryNoRetry.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/RetryNoRetry.java similarity index 92% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryNoRetry.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/RetryNoRetry.java index dbf313f095f41..de66bf8e6902b 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryNoRetry.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/RetryNoRetry.java @@ -12,13 +12,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; /** * Represents a retry policy that performs no retries. * - * This class extends the {@link com.microsoft.windowsazure.storage.RetryPolicy} class and implements the - * {@link com.microsoft.windowsazure.storage.RetryPolicyFactory} interface. + * This class extends the {@link com.microsoft.azure.storage.RetryPolicy} class and implements the + * {@link com.microsoft.azure.storage.RetryPolicyFactory} interface. */ public final class RetryNoRetry extends RetryPolicy implements RetryPolicyFactory { diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryPolicy.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/RetryPolicy.java similarity index 98% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryPolicy.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/RetryPolicy.java index 48000279bbeb4..80de93f3f101c 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryPolicy.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/RetryPolicy.java @@ -15,12 +15,12 @@ /** * */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import java.net.HttpURLConnection; import java.util.Date; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.core.Utility; /** * Abstract class that represents a retry policy. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryPolicyFactory.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/RetryPolicyFactory.java similarity index 96% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryPolicyFactory.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/RetryPolicyFactory.java index 2e1b1c4ac53af..16c22dce7f3d3 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryPolicyFactory.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/RetryPolicyFactory.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; /** * Represents a retry policy factory that creates a new {@link RetryPolicy} object per transaction. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryingEvent.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/RetryingEvent.java similarity index 87% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryingEvent.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/RetryingEvent.java index a2df7f7b08745..7c44673cd29b6 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/RetryingEvent.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/RetryingEvent.java @@ -12,9 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; - -import com.microsoft.windowsazure.storage.core.BaseEvent; +package com.microsoft.azure.storage; /** * Represents an event that is fired when a request is retried. @@ -28,7 +26,7 @@ public final class RetryingEvent extends BaseEvent { private final RetryContext retryContext; /** - * Creates an instance of the BaseEvent class. + * Creates an instance of the BaseEvent class which is fired when a request is retried. * * @param opContext * An {@link OperationContext} object that represents the context for the current operation. This object @@ -49,6 +47,9 @@ public RetryingEvent(OperationContext opContext, Object connectionObject, Reques } /** + * Gets the context for a retry of a request made against the storage services. Includes current retry count, + * location mode, and next location. + * * @return the retryCount */ public RetryContext getRetryContext() { diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/SendingRequestEvent.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/SendingRequestEvent.java similarity index 52% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/SendingRequestEvent.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/SendingRequestEvent.java index 5a0486d75b6db..083e26d8611dd 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/SendingRequestEvent.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/SendingRequestEvent.java @@ -12,15 +12,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; - -import com.microsoft.windowsazure.storage.core.BaseEvent; +package com.microsoft.azure.storage; /** - * Represents an event that is fired when before sending a request. + * Represents an event that is fired when before sending a request. The connection object is not yet live. */ public final class SendingRequestEvent extends BaseEvent { + /** + * Creates an instance of the BaseEvent class that is fired when before sending a request. + * + * @param opContext + * An {@link OperationContext} object that 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. + * @param connectionObject + * Represents a connection object. Currently only java.net.HttpURLConnection is supported as + * a connection object. + * @param requestResult + * A {@link RequestResult} object that represents the current request result. + */ public SendingRequestEvent(OperationContext opContext, Object connectionObject, RequestResult requestResult) { super(opContext, connectionObject, requestResult); } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ServiceClient.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/ServiceClient.java similarity index 79% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ServiceClient.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/ServiceClient.java index a07e3cf3a1854..b36d1dc8f1006 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ServiceClient.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/ServiceClient.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -21,15 +21,15 @@ import javax.xml.stream.XMLStreamException; -import com.microsoft.windowsazure.storage.core.BaseRequest; -import com.microsoft.windowsazure.storage.core.RequestLocationMode; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.StorageRequest; -import com.microsoft.windowsazure.storage.core.StreamMd5AndLength; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.core.BaseRequest; +import com.microsoft.azure.storage.core.RequestLocationMode; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.StorageRequest; +import com.microsoft.azure.storage.core.StreamMd5AndLength; +import com.microsoft.azure.storage.core.Utility; /** - * Reserved for internal use. Provides a client for accessing the Windows Azure Storage service. + * Reserved for internal use. Provides a client for accessing the Microsoft Azure Storage service. */ public abstract class ServiceClient { @@ -38,11 +38,6 @@ public abstract class ServiceClient { */ private StorageUri storageUri; - /** - * Gets or sets the default location mode for requests made via the service client. - */ - private LocationMode locationMode; - /** * Holds the StorageCredentials associated with this Service Client. */ @@ -53,48 +48,11 @@ public abstract class ServiceClient { */ private boolean usePathStyleUris; - /** - * Holds the default retry policy for requests made via the service client to set. - */ - protected RetryPolicyFactory retryPolicyFactory = new RetryExponentialRetry(); - - /** - * Holds the default server and client timeout for requests made by the service client. - */ - protected int timeoutInMs = Constants.DEFAULT_TIMEOUT_IN_MS; - - /** - * The maximum execution time, in milliseconds, across all potential retries. - */ - private Integer maximumExecutionTimeInMs; - /** * Holds the AuthenticationScheme associated with this Service Client. */ protected AuthenticationScheme authenticationScheme = AuthenticationScheme.SHAREDKEYFULL; - /** - * Creates an instance of the ServiceClient class using the specified service endpoint. - * - * @param baseUri - * A java.net.URI object that represents the service endpoint used to create the client. - */ - public ServiceClient(final URI baseUri) { - this(new StorageUri(baseUri), null /* credentials */); - } - - /** - * Creates an instance of the ServiceClient class using the specified service endpoint. - * - * @param baseUri - * A java.net.URI object that represents the service endpoint used to create the client. - * @param credentials - * A {@link StorageCredentials} object that represents the account credentials. - */ - public ServiceClient(final URI baseUri, final StorageCredentials credentials) { - this(new StorageUri(baseUri), credentials); - } - /** * Creates an instance of the ServiceClient class using the specified service endpoint and account * credentials. @@ -105,33 +63,26 @@ public ServiceClient(final URI baseUri, final StorageCredentials credentials) { * @param credentials * A {@link StorageCredentials} object that represents the account credentials. */ - public ServiceClient(final StorageUri storageUri, final StorageCredentials credentials) { + protected ServiceClient(final StorageUri storageUri, final StorageCredentials credentials) { Utility.assertNotNull("baseUri", storageUri); if (!storageUri.isAbsolute()) { throw new IllegalArgumentException(String.format(SR.RELATIVE_ADDRESS_NOT_PERMITTED, storageUri)); } this.credentials = credentials == null ? StorageCredentialsAnonymous.ANONYMOUS : credentials; - - this.retryPolicyFactory = new RetryExponentialRetry(); - this.timeoutInMs = Constants.DEFAULT_TIMEOUT_IN_MS; - - this.usePathStyleUris = Utility.determinePathStyleFromUri(storageUri.getPrimaryUri(), - this.credentials.getAccountName()); + this.usePathStyleUris = Utility.determinePathStyleFromUri(storageUri.getPrimaryUri()); this.storageUri = storageUri; - this.locationMode = LocationMode.PRIMARY_ONLY; } protected StorageRequest downloadServicePropertiesImpl( - final RequestOptions options, final boolean signAsTable) throws StorageException { + final RequestOptions options, final boolean signAsTable) { final StorageRequest getRequest = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(ServiceClient client, Void parentObject, OperationContext context) throws Exception { - return BaseRequest.getServiceProperties(client.getEndpoint(), options.getTimeoutIntervalInMs(), null, - context); + return BaseRequest.getServiceProperties(client.getEndpoint(), options, null, context); } @Override @@ -158,8 +109,7 @@ public ServiceProperties preProcessResponse(Void parentObject, ServiceClient cli @Override public ServiceProperties postProcessResponse(HttpURLConnection connection, Void parentObject, ServiceClient client, OperationContext context, ServiceProperties storageObject) throws Exception { - return ServicePropertiesDeserializer.readServicePropertiesFromStream(connection.getInputStream(), - context); + return ServicePropertiesHandler.readServicePropertiesFromStream(connection.getInputStream()); } }; @@ -167,7 +117,7 @@ public ServiceProperties postProcessResponse(HttpURLConnection connection, Void } protected StorageRequest getServiceStatsImpl(final RequestOptions options, - final boolean signAsTable) throws StorageException { + final boolean signAsTable) { final StorageRequest getRequest = new StorageRequest( options, this.getStorageUri()) { @@ -180,8 +130,8 @@ public void setRequestLocationMode() { @Override public HttpURLConnection buildRequest(ServiceClient client, Void parentObject, OperationContext context) throws Exception { - return BaseRequest.getServiceStats(client.getStorageUri().getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), null, context); + return BaseRequest.getServiceStats(client.getStorageUri().getUri(this.getCurrentLocation()), options, + null, context); } @Override @@ -208,7 +158,7 @@ public ServiceStats preProcessResponse(Void parentObject, ServiceClient client, @Override public ServiceStats postProcessResponse(HttpURLConnection connection, Void parentObject, ServiceClient client, OperationContext context, ServiceStats storageObject) throws Exception { - return ServiceStatsDeserializer.readServiceStatsFromStream(connection.getInputStream(), context); + return ServiceStatsHandler.readServiceStatsFromStream(connection.getInputStream()); } }; @@ -244,29 +194,6 @@ public final URI getEndpoint() { return this.storageUri.getPrimaryUri(); } - /** - * Gets the default location mode for requests made via the service client. - * - * @return A {@link LocationMode} object that represents the default location mode for the service client. - */ - public final LocationMode getLocationMode() { - return this.locationMode; - } - - /** - * Returns the retry policy currently in effect for this Blob service client. - * - * @return An {@link RetryPolicyFactory} object that represents the current retry policy. - * - * @see RetryPolicy - * @see RetryExponentialRetry - * @see RetryLinearRetry - * @see RetryNoRetry - */ - public final RetryPolicyFactory getRetryPolicyFactory() { - return this.retryPolicyFactory; - } - /** * Returns the list of URIs for all locations. * @@ -276,30 +203,10 @@ public final StorageUri getStorageUri() { return this.storageUri; } - /** - * Returns the timeout value for requests made to the service. For more information about the timeout, see - * {@link #setTimeoutInMs}. - * - * @return The current timeout value, in milliseconds, for requests made to the storage service. - */ - public final int getTimeoutInMs() { - return this.timeoutInMs; - } - - /** - * Returns the maximum execution time, in milliseconds, across all potential retries. For more information about - * maximum execution time, see {@link #setMaximumExecutionTimeInMs(Integer)}. - * - * @return The maximum execution time, in milliseconds, for requests made to the storage service. - */ - public Integer getMaximumExecutionTimeInMs() { - return maximumExecutionTimeInMs; - } - /** * @return the usePathStyleUris */ - public final boolean isUsePathStyleUris() { + protected boolean isUsePathStyleUris() { return this.usePathStyleUris; } @@ -314,16 +221,6 @@ protected final void setCredentials(final StorageCredentials credentials) { this.credentials = credentials; } - /** - * Sets the default {@link LocationMode} for requests made via the service client. - * - * @param locationMode - * the locationMode to set - */ - public void setLocationMode(LocationMode locationMode) { - this.locationMode = locationMode; - } - /** * Sets the list of URIs for all locations. * @@ -331,8 +228,7 @@ public void setLocationMode(LocationMode locationMode) { * A StorageUri object that represents the list of URIs for all locations. */ protected final void setStorageUri(final StorageUri storageUri) { - this.usePathStyleUris = Utility.determinePathStyleFromUri(storageUri.getPrimaryUri(), - this.credentials.getAccountName()); + this.usePathStyleUris = Utility.determinePathStyleFromUri(storageUri.getPrimaryUri()); this.storageUri = storageUri; } @@ -348,57 +244,6 @@ public final void setAuthenticationScheme(final AuthenticationScheme scheme) { this.authenticationScheme = scheme; } - /** - * Sets the RetryPolicyFactory object to use when making service requests. - * - * @param retryPolicyFactory - * the RetryPolicyFactory object to use when making service requests. - */ - public void setRetryPolicyFactory(final RetryPolicyFactory retryPolicyFactory) { - this.retryPolicyFactory = retryPolicyFactory; - } - - /** - * Sets the timeout to use when making requests to the storage service. - *

- * The server timeout interval begins at the time that the complete request has been received by the service, and - * the server begins processing the response. If the timeout interval elapses before the response is returned to the - * client, the operation times out. The timeout interval resets with each retry, if the request is retried. - * - * The default timeout interval for a request made via the service client is 90 seconds. You can change this value - * on the service client by setting this property, so that all subsequent requests made via the service client will - * use the new timeout interval. You can also change this value for an individual request, by setting the - * {@link RequestOptions#setTimeoutIntervalInMs(Integer)} property. - * - * If you are downloading a large blob, you should increase the value of the timeout beyond the default value. - * - * @param timeoutInMs - * The timeout, in milliseconds, to use when making requests to the storage service. - */ - public final void setTimeoutInMs(final int timeoutInMs) { - this.timeoutInMs = timeoutInMs; - } - - /** - * Sets the maximum execution time to use when making requests to the storage service. - *

- * The maximum execution time interval begins at the time that the client begins building the request. The maximum - * execution time is checked intermittently while uploading data, downloading data, and before executing retries. - * The service will continue to upload, download, and retry until the maximum execution time is reached. At that - * time, any partial uploads or downloads will be cancelled and an exception will be thrown. - * - * The default maximum execution time is null, indicating no maximum time. You can change this value on the service - * client by setting this property, so that all subsequent requests made via the service client will use the new - * maximum execution time. You can also change this value for an individual request, by setting the - * {@link RequestOptions#setMaximumExecutionTimeInMs(Integer)} property. - * - * @param maximumExecutionTimeInMs - * The maximum execution time, in milliseconds, to use when making service requests. - */ - public void setMaximumExecutionTimeInMs(Integer maximumExecutionTimeInMs) { - this.maximumExecutionTimeInMs = maximumExecutionTimeInMs; - } - protected StorageRequest uploadServicePropertiesImpl(final ServiceProperties properties, final RequestOptions options, final OperationContext opContext, final boolean signAsTable) throws StorageException { @@ -417,8 +262,7 @@ public HttpURLConnection buildRequest(ServiceClient client, Void parentObject, O throws Exception { this.setSendStream(sendStream); this.setLength(descriptor.getLength()); - return BaseRequest.setServiceProperties(client.getEndpoint(), options.getTimeoutIntervalInMs(), - null, context); + return BaseRequest.setServiceProperties(client.getEndpoint(), options, null, context); } @Override @@ -473,4 +317,136 @@ public void recoveryAction(OperationContext context) throws IOException { throw translatedException; } } + + /** + * Gets the default location mode for requests made via the service client. + * + * @return A {@link LocationMode} object that represents the default location mode for the service client. + * + * @deprecated use {@link #getDefaultRequestOptions().getLocationMode()} instead. + */ + @Deprecated + public final LocationMode getLocationMode() { + return this.getDefaultRequestOptions().getLocationMode(); + } + + /** + * Returns the retry policy currently in effect for this service client. + * + * @return An {@link RetryPolicyFactory} object that represents the current retry policy. + * + * @see RetryPolicy + * @see RetryExponentialRetry + * @see RetryLinearRetry + * @see RetryNoRetry + * + * @deprecated use {@link #getDefaultRequestOptions().getRetryPolicyFactory()} instead. + */ + @Deprecated + public final RetryPolicyFactory getRetryPolicyFactory() { + return this.getDefaultRequestOptions().getRetryPolicyFactory(); + } + + /** + * Returns the timeout value for requests made to the service. For more information about the timeout, see + * {@link #setTimeoutInMs}. + * + * @return The current timeout value, in milliseconds, for requests made to the storage service. + * + * @deprecated use {@link #getDefaultRequestOptions().getTimeoutIntervalInMs()} instead. + */ + @Deprecated + public final int getTimeoutInMs() { + return this.getDefaultRequestOptions().getTimeoutIntervalInMs(); + } + + /** + * Returns the maximum execution time, in milliseconds, across all potential retries. For more information about + * maximum execution time, see {@link #setMaximumExecutionTimeInMs(Integer)}. + * + * @return The maximum execution time, in milliseconds, for requests made to the storage service. + * + * @deprecated use {@link #getDefaultRequestOptions().getMaximumExecutionTimeInMs()} instead. + */ + @Deprecated + public Integer getMaximumExecutionTimeInMs() { + return this.getDefaultRequestOptions().getMaximumExecutionTimeInMs(); + } + + /** + * Sets the default {@link LocationMode} for requests made via the service client. + * + * @param locationMode + * the locationMode to set + * + * @deprecated use {@link #getDefaultRequestOptions().setLocationMode()} instead. + */ + @Deprecated + public void setLocationMode(LocationMode locationMode) { + this.getDefaultRequestOptions().setLocationMode(locationMode); + } + + /** + * Sets the RetryPolicyFactory object to use when making service requests. + * + * @param retryPolicyFactory + * the RetryPolicyFactory object to use when making service requests. + * + * @deprecated use {@link #getDefaultRequestOptions().setRetryPolicyFactory()} instead. + */ + @Deprecated + public void setRetryPolicyFactory(final RetryPolicyFactory retryPolicyFactory) { + this.getDefaultRequestOptions().setRetryPolicyFactory(retryPolicyFactory); + } + + /** + * Sets the timeout to use when making requests to the storage service. + *

+ * The server timeout interval begins at the time that the complete request has been received by the service, and + * the server begins processing the response. If the timeout interval elapses before the response is returned to the + * client, the operation times out. The timeout interval resets with each retry, if the request is retried. + * + * You can change this value on the service client by setting this property, so that all subsequent requests made + * via the service client will use the new timeout interval. You can also change this value for an individual + * request, by setting the {@link RequestOptions#setTimeoutIntervalInMs(Integer)} property. + * + * @param timeoutInMs + * The timeout, in milliseconds, to use when making requests to the storage service. + * + * @deprecated use {@link #getDefaultRequestOptions().setTimeoutIntervalInMs()} instead. + */ + @Deprecated + public final void setTimeoutInMs(final int timeoutInMs) { + this.getDefaultRequestOptions().setTimeoutIntervalInMs(timeoutInMs); + } + + /** + * Sets the maximum execution time to use when making requests to the storage service. + *

+ * The maximum execution time interval begins at the time that the client begins building the request. The maximum + * execution time is checked intermittently while uploading data, downloading data, and before executing retries. + * The service will continue to upload, download, and retry until the maximum execution time is reached. At that + * time, any partial uploads or downloads will be cancelled and an exception will be thrown. + * + * The default maximum execution time is null, indicating no maximum time. You can change this value on the service + * client by setting this property, so that all subsequent requests made via the service client will use the new + * maximum execution time. You can also change this value for an individual request, by setting the + * {@link RequestOptions#setMaximumExecutionTimeInMs(Integer)} property. + * + * @param maximumExecutionTimeInMs + * The maximum execution time, in milliseconds, to use when making service requests. + * + * @deprecated use {@link #getDefaultRequestOptions().setMaximumExecutionTimeInMs()} instead. + */ + @Deprecated + public void setMaximumExecutionTimeInMs(Integer maximumExecutionTimeInMs) { + this.getDefaultRequestOptions().setMaximumExecutionTimeInMs(maximumExecutionTimeInMs); + } + + /** + * Gets the {@link RequestOptions} that is used for requests associated with this ServiceClient + * + * @return The {@link RequestOptions} object containing the values used by this ServiceClient + */ + public abstract RequestOptions getDefaultRequestOptions(); } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ServiceProperties.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/ServiceProperties.java similarity index 77% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ServiceProperties.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/ServiceProperties.java index 966a4587d6ba2..e1c22a318d820 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ServiceProperties.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/ServiceProperties.java @@ -12,8 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; - +package com.microsoft.azure.storage; /** * Represents the analytics properties for the service. @@ -57,7 +56,7 @@ public ServiceProperties() { } /** - * Get the logging properties + * Gets the logging properties. * * @return the logging */ @@ -66,7 +65,7 @@ public LoggingProperties getLogging() { } /** - * Set the logging properties + * Sets the logging properties. * * @param logging */ @@ -75,29 +74,7 @@ public void setLogging(final LoggingProperties logging) { } /** - * Get the metrics properties - * - * @deprecated use {@link #getHourMetrics()} instead. - * @return the hour metrics - */ - @Deprecated - public MetricsProperties getMetrics() { - return this.hourMetrics; - } - - /** - * Set the metrics properties - * - * @deprecated use {@link #setHourMetrics()} instead. - * @param metrics - */ - @Deprecated - public void setMetrics(final MetricsProperties metrics) { - this.hourMetrics = metrics; - } - - /** - * Get the hour metrics properties + * Gets the hour metrics properties. * * @return the hour metrics */ @@ -106,7 +83,7 @@ public MetricsProperties getHourMetrics() { } /** - * Set the hour metrics properties + * Sets the hour metrics properties. * * @param metrics */ @@ -115,7 +92,7 @@ public void setHourMetrics(final MetricsProperties metrics) { } /** - * Get the minute metrics properties + * Gets the minute metrics properties. * * @return the minute metrics */ @@ -124,7 +101,7 @@ public MetricsProperties getMinuteMetrics() { } /** - * Set the minute metrics properties + * Sets the minute metrics properties. * * @param metrics */ @@ -133,7 +110,7 @@ public void setMinuteMetrics(final MetricsProperties metrics) { } /** - * Get the CORS properties + * Gets the Cross Origin Resource Sharing (CORS) properties. * * @return the CORS properties */ @@ -142,7 +119,7 @@ public CorsProperties getCors() { } /** - * Set the CORS properties + * Sets the Cross Origin Resource Sharing (CORS) properties. * * @param CORS */ @@ -151,7 +128,7 @@ public void setCors(final CorsProperties cors) { } /** - * Get default service version + * Gets default service version. * * @return the defaultServiceVersion */ @@ -160,7 +137,7 @@ public String getDefaultServiceVersion() { } /** - * Set default service version + * Sets default service version. * * @param defaultServiceVersion */ diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/ServicePropertiesHandler.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/ServicePropertiesHandler.java new file mode 100644 index 0000000000000..ecb9d92cf4e25 --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/ServicePropertiesHandler.java @@ -0,0 +1,242 @@ +/** + * 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; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.Stack; +import java.util.StringTokenizer; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; + +/** + * RESERVED FOR INTERNAL USE. A class used to deserialize a service properties. + */ +final class ServicePropertiesHandler extends DefaultHandler { + + private final Stack elementStack = new Stack(); + private StringBuilder bld = new StringBuilder(); + + private final ServiceProperties props = new ServiceProperties(); + + private CorsRule rule = new CorsRule(); + private boolean retentionPolicyEnabled; + private int retentionPolicyDays; + + /** + * Parses the {@link ServiceProperties} from the given XML stream. + * + * @param stream + * @throws IOException + * @throws SAXException + * @throws ParserConfigurationException + */ + public static ServiceProperties readServicePropertiesFromStream(final InputStream stream) throws SAXException, + IOException, ParserConfigurationException { + SAXParser saxParser = Utility.getSAXParser(); + ServicePropertiesHandler handler = new ServicePropertiesHandler(); + saxParser.parse(stream, handler); + + return handler.props; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + this.elementStack.push(localName); + + if (Constants.AnalyticsConstants.CORS_RULE_ELEMENT.equals(localName)) { + this.rule = new CorsRule(); + } + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + String currentNode = this.elementStack.pop(); + + // if the node popped from the stack and the localName don't match, the xml document is improperly formatted + if (!localName.equals(currentNode)) { + throw new SAXException(SR.INVALID_RESPONSE_RECEIVED); + } + + String parentNode = null; + if (!this.elementStack.isEmpty()) { + parentNode = this.elementStack.peek(); + } + + String value = this.bld.toString(); + if (value.isEmpty()) { + value = null; + } + + if (this.retentionPolicyEnabled && Constants.AnalyticsConstants.RETENTION_POLICY_ELEMENT.equals(currentNode)) { + if (Constants.AnalyticsConstants.LOGGING_ELEMENT.equals(parentNode)) { + this.props.getLogging().setRetentionIntervalInDays(this.retentionPolicyDays); + } + else if (Constants.AnalyticsConstants.HOUR_METRICS_ELEMENT.equals(parentNode)) { + this.props.getHourMetrics().setRetentionIntervalInDays(this.retentionPolicyDays); + } + else if (Constants.AnalyticsConstants.MINUTE_METRICS_ELEMENT.equals(parentNode)) { + this.props.getMinuteMetrics().setRetentionIntervalInDays(this.retentionPolicyDays); + } + } + else if (Constants.AnalyticsConstants.CORS_RULE_ELEMENT.equals(currentNode)) { + this.props.getCors().getCorsRules().add(this.rule); + } + else if (Constants.AnalyticsConstants.RETENTION_POLICY_ELEMENT.equals(parentNode)) { + if (Constants.AnalyticsConstants.DAYS_ELEMENT.equals(currentNode)) { + this.retentionPolicyDays = Integer.parseInt(value); + } + else if (Constants.AnalyticsConstants.ENABLED_ELEMENT.equals(currentNode)) { + this.retentionPolicyEnabled = Boolean.parseBoolean(value); + } + } + else if (Constants.AnalyticsConstants.LOGGING_ELEMENT.equals(parentNode)) { + if (Constants.AnalyticsConstants.VERSION_ELEMENT.equals(currentNode)) { + this.props.getLogging().setVersion(value); + } + else if (Constants.AnalyticsConstants.DELETE_ELEMENT.equals(currentNode)) { + if (Boolean.parseBoolean(value)) { + this.props.getLogging().getLogOperationTypes().add(LoggingOperations.DELETE); + } + } + else if (Constants.AnalyticsConstants.READ_ELEMENT.equals(currentNode)) { + if (Boolean.parseBoolean(value)) { + this.props.getLogging().getLogOperationTypes().add(LoggingOperations.READ); + } + } + else if (Constants.AnalyticsConstants.WRITE_ELEMENT.equals(currentNode)) { + if (Boolean.parseBoolean(value)) { + this.props.getLogging().getLogOperationTypes().add(LoggingOperations.WRITE); + } + } + } + else if (Constants.AnalyticsConstants.HOUR_METRICS_ELEMENT.equals(parentNode)) { + MetricsProperties metrics = this.props.getHourMetrics(); + if (Constants.AnalyticsConstants.VERSION_ELEMENT.equals(currentNode)) { + metrics.setVersion(value); + } + else if (Constants.AnalyticsConstants.ENABLED_ELEMENT.equals(currentNode)) { + if (Boolean.parseBoolean(value)) { + metrics.setMetricsLevel(metrics.getMetricsLevel() != MetricsLevel.SERVICE_AND_API ? MetricsLevel.SERVICE + : MetricsLevel.SERVICE_AND_API); + } + } + else if (Constants.AnalyticsConstants.INCLUDE_APIS_ELEMENT.equals(currentNode)) { + if (Boolean.parseBoolean(value) && metrics.getMetricsLevel() != MetricsLevel.DISABLED) { + metrics.setMetricsLevel(MetricsLevel.SERVICE_AND_API); + } + } + } + else if (Constants.AnalyticsConstants.MINUTE_METRICS_ELEMENT.equals(parentNode)) { + MetricsProperties metrics = this.props.getMinuteMetrics(); + if (Constants.AnalyticsConstants.VERSION_ELEMENT.equals(currentNode)) { + metrics.setVersion(value); + } + else if (Constants.AnalyticsConstants.ENABLED_ELEMENT.equals(currentNode)) { + if (Boolean.parseBoolean(value)) { + metrics.setMetricsLevel(metrics.getMetricsLevel() != MetricsLevel.SERVICE_AND_API ? MetricsLevel.SERVICE + : MetricsLevel.SERVICE_AND_API); + } + } + else if (Constants.AnalyticsConstants.INCLUDE_APIS_ELEMENT.equals(currentNode)) { + if (Boolean.parseBoolean(value) && metrics.getMetricsLevel() != MetricsLevel.DISABLED) { + metrics.setMetricsLevel(MetricsLevel.SERVICE_AND_API); + } + } + } + else if (Constants.AnalyticsConstants.DEFAULT_SERVICE_VERSION.equals(currentNode)) { + this.props.setDefaultServiceVersion(value); + } + else if (Constants.AnalyticsConstants.CORS_RULE_ELEMENT.equals(parentNode)) { + if (Constants.AnalyticsConstants.ALLOWED_ORIGINS_ELEMENT.equals(currentNode)) { + if (value != null) { + this.rule.setAllowedOrigins(splitToList(value, ",")); + } + } + else if (Constants.AnalyticsConstants.ALLOWED_METHODS_ELEMENT.equals(currentNode)) { + if (value != null) { + this.rule.setAllowedMethods(splitToEnumSet(value, ",")); + } + } + else if (Constants.AnalyticsConstants.EXPOSED_HEADERS_ELEMENT.equals(currentNode)) { + if (value != null) { + this.rule.setExposedHeaders(splitToList(value, ",")); + } + } + else if (Constants.AnalyticsConstants.ALLOWED_HEADERS_ELEMENT.equals(currentNode)) { + if (value != null) { + this.rule.setAllowedHeaders(splitToList(value, ",")); + } + } + else if (Constants.AnalyticsConstants.MAX_AGE_IN_SECONDS_ELEMENT.equals(currentNode)) { + this.rule.setMaxAgeInSeconds(Integer.parseInt(value)); + } + } + + this.bld = new StringBuilder(); + } + + @Override + public void characters(char ch[], int start, int length) throws SAXException { + this.bld.append(ch, start, length); + } + + /** + * Split a delimiter separated string into an ArrayList + * + * @param str + * the string to split + * @param delimiter + * the character to split on + * @return the list of strings + */ + private static List splitToList(String str, String delimiter) { + ArrayList list = new ArrayList(); + StringTokenizer st = new StringTokenizer(str, delimiter); + while (st.hasMoreElements()) { + list.add(st.nextToken()); + } + return list; + } + + /** + * Split a delimiter separated string into a EnumSet of CorsHttpMethods + * + * @param str + * the string to split + * @param delimiter + * the character to split on + * @return the set of CorsHttpMethods + */ + private static EnumSet splitToEnumSet(String str, String delimiter) { + EnumSet set = EnumSet.noneOf(CorsHttpMethods.class); + StringTokenizer st = new StringTokenizer(str, delimiter); + while (st.hasMoreElements()) { + set.add(CorsHttpMethods.valueOf(st.nextToken())); + } + return set; + } +} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ServicePropertiesSerializer.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/ServicePropertiesSerializer.java similarity index 98% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ServicePropertiesSerializer.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/ServicePropertiesSerializer.java index b24b5b82e528b..ccb906e1263e1 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ServicePropertiesSerializer.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/ServicePropertiesSerializer.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import java.io.StringWriter; import java.io.UnsupportedEncodingException; @@ -22,13 +22,13 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; /** * RESERVED FOR INTERNAL USE. A class used to serialize ServiceProperties to a byte array. */ -public final class ServicePropertiesSerializer { +final class ServicePropertiesSerializer { /** * Writes the contents of the ServiceProperties to the stream in xml format. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ServiceStats.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/ServiceStats.java similarity index 96% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ServiceStats.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/ServiceStats.java index 3eeb1d1826fe5..4c85db1bdfb22 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ServiceStats.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/ServiceStats.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; /** * Class representing a set of stats pertaining to a cloud storage service. diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/ServiceStatsHandler.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/ServiceStatsHandler.java new file mode 100644 index 0000000000000..6811acd52d8af --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/ServiceStatsHandler.java @@ -0,0 +1,121 @@ +/** + * 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; + +import java.io.IOException; +import java.io.InputStream; +import java.text.ParseException; +import java.util.Stack; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; + +/** + * RESERVED FOR INTERNAL USE. A class used to deserialize service stats. + */ +final class ServiceStatsHandler extends DefaultHandler { + /** + * The name of the geo-replication XML element. + */ + private final static String GEO_REPLICATION_NAME = "GeoReplication"; + + /** + * The name of the status XML element. + */ + private final static String STATUS_NAME = "Status"; + + /** + * The name of the last sync time XML element. + */ + private final static String LAST_SYNC_TIME_NAME = "LastSyncTime"; + + private final Stack elementStack = new Stack(); + private StringBuilder bld = new StringBuilder(); + + private final GeoReplicationStats geoReplicationStats = new GeoReplicationStats(); + private final ServiceStats stats = new ServiceStats(); + + /** + * Constructs a {@link ServiceStats} object from an XML document received from the service. + * + * @param inStream + * The XMLStreamReader object. + * @return + * A {@link ServiceStats} object containing the properties in the XML document. + * + * @throws SAXException + * @throws ParserConfigurationException + * @throws IOException + */ + public static ServiceStats readServiceStatsFromStream(final InputStream inStream) + throws ParserConfigurationException, SAXException, IOException { + SAXParser saxParser = Utility.getSAXParser(); + ServiceStatsHandler handler = new ServiceStatsHandler(); + saxParser.parse(inStream, handler); + + return handler.stats; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + this.elementStack.push(localName); + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + String currentNode = this.elementStack.pop(); + + // if the node popped from the stack and the localName don't match, the xml document is improperly formatted + if (!localName.equals(currentNode)) { + throw new SAXException(SR.INVALID_RESPONSE_RECEIVED); + } + + String value = this.bld.toString(); + if (value.isEmpty()) { + value = null; + } + + if (GEO_REPLICATION_NAME.equals(currentNode)) { + this.stats.setGeoReplication(this.geoReplicationStats); + } + else if (STATUS_NAME.equals(currentNode)) { + this.geoReplicationStats.setStatus(GeoReplicationStatus.parse(value)); + } + else if (LAST_SYNC_TIME_NAME.equals(currentNode)) { + try { + this.geoReplicationStats.setLastSyncTime(Utility.isNullOrEmpty(value) ? null : Utility + .parseRFC1123DateFromStringInGMT(value)); + } + catch (ParseException e) { + throw new SAXException(e); + } + } + + this.bld = new StringBuilder(); + } + + @Override + public void characters(char ch[], int start, int length) throws SAXException { + this.bld.append(ch, start, length); + } + +} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/SharedAccessPolicy.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/SharedAccessPolicy.java similarity index 93% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/SharedAccessPolicy.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/SharedAccessPolicy.java index c8bd2824a84b0..cde9ce1fe7009 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/SharedAccessPolicy.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/SharedAccessPolicy.java @@ -12,13 +12,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage; import java.util.Date; /** - * RESERVED FOR INTERNAL USE. Represents a shared access policy, which specifies the start time, expiry time, and - * permissions for a shared access signature. + * Represents a shared access policy, which specifies the start time, expiry time, and permissions for a shared access + * signature. */ public abstract class SharedAccessPolicy { diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/SharedAccessPolicyHandler.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/SharedAccessPolicyHandler.java new file mode 100644 index 0000000000000..0a81b547ef2da --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/SharedAccessPolicyHandler.java @@ -0,0 +1,137 @@ +/** + * 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; + +import java.io.IOException; +import java.io.InputStream; +import java.text.ParseException; +import java.util.HashMap; +import java.util.Stack; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; + +/** + * RESERVED FOR INTERNAL USE. A class used to deserialize SharedAccessPolicies. + */ +public class SharedAccessPolicyHandler extends DefaultHandler { + + private final Stack elementStack = new Stack(); + private StringBuilder bld = new StringBuilder(); + + private final HashMap policies = new HashMap(); + private final Class policyClassType; + + private String id; + private T policy; + + private SharedAccessPolicyHandler(final Class cls) { + this.policyClassType = cls; + } + + /** + * RESERVED FOR INTERNAL USE. Gets the HashMap of SharedAccessPolicies from the response. + * + * @param stream + * the stream to read from + * @param cls + * the SharedAccessPolicy class type + * @return the HashMap of SharedAccessPolicies from the response + * @throws SAXException + * @throws ParserConfigurationException + * @throws ParseException + * if a date is incorrectly encoded in the stream + * @throws IOException + */ + public static HashMap getAccessIdentifiers(final InputStream stream, + final Class cls) throws ParserConfigurationException, SAXException, IOException { + SAXParser saxParser = Utility.getSAXParser(); + SharedAccessPolicyHandler handler = new SharedAccessPolicyHandler(cls); + saxParser.parse(stream, handler); + + return handler.policies; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + this.elementStack.push(localName); + + if (Constants.SIGNED_IDENTIFIER_ELEMENT.equals(localName)) { + this.id = null; + + try { + this.policy = this.policyClassType.newInstance(); + } + catch (Exception e) { + throw new SAXException(e); + } + } + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + String currentNode = this.elementStack.pop(); + + // if the node popped from the stack and the localName don't match, the xml document is improperly formatted + if (!localName.equals(currentNode)) { + throw new SAXException(SR.INVALID_RESPONSE_RECEIVED); + } + + String value = this.bld.toString(); + if (value.isEmpty()) { + value = null; + } + + if (Constants.SIGNED_IDENTIFIER_ELEMENT.equals(currentNode)) { + this.policies.put(this.id, this.policy); + } + else if (Constants.ID.equals(currentNode)) { + this.id = value; + } + else if (Constants.START.equals(currentNode)) { + try { + this.policy.setSharedAccessStartTime(Utility.parseISO8061LongDateFromString(value)); + } + catch (ParseException e) { + throw new SAXException(e); + } + } + else if (Constants.EXPIRY.equals(currentNode)) { + try { + this.policy.setSharedAccessExpiryTime(Utility.parseISO8061LongDateFromString(value)); + } + catch (ParseException e) { + throw new SAXException(e); + } + } + else if (Constants.PERMISSION.equals(currentNode)) { + this.policy.setPermissionsFromString(value); + } + + this.bld = new StringBuilder(); + } + + @Override + public void characters(char ch[], int start, int length) throws SAXException { + this.bld.append(ch, start, length); + } +} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/SharedAccessPolicySerializer.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/SharedAccessPolicySerializer.java similarity index 93% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/SharedAccessPolicySerializer.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/SharedAccessPolicySerializer.java index f68a08f72ee16..f4c22b269fbc6 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/SharedAccessPolicySerializer.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/SharedAccessPolicySerializer.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage; import java.io.StringWriter; import java.util.HashMap; @@ -22,14 +22,15 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; -import com.microsoft.windowsazure.storage.Constants; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; /** * RESERVED FOR INTERNAL USE. A class used to serialize SharedAccessPolicies to a byte array. */ public final class SharedAccessPolicySerializer { /** - * Writes a collection of shared access policies to the specified stream in XML format. + * RESERVED FOR INTERNAL USE. Writes a collection of shared access policies to the specified stream in XML format. * * @param * diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageCredentials.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageCredentials.java new file mode 100644 index 0000000000000..e91dc6503dcfe --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageCredentials.java @@ -0,0 +1,200 @@ +/** + * 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; + +import java.net.URI; +import java.net.URISyntaxException; +import java.security.InvalidKeyException; +import java.util.HashMap; + +import com.microsoft.azure.storage.core.Base64; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; + +/** + * Represents a set of credentials used to authenticate access to a Microsoft Azure storage account. This is the base + * class for the {@link StorageCredentialsAccountAndKey} and {@link StorageCredentialsSharedAccessSignature} classes. + */ +public abstract class StorageCredentials { + + /** + * Tries to determine the storage credentials from a collection of name/value pairs. + * + * @param settings + * A HashMap object of the name/value pairs that represent the settings to use to configure + * the credentials. + *

+ * Either include an account name with an account key (specifying values for + * {@link CloudStorageAccount#ACCOUNT_NAME_NAME} and {@link CloudStorageAccount#ACCOUNT_KEY_NAME} ), or a + * shared access signature (specifying a value for + * {@link CloudStorageAccount#SHARED_ACCESS_SIGNATURE_NAME} ). If you use an account name and account + * key, do not include a shared access signature, and vice versa. + * + * @return A {@link StorageCredentials} object representing the storage credentials determined from the name/value + * pairs. + * + * @throws InvalidKeyException + * If the key value specified for {@link CloudStorageAccount#ACCOUNT_KEY_NAME} is not a valid + * Base64-encoded string. + */ + protected static StorageCredentials tryParseCredentials(final HashMap settings) + throws InvalidKeyException { + final String accountName = settings.get(CloudStorageAccount.ACCOUNT_NAME_NAME) != null ? settings + .get(CloudStorageAccount.ACCOUNT_NAME_NAME) : null; + + final String accountKey = settings.get(CloudStorageAccount.ACCOUNT_KEY_NAME) != null ? settings + .get(CloudStorageAccount.ACCOUNT_KEY_NAME) : null; + + final String sasSignature = settings.get(CloudStorageAccount.SHARED_ACCESS_SIGNATURE_NAME) != null ? settings + .get(CloudStorageAccount.SHARED_ACCESS_SIGNATURE_NAME) : null; + + if (accountName != null && accountKey != null && sasSignature == null) { + if (Base64.validateIsBase64String(accountKey)) { + return new StorageCredentialsAccountAndKey(accountName, accountKey); + } + else { + throw new InvalidKeyException(SR.INVALID_KEY); + } + } + if (accountName == null && accountKey == null && sasSignature != null) { + return new StorageCredentialsSharedAccessSignature(sasSignature); + } + + return null; + } + + /** + * Tries to determine the storage credentials from a connection string. + *

+ * The format for the connection string is in the pattern "keyname=value". Multiple key/value pairs can be + * separated by a semi-colon, for example, "keyname1=value1;keyname2=value2". Either include an account name + * with an account key or a shared access signature. If you use an account name and account key, do not include a + * shared access signature, and vice versa. + *

+ * The same connection string can be used as for {@link CloudStorageAccount#parse(String)} but here only the account + * name, account key, and sas key/value pairs will be examined. + * + * @param connectionString + * A String that contains the key/value pairs that represent the storage credentials. + * + * @return A {@link StorageCredentials} object representing the storage credentials determined from the connection + * string. + * + * @throws InvalidKeyException + * If the account key specified in connectionString is not valid. + */ + public static StorageCredentials tryParseCredentials(final String connectionString) throws InvalidKeyException { + return tryParseCredentials(Utility.parseAccountString(connectionString)); + } + + /** + * Returns the associated account name for the credentials. This is null for anonymous and shared access signature + * credentials. + * + * @return A String that represents the associated account name for the credentials + */ + public String getAccountName() { + return null; + } + + /** + * Returns a String that represents this instance. + * + * @param exportSecrets + * true to include sensitive data in the return string; otherwise, false. + * @return A String that represents this object, optionally including sensitive data. + */ + public abstract String toString(boolean exportSecrets); + + /** + * Transforms a resource URI into a shared access signature URI, by appending a shared access token. + * + * @param resourceUri + * A java.net.URI object that represents the resource URI to be transformed. + * + * @return A java.net.URI object that represents the signature, including the resource URI and the + * shared access token. + * + * @throws StorageException + * If a storage service error occurred. + * @throws URISyntaxException + * If the resource URI is not properly formatted. + */ + public URI transformUri(final URI resourceUri) throws URISyntaxException, StorageException { + return this.transformUri(resourceUri, null); + } + + /** + * Transforms a resource URI into a shared access signature URI, by appending a shared access token. + * + * @param resourceUri + * A StorageUri object that represents the resource URI to be transformed. + * + * @return A StorageUri object that represents the signature, including the resource URI and the + * shared access token. + * + * @throws StorageException + * If a storage service error occurred. + * @throws URISyntaxException + * If the resource URI is not properly formatted. + */ + public StorageUri transformUri(StorageUri resourceUri) throws URISyntaxException, StorageException { + return this.transformUri(resourceUri, null /* opContext */); + } + + /** + * Transforms a resource URI into a shared access signature URI, by appending a shared access token and using the + * specified operation context. + * + * @param resourceUri + * A java.net.URI object that represents the resource URI to be transformed. + * @param opContext + * An {@link OperationContext} object that 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. + * + * @return A java.net.URI object that represents the signature, including the resource URI and the + * shared access token. + * + * @throws StorageException + * If a storage service error occurred. + * @throws URISyntaxException + * If the resource URI is not properly formatted. + */ + public abstract URI transformUri(URI resourceUri, OperationContext opContext) throws URISyntaxException, + StorageException; + + /** + * Transforms a resource URI into a shared access signature URI, by appending a shared access token and using the + * specified operation context. + * + * @param resourceUri + * A StorageUri object that represents the resource URI to be transformed. + * @param opContext + * An {@link OperationContext} object that 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. + * + * @return A StorageUri object that represents the signature, including the resource URI and the + * shared access token. + * + * @throws StorageException + * If a storage service error occurred. + * @throws URISyntaxException + * If the resource URI is not properly formatted. + */ + public abstract StorageUri transformUri(StorageUri resourceUri, OperationContext opContext) + throws URISyntaxException, StorageException; +} diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageCredentialsAccountAndKey.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageCredentialsAccountAndKey.java new file mode 100644 index 0000000000000..13a23191d2220 --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageCredentialsAccountAndKey.java @@ -0,0 +1,120 @@ +/** + * 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; + +import java.net.URI; + +import com.microsoft.azure.storage.core.Base64; + +/** + * Represents storage account credentials, based on storage account and access key, for accessing the Microsoft Azure + * storage services. + */ +public final class StorageCredentialsAccountAndKey extends StorageCredentials { + + /** + * The internal Credentials associated with the StorageCredentials. + */ + private Credentials credentials; + + /** + * Creates an instance of the StorageCredentialsAccountAndKey class, using the specified storage + * account name and access key; the specified access key is in the form of a byte array. + * + * @param accountName + * A String that represents the name of the storage account. + * @param key + * An array of bytes that represent the account access key. + */ + public StorageCredentialsAccountAndKey(final String accountName, final byte[] key) { + this.credentials = new Credentials(accountName, key); + } + + /** + * Creates an instance of the StorageCredentialsAccountAndKey class, using the specified storage + * account name and access key; the specified access key is stored as a String. + * + * @param accountName + * A String that represents the name of the storage account. + * @param key + * A String that represents the Base-64-encoded account access key. + */ + public StorageCredentialsAccountAndKey(final String accountName, final String key) { + this(accountName, Base64.decode(key)); + } + + /** + * Returns the associated account name for the credentials. + * + * @return A String that contains the account name for the credentials. + */ + @Override + public String getAccountName() { + return this.credentials.getAccountName(); + } + + /** + * Gets the name of the key used by these credentials. + */ + public String getAccountKeyName() { + return this.credentials.getKeyName(); + } + + /** + * Returns the internal credentials associated with the storage credentials. + * + * @return A Credentials object that contains the internal credentials associated with this instance of + * the StorageCredentialsAccountAndKey class. + */ + public Credentials getCredentials() { + return this.credentials; + } + + /** + * Sets the credentials. + * + * @param credentials + * A Credentials object that represents the credentials to set for this instance of the + * StorageCredentialsAccountAndKey class. + */ + public void setCredentials(final Credentials credentials) { + this.credentials = credentials; + } + + /** + * Returns a String that represents this instance, optionally including sensitive data. + * + * @param exportSecrets + * true to include sensitive data in the return string; otherwise, false. + * + * @return A String that represents this object, optionally including sensitive data. + */ + @Override + public String toString(final boolean exportSecrets) { + return String.format("%s=%s;%s=%s", CloudStorageAccount.ACCOUNT_NAME_NAME, this.getAccountName(), + CloudStorageAccount.ACCOUNT_KEY_NAME, exportSecrets ? this.credentials.getKey().getBase64EncodedKey() + : "[key hidden]"); + } + + @Override + public URI transformUri(URI resourceUri, OperationContext opContext) { + return resourceUri; + } + + @Override + public StorageUri transformUri(StorageUri resourceUri, OperationContext opContext) { + return resourceUri; + } +} diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageCredentialsAnonymous.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageCredentialsAnonymous.java new file mode 100644 index 0000000000000..b8bf5769b021c --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageCredentialsAnonymous.java @@ -0,0 +1,67 @@ +/** + * 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; + +import java.net.URI; + +/** + * *RESERVED FOR INTERNAL USE* Represents credentials for anonymous access. This class is used by the internal + * implementation (not a public class, so its comments are not built into the Javadoc output). + */ +public final class StorageCredentialsAnonymous extends StorageCredentials { + + /** + * Stores the singleton instance of this class. + */ + public static final StorageCredentials ANONYMOUS = new StorageCredentialsAnonymous(); + + /** + * Returns the singleton instance of the StorageCredentials class. + * + * @return the singleton instance of this class + */ + protected static StorageCredentials getInstance() { + return StorageCredentialsAnonymous.ANONYMOUS; + } + + /** + * Enforces the singleton pattern via a private constructor. + */ + protected StorageCredentialsAnonymous() { + // Empty Default Ctor + } + + /** + * Returns a String object that represents this instance. + * + * @param exportSecrets + * true to include sensitive data in the string; otherwise, false + * @return a string representation of the credentials, optionally including sensitive data. + */ + @Override + public String toString(final boolean exportSecrets) { + return Constants.EMPTY_STRING; + } + + @Override + public URI transformUri(URI resourceUri, OperationContext opContext) { + return resourceUri; + } + + @Override + public StorageUri transformUri(StorageUri resourceUri, OperationContext opContext) { + return resourceUri; + } +} diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageCredentialsSharedAccessSignature.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageCredentialsSharedAccessSignature.java new file mode 100644 index 0000000000000..230f9e40dfbe4 --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageCredentialsSharedAccessSignature.java @@ -0,0 +1,119 @@ +/** + * 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; + +import java.net.URI; +import java.net.URISyntaxException; + +import com.microsoft.azure.storage.core.PathUtility; + +/** + * Represents storage credentials for delegated access to Blob service resources via a shared access signature. + */ +public final class StorageCredentialsSharedAccessSignature extends StorageCredentials { + + /** + * Stores the shared access signature token. + */ + private final String token; + + /** + * Creates an instance of the StorageCredentialsSharedAccessSignature class using the specified shared + * access signature token. + * + * @param token + * A String that represents shared access signature token. + */ + public StorageCredentialsSharedAccessSignature(final String token) { + this.token = token; + } + + /** + * Returns the shared access signature token. + * + * @return A String that contains the token. + */ + public String getToken() { + return this.token; + } + + /** + * Returns a String that represents this instance, optionally including sensitive data. + * + * @param exportSecrets + * true to include sensitive data in the return string; otherwise, false. + * @return A String that represents this object, optionally including sensitive data. + */ + @Override + public String toString(final boolean exportSecrets) { + return String.format("%s=%s", CloudStorageAccount.SHARED_ACCESS_SIGNATURE_NAME, exportSecrets ? this.token + : "[signature hidden]"); + } + + /** + * Transforms a resource URI into a shared access signature URI, by appending a shared access token and using the + * specified operation context. + * + * @param resourceUri + * A java.net.URI object that represents the resource URI to be transformed. + * @param opContext + * An {@link OperationContext} object that 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. + * + * @return A java.net.URI object that represents the signature, including the resource URI and the + * shared access token. + * + * @throws StorageException + * If a storage service error occurred. + * @throws URISyntaxException + * If the resource URI is not properly formatted. + */ + @Override + public URI transformUri(final URI resourceUri, final OperationContext opContext) throws URISyntaxException, + StorageException { + if (resourceUri == null) { + return null; + } + + return PathUtility.addToQuery(resourceUri, this.token); + } + + /** + * Transforms a resource URI into a shared access signature URI, by appending a shared access token and using the + * specified operation context. + * + * @param resourceUri + * A StorageUri object that represents the resource URI to be transformed. + * @param opContext + * An {@link OperationContext} object that 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. + * + * @return A StorageUri object that represents the signature, including the resource URI and the + * shared access token. + * + * @throws StorageException + * If a storage service error occurred. + * @throws URISyntaxException + * If the resource URI is not properly formatted. + */ + @Override + public StorageUri transformUri(StorageUri resourceUri, OperationContext opContext) throws URISyntaxException, + StorageException { + return new StorageUri(this.transformUri(resourceUri.getPrimaryUri(), opContext), this.transformUri( + resourceUri.getSecondaryUri(), opContext)); + } +} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageErrorCode.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageErrorCode.java similarity index 95% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageErrorCode.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/StorageErrorCode.java index a5f83c138b299..1f5002419bbc8 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageErrorCode.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageErrorCode.java @@ -12,11 +12,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; /** - * - * Represents error codes that may be returned by the Windows Azure storage services or the storage client library. + * Represents error codes that may be returned by the Microsoft Azure storage services or the storage client library. */ public enum StorageErrorCode { /** diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageErrorCodeStrings.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageErrorCodeStrings.java similarity index 99% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageErrorCodeStrings.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/StorageErrorCodeStrings.java index 810c65eb5823e..ae26a182b54ee 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageErrorCodeStrings.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageErrorCodeStrings.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; /** * Represents error code strings that are common to all storage services. diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageErrorHandler.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageErrorHandler.java new file mode 100644 index 0000000000000..85a4dcadd6eaf --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageErrorHandler.java @@ -0,0 +1,106 @@ +/** + * 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; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Stack; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; + +/** + * RESERVED FOR INTERNAL USE. A class used to deserialize storage errors. + */ +final class StorageErrorHandler extends DefaultHandler { + + private final Stack elementStack = new Stack(); + private StringBuilder bld = new StringBuilder(); + + private final StorageExtendedErrorInformation errorInfo = new StorageExtendedErrorInformation(); + + /** + * Gets the Extended Error information from the response stream. + * + * @return the Extended Error information from the response stream + * @throws ParserConfigurationException + * @throws IOException + * @throws SAXException + */ + public static StorageExtendedErrorInformation getExtendedErrorInformation(final InputStream stream) + throws SAXException, IOException, ParserConfigurationException { + SAXParser saxParser = Utility.getSAXParser(); + StorageErrorHandler handler = new StorageErrorHandler(); + saxParser.parse(stream, handler); + + return handler.errorInfo; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + this.elementStack.push(localName); + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + String currentNode = this.elementStack.pop(); + + // if the node popped from the stack and the localName don't match, the xml document is improperly formatted + if (!localName.equals(currentNode)) { + throw new SAXException(SR.INVALID_RESPONSE_RECEIVED); + } + + String parentNode = null; + if (!this.elementStack.isEmpty()) { + parentNode = this.elementStack.peek(); + } + + String value = this.bld.toString(); + if (value.isEmpty()) { + value = null; + } + + if (Constants.ERROR_ROOT_ELEMENT.equals(parentNode)) { + if (Constants.ERROR_CODE.equals(currentNode)) { + this.errorInfo.setErrorCode(value); + } + else if (Constants.ERROR_MESSAGE.equals(currentNode)) { + this.errorInfo.setErrorMessage(value); + } + else { + // get additional details + this.errorInfo.getAdditionalDetails().put(currentNode, new String[] { value }); + } + } + else if (Constants.ERROR_EXCEPTION.equals(parentNode)) { + // get additional details + this.errorInfo.getAdditionalDetails().put(currentNode, new String[] { value }); + } + + this.bld = new StringBuilder(); + } + + @Override + public void characters(char ch[], int start, int length) throws SAXException { + this.bld.append(ch, start, length); + } +} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageEvent.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageEvent.java similarity index 90% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageEvent.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/StorageEvent.java index 768fec4ac4e2f..279239defeadd 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageEvent.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageEvent.java @@ -12,14 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import java.util.EventListener; -import com.microsoft.windowsazure.storage.core.BaseEvent; - /** - * * Abstract class that represents a generic event listener. * * @param diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageEventMultiCaster.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageEventMultiCaster.java similarity index 96% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageEventMultiCaster.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/StorageEventMultiCaster.java index 4da9cfdbfaf14..890d2ff010016 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageEventMultiCaster.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageEventMultiCaster.java @@ -12,12 +12,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import java.util.concurrent.CopyOnWriteArrayList; -import com.microsoft.windowsazure.storage.core.BaseEvent; - /** * Represents a generic event multi-caster that allows event listeners to be dynamically added and removed. * diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageException.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageException.java similarity index 93% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageException.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/StorageException.java index d5150bbe438ce..238db506e2970 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageException.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageException.java @@ -12,23 +12,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.SocketException; -import com.microsoft.windowsazure.storage.core.StorageErrorDeserializer; -import com.microsoft.windowsazure.storage.table.TableConstants; -import com.microsoft.windowsazure.storage.table.TablePayloadFormat; -import com.microsoft.windowsazure.storage.table.TableStorageErrorDeserializer; +import com.microsoft.azure.storage.table.TablePayloadFormat; +import com.microsoft.azure.storage.table.TableStorageErrorDeserializer; /** - * Represents an exception for the Windows Azure storage service. + * Represents an exception for the Microsoft Azure storage service. */ public class StorageException extends Exception { + /** + * The Content-Type header for JSON. + */ + private static final String JSON_CONTENT_TYPE = "application/json"; + /** * Represents the serialization version number. */ @@ -54,7 +57,7 @@ protected static StorageExtendedErrorInformation getErrorDetailsFromRequest(fina return null; } try { - return StorageErrorDeserializer.getExtendedErrorInformation(request.getErrorStream()); + return StorageErrorHandler.getExtendedErrorInformation(request.getErrorStream()); } catch (final Exception e) { return null; @@ -93,7 +96,7 @@ protected static StorageExtendedErrorInformation getErrorDetailsFromTableRequest } /** - * Translates the specified exception into a storage exception. + * RESERVED FOR INTERNAL USE. Translates the specified exception into a storage exception. * * @param request * An HttpURLConnection object that represents the request whose exception is being @@ -107,6 +110,7 @@ protected static StorageExtendedErrorInformation getErrorDetailsFromTableRequest * * @return A StorageException object that represents translated exception. */ + @SuppressWarnings("deprecation") public static StorageException translateException(final HttpURLConnection request, final Exception cause, final OperationContext opContext) { if (request == null) { @@ -127,7 +131,7 @@ public static StorageException translateException(final HttpURLConnection reques final String server = request.getHeaderField("Server"); if (server != null && server.startsWith("Windows-Azure-Table")) { final String type = request.getHeaderField(Constants.HeaderConstants.CONTENT_TYPE); - if (TableConstants.HeaderConstants.JSON_CONTENT_TYPE.equals(type)) { + if (JSON_CONTENT_TYPE.equals(type)) { extendedError = getErrorDetailsFromTableRequest(request, TablePayloadFormat.Json, opContext); } else { @@ -297,6 +301,8 @@ public StorageException(final String errorCode, final String message, final int } /** + * Gets the error code returned by the operation. + * * @return the errorCode */ public String getErrorCode() { @@ -304,6 +310,8 @@ public String getErrorCode() { } /** + * Gets the extended error information returned by the operation. + * * @return the extendedErrorInformation */ public StorageExtendedErrorInformation getExtendedErrorInformation() { @@ -311,6 +319,8 @@ public StorageExtendedErrorInformation getExtendedErrorInformation() { } /** + * Gets the HTTP status code returned by the operation. + * * @return the httpStatusCode */ public int getHttpStatusCode() { diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageExtendedErrorInformation.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageExtendedErrorInformation.java similarity index 81% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageExtendedErrorInformation.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/StorageExtendedErrorInformation.java index 17402a44de26d..bb8df5b855be3 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageExtendedErrorInformation.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageExtendedErrorInformation.java @@ -12,13 +12,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import java.io.Serializable; import java.util.HashMap; /** - * Represents extended error information returned by the Windows Azure storage service. + * Represents extended error information returned by the Microsoft Azure storage service. */ public final class StorageExtendedErrorInformation implements Serializable { /** @@ -49,6 +49,8 @@ public StorageExtendedErrorInformation() { } /** + * Gets additional error details, as a java.util.HashMap object. + * * @return the additionalDetails */ public HashMap getAdditionalDetails() { @@ -56,6 +58,8 @@ public HashMap getAdditionalDetails() { } /** + * Gets the storage service error code. + * * @return the errorCode */ public String getErrorCode() { @@ -63,6 +67,8 @@ public String getErrorCode() { } /** + * Gets the storage service error message. + * * @return the errorMessage */ public String getErrorMessage() { @@ -70,14 +76,18 @@ public String getErrorMessage() { } /** + * RESERVED FOR INTERNAL USE. + * * @param additionalDetails * the additionalDetails to set */ - protected void setAdditionalDetails(final HashMap additionalDetails) { + public void setAdditionalDetails(final HashMap additionalDetails) { this.additionalDetails = additionalDetails; } /** + * RESERVED FOR INTERNAL USE. + * * @param errorCode * the errorCode to set */ @@ -86,6 +96,8 @@ public void setErrorCode(final String errorCode) { } /** + * RESERVED FOR INTERNAL USE. + * * @param errorMessage * the errorMessage to set */ diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageKey.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageKey.java similarity index 95% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageKey.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/StorageKey.java index 7c164fb212332..4acc92a571496 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageKey.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageKey.java @@ -12,9 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; -import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; @@ -23,7 +22,7 @@ import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; -import com.microsoft.windowsazure.storage.core.Base64; +import com.microsoft.azure.storage.core.Base64; /** * Represents a container for a storage key. @@ -204,10 +203,8 @@ public void setKey(final byte[] key) { * * @param key * A String that represents the key being assigned. - * @throws IOException - * If the specified key is not a valid Base64-encoded string. */ - public void setKey(final String key) throws IOException { + public void setKey(final String key) { this.key = Base64.decode(key); } } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageLocation.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageLocation.java similarity index 94% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageLocation.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/StorageLocation.java index 131bcb7e813a6..be2d284868da1 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageLocation.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageLocation.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; /** * Represents a storage service location. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageUri.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageUri.java similarity index 67% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageUri.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/StorageUri.java index 6e2ab92221b19..17a2fbf426448 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageUri.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/StorageUri.java @@ -12,12 +12,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage; import java.net.URI; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; /** * Holds a list of URIs that represents the storage resource. @@ -50,11 +50,45 @@ public StorageUri(URI primaryUri) { * Initializes a new instance of the StorageUri class using the URI specified. */ public StorageUri(URI primaryUri, URI secondaryUri) { - if ((primaryUri != null) - && (secondaryUri != null) - && (!(primaryUri.getPath().equals(secondaryUri.getPath())) || (primaryUri.getQuery() != null && !(primaryUri - .getQuery().equals(secondaryUri.getQuery()))))) { - throw new IllegalArgumentException(SR.STORAGE_URI_MUST_MATCH); + if (primaryUri != null && secondaryUri != null) { + // check query component is equivalent + if ((primaryUri.getQuery() == null && secondaryUri.getQuery() != null) + || (primaryUri.getQuery() != null && !(primaryUri.getQuery().equals(secondaryUri.getQuery())))) { + throw new IllegalArgumentException(SR.STORAGE_URI_MUST_MATCH); + } + + boolean primaryPathStyle = Utility.determinePathStyleFromUri(primaryUri); + boolean secondaryPathStyle = Utility.determinePathStyleFromUri(secondaryUri); + + if (!primaryPathStyle && !secondaryPathStyle) { + if ((primaryUri.getPath() == null && secondaryUri.getPath() != null) + || (primaryUri.getPath() != null && !(primaryUri.getPath().equals(secondaryUri.getPath())))) { + throw new IllegalArgumentException(SR.STORAGE_URI_MUST_MATCH); + } + } + else { + final int maxPrimaryPathSegments = primaryPathStyle ? 3 : 2; + final int maxSecondaryPathSegments = secondaryPathStyle ? 3 : 2; + + // getPath() on a path-style uri returns /devstore1[/path1/path2], split(3) returns ["","devstore","path1/path2"] + // getPath() on a regular uri returns [/path1/path2], split(2) returns ["","path1/path2"] + final String[] primaryPathSegments = primaryUri.getPath().split("/", maxPrimaryPathSegments); + final String[] secondaryPathSegments = secondaryUri.getPath().split("/", maxSecondaryPathSegments); + + String primaryPath = ""; + if (primaryPathSegments.length == maxPrimaryPathSegments) { + primaryPath = primaryPathSegments[primaryPathSegments.length - 1]; + } + + String secondaryPath = ""; + if (secondaryPathSegments.length == maxSecondaryPathSegments) { + secondaryPath = secondaryPathSegments[secondaryPathSegments.length - 1]; + } + + if (!primaryPath.equals(secondaryPath)) { + throw new IllegalArgumentException(SR.STORAGE_URI_MUST_MATCH); + } + } } this.setPrimaryUri(primaryUri); @@ -80,6 +114,8 @@ public boolean equals(StorageUri other) { } /** + * Gets the endpoint for the primary location for the storage account. + * * @return the primaryUri */ public URI getPrimaryUri() { @@ -87,6 +123,8 @@ public URI getPrimaryUri() { } /** + * Gets the endpoint for the secondary location for the storage account. + * * @return the secondaryUri */ public URI getSecondaryUri() { @@ -123,6 +161,8 @@ public int hashCode() { } /** + * Sets the endpoint for the primary location for the storage account. + * * @param primaryUri * the primaryUri to set */ @@ -133,6 +173,8 @@ private void setPrimaryUri(URI primaryUri) { } /** + * Sets the endpoint for the secondary location for the storage account. + * * @param secondaryUri * the secondaryUri to set */ diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobAttributes.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobAttributes.java similarity index 78% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobAttributes.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobAttributes.java index eda0deca76a20..567014cefce5a 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobAttributes.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobAttributes.java @@ -12,16 +12,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import java.net.URI; import java.util.HashMap; -import com.microsoft.windowsazure.storage.StorageUri; +import com.microsoft.azure.storage.StorageUri; /** * RESERVED FOR INTERNAL USE. Represents a blob's attributes. - * */ final class BlobAttributes { @@ -46,7 +45,7 @@ final class BlobAttributes { private StorageUri storageUri; /** - * Initializes a new instance of the BlobAttributes class. RESERVED FOR INTERNAL USE. + * Initializes a new instance of the BlobAttributes class. * * @param type * The type of blob to set. @@ -57,7 +56,7 @@ public BlobAttributes(final BlobType type) { } /** - * Gets the metadata for the blob. RESERVED FOR INTERNAL USE. + * Gets the metadata for the blob. * * @return A HashMap object containing the metadata for the blob. */ @@ -66,7 +65,7 @@ public HashMap getMetadata() { } /** - * Gets the properties for the blob. RESERVED FOR INTERNAL USE. + * Gets the properties for the blob. * * @return A BlobProperties object that represents the blob properties. */ @@ -75,7 +74,7 @@ public BlobProperties getProperties() { } /** - * Gets the snapshot ID of the blob. RESERVED FOR INTERNAL USE. + * Gets the snapshot ID of the blob. * * @return A String that represents snapshot ID of the blob. */ @@ -84,7 +83,7 @@ public final String getSnapshotID() { } /** - * Gets the list of URIs for all locations for the blob. RESERVED FOR INTERNAL USE. + * Gets the list of URIs for all locations for the blob. * * @return A StorageUri object that represents the list of URIs for all locations for the blob. */ @@ -93,7 +92,7 @@ public final StorageUri getStorageUri() { } /** - * Gets the URI of the blob. RESERVED FOR INTERNAL USE. + * Gets the URI of the blob. * * @return A java.net.URI object that represents the URI of the blob. */ @@ -102,7 +101,7 @@ public final URI getUri() { } /** - * Sets the metadata for a blob. RESERVED FOR INTERNAL USE. + * Sets the metadata for a blob. * * @param metadata * The blob meta data to set. @@ -112,7 +111,7 @@ protected void setMetadata(final HashMap metadata) { } /** - * Sets the properties for a blob. RESERVED FOR INTERNAL USE. + * Sets the properties for a blob. * * @param properties * The blob properties to set. @@ -122,17 +121,17 @@ protected void setProperties(final BlobProperties properties) { } /** - * Sets the snapshot ID of the blob. RESERVED FOR INTERNAL USE. + * Sets the snapshot ID of the blob. * * @param snapshotID * A String that represents snapshot ID of the blob. */ - public final void setSnapshotID(String snapshotID) { + protected final void setSnapshotID(String snapshotID) { this.snapshotID = snapshotID; } /** - * Sets the list of URIs for all locations for the blob. RESERVED FOR INTERNAL USE. + * Sets the list of URIs for all locations for the blob. * * @param storageUri * The list of URIs for all locations for the blob. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobConstants.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobConstants.java similarity index 86% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobConstants.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobConstants.java index 4670fbe9f0720..17f8a440581e0 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobConstants.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobConstants.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; /** * Holds the Constants used for the Queue Service. @@ -26,7 +26,7 @@ final class BlobConstants { /** * The header that specifies blob content MD5. */ - public static final String BLOB_CONTENT_MD5_HEADER = com.microsoft.windowsazure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + public static final String BLOB_CONTENT_MD5_HEADER = com.microsoft.azure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + "blob-content-md5"; /** @@ -42,7 +42,7 @@ final class BlobConstants { /** * The header that specifies public access to blobs. */ - public static final String BLOB_PUBLIC_ACCESS_HEADER = com.microsoft.windowsazure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + public static final String BLOB_PUBLIC_ACCESS_HEADER = com.microsoft.azure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + "blob-public-access"; /** @@ -52,7 +52,7 @@ final class BlobConstants { /** * The header for the blob type. */ - public static final String BLOB_TYPE_HEADER = com.microsoft.windowsazure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + public static final String BLOB_TYPE_HEADER = com.microsoft.azure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + "blob-type"; /** @@ -103,31 +103,31 @@ final class BlobConstants { /** * The header that specifies blob content encoding. */ - public static final String CONTENT_DISPOSITION_HEADER = com.microsoft.windowsazure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + public static final String CONTENT_DISPOSITION_HEADER = com.microsoft.azure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + "blob-content-disposition"; /** * The header that specifies blob content encoding. */ - public static final String CONTENT_ENCODING_HEADER = com.microsoft.windowsazure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + public static final String CONTENT_ENCODING_HEADER = com.microsoft.azure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + "blob-content-encoding"; /** * The header that specifies blob content language. */ - public static final String CONTENT_LANGUAGE_HEADER = com.microsoft.windowsazure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + public static final String CONTENT_LANGUAGE_HEADER = com.microsoft.azure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + "blob-content-language"; /** * The header that specifies blob content length. */ - public static final String CONTENT_LENGTH_HEADER = com.microsoft.windowsazure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + public static final String CONTENT_LENGTH_HEADER = com.microsoft.azure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + "blob-content-length"; /** * The header that specifies blob content type. */ - public static final String CONTENT_TYPE_HEADER = com.microsoft.windowsazure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + public static final String CONTENT_TYPE_HEADER = com.microsoft.azure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + "blob-content-type"; /** @@ -163,7 +163,7 @@ final class BlobConstants { /** * The default maximum size, in bytes, of a blob before it must be separated into blocks. */ - public static final int DEFAULT_SINGLE_BLOB_PUT_THRESHOLD_IN_BYTES = 32 * com.microsoft.windowsazure.storage.Constants.MB; + public static final int DEFAULT_SINGLE_BLOB_PUT_THRESHOLD_IN_BYTES = 32 * com.microsoft.azure.storage.Constants.MB; /** * Specifies snapshots are to be included. @@ -178,13 +178,13 @@ final class BlobConstants { /** * Maximum commit size */ - public static final int MAX_COMMIT_SIZE_4_MB = 4 * com.microsoft.windowsazure.storage.Constants.MB; + public static final int MAX_COMMIT_SIZE_4_MB = 4 * com.microsoft.azure.storage.Constants.MB; /** * The maximum size, in bytes, of a blob before it must be separated into blocks */ // Note if this is updated then Constants.MAX_MARK_LENGTH needs to be as well. - public static final int MAX_SINGLE_UPLOAD_BLOB_SIZE_IN_BYTES = 64 * com.microsoft.windowsazure.storage.Constants.MB; + public static final int MAX_SINGLE_UPLOAD_BLOB_SIZE_IN_BYTES = 64 * com.microsoft.azure.storage.Constants.MB; /** * Specifies the page blob type. @@ -214,7 +214,7 @@ final class BlobConstants { /** * The header that specifies page write mode. */ - public static final String PAGE_WRITE = com.microsoft.windowsazure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + public static final String PAGE_WRITE = com.microsoft.azure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + "page-write"; /** @@ -225,13 +225,13 @@ final class BlobConstants { /** * The header for specifying the sequence number. */ - public static final String SEQUENCE_NUMBER = com.microsoft.windowsazure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + public static final String SEQUENCE_NUMBER = com.microsoft.azure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + "blob-sequence-number"; /** * The header for the blob content length. */ - public static final String SIZE = com.microsoft.windowsazure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + public static final String SIZE = com.microsoft.azure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + "blob-content-length"; /** @@ -252,7 +252,7 @@ final class BlobConstants { /** * The header for snapshots. */ - public static final String SNAPSHOT_HEADER = com.microsoft.windowsazure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + public static final String SNAPSHOT_HEADER = com.microsoft.azure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + "snapshot"; /** diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobContainerAttributes.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobContainerAttributes.java similarity index 59% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobContainerAttributes.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobContainerAttributes.java index 1762329a2d8c3..253503b31ad8a 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobContainerAttributes.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobContainerAttributes.java @@ -12,16 +12,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import java.net.URI; import java.util.HashMap; -import com.microsoft.windowsazure.storage.StorageUri; +import com.microsoft.azure.storage.StorageUri; /** * RESERVED FOR INTERNAL USE. Represents a container's attributes, including its properties and metadata. - * */ final class BlobContainerAttributes { /** @@ -52,38 +51,87 @@ public BlobContainerAttributes() { this.setProperties(new BlobContainerProperties()); } + /** + * Gets the metadata for the container. + * + * @return A HashMap object containing the metadata for the container. + */ public HashMap getMetadata() { return this.metadata; } + /** + * Gets the name of the container. + * + * @return A String that represents name of the container. + */ public String getName() { return this.name; } + /** + * Gets the properties for the container. + * + * @return A BlobContainerProperties object that represents the container properties. + */ public BlobContainerProperties getProperties() { return this.properties; } + /** + * Gets the list of URIs for all locations for the container. + * + * @return A StorageUri object that represents the list of URIs for all locations for the container. + */ public final StorageUri getStorageUri() { return this.storageUri; } + /** + * Gets the URI of the container. + * + * @return A java.net.URI object that represents the URI of the container. + */ public URI getUri() { return this.storageUri.getPrimaryUri(); } + /** + * Sets the metadata for a container. + * + * @param metadata + * The container metadata to set. + */ public void setMetadata(final HashMap metadata) { this.metadata = metadata; } + /** + * Sets the name of the container. + * + * @param name + * A String that represents name of the container. + */ public void setName(final String name) { this.name = name; } + /** + * Sets the properties for a container. + * + * @param properties + * The container properties to set. + */ public void setProperties(final BlobContainerProperties properties) { this.properties = properties; } + /** + * Sets the list of URIs for all locations for the container. + * + * @param storageUri + * The list of URIs for all locations for the container. + */ protected void setStorageUri(final StorageUri storageUri) { this.storageUri = storageUri; } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobContainerPermissions.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobContainerPermissions.java similarity index 73% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobContainerPermissions.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobContainerPermissions.java index 248b2fde30a41..f6f1dc18dd808 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobContainerPermissions.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobContainerPermissions.java @@ -12,9 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; -import com.microsoft.windowsazure.storage.core.Permissions; +import com.microsoft.azure.storage.Permissions; /** * Represents the permissions for a container. @@ -30,12 +30,24 @@ * * For more information on managing container permissions, see Managing Access to Containers and Blobs. - * */ public final class BlobContainerPermissions extends Permissions { /** * Represents the public access setting for the container. + */ + private BlobContainerPublicAccessType publicAccess; + + /** + * Creates an instance of the BlobContainerPermissions class. + */ + public BlobContainerPermissions() { + super(); + this.setPublicAccess(BlobContainerPublicAccessType.OFF); + } + + /** + * Gets the public access setting for the container. *

* The public access setting indicates whether the container and its blobs can be read via an anonymous request. *

@@ -50,26 +62,25 @@ public final class BlobContainerPermissions extends PermissionsSetting Access Control for Containers. */ - private BlobContainerPublicAccessType publicAccess; - - /** - * Creates an instance of the BlobContainerPermissions class. - */ - public BlobContainerPermissions() { - super(); - this.setPublicAccess(BlobContainerPublicAccessType.OFF); - } - - /** - * @return the publicAccess - */ public BlobContainerPublicAccessType getPublicAccess() { return this.publicAccess; } /** - * @param publicAccess - * the publicAccess to set + * Sets the public access setting for the container. + *

+ * The public access setting indicates whether the container and its blobs can be read via an anonymous request. + *

+ * The {@link BlobContainerPublicAccessType} enumeration provides three levels of anonymous read access: + *

    + *
  • {@link BlobContainerPublicAccessType#OFF}, which prevents anonymous access.
  • + *
  • {@link BlobContainerPublicAccessType#BLOB}, which permits anonymous read access to blob resources, but not to + * container metadata or to the list of blobs in the container.
  • + *
  • {@link BlobContainerPublicAccessType#CONTAINER}, which permits anonymous read access to blob resources, + * container metadata, and the list of blobs in the container.
  • + *
+ * For more information on managing anonymous access to Blob service resources, see Setting Access Control for Containers. */ public void setPublicAccess(final BlobContainerPublicAccessType publicAccess) { this.publicAccess = publicAccess; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobContainerProperties.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobContainerProperties.java similarity index 81% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobContainerProperties.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobContainerProperties.java index 53d2e6af6b121..731ab19cd7ca4 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobContainerProperties.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobContainerProperties.java @@ -12,14 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import java.util.Date; -import com.microsoft.windowsazure.storage.AccessCondition; -import com.microsoft.windowsazure.storage.LeaseDuration; -import com.microsoft.windowsazure.storage.LeaseState; -import com.microsoft.windowsazure.storage.LeaseStatus; +import com.microsoft.azure.storage.AccessCondition; /** * Represents the system properties for a container. @@ -28,12 +25,6 @@ public final class BlobContainerProperties { /** * Represents the ETag value for the container. - *

- * The ETag value is a unique identifier that is updated when a write operation is performed against the container. - * It may be used to perform operations conditionally, providing concurrency control and improved efficiency. - *

- * The {@link AccessCondition#ifMatch} and {@link AccessCondition#ifNoneMatch} methods take an ETag value and return - * an {@link AccessCondition} object that may be specified on the request. */ private String etag; @@ -58,6 +49,14 @@ public final class BlobContainerProperties { private LeaseDuration leaseDuration; /** + * Gets the ETag value of the container. + *

+ * The ETag value is a unique identifier that is updated when a write operation is performed against the container. + * It may be used to perform operations conditionally, providing concurrency control and improved efficiency. + *

+ * The {@link AccessCondition#ifMatch} and {@link AccessCondition#ifNoneMatch} methods take an ETag value and return + * an {@link AccessCondition} object that may be specified on the request. + * * @return the etag */ public String getEtag() { @@ -65,6 +64,8 @@ public String getEtag() { } /** + * Gets the last modified time on the container. + * * @return the lastModified */ public Date getLastModified() { @@ -104,7 +105,7 @@ public LeaseDuration getLeaseDuration() { * @param etag * The ETag value to set, as a string. */ - public void setEtag(final String etag) { + protected void setEtag(final String etag) { this.etag = etag; } @@ -114,37 +115,37 @@ public void setEtag(final String etag) { * @param lastModified * The last modified time to set, as a Date object. */ - public void setLastModified(final Date lastModified) { + protected void setLastModified(final Date lastModified) { this.lastModified = lastModified; } /** - * Sets the lease status on the container. Reserved for internal use. + * Sets the lease status on the container. * * @param leaseStatus * The lease status to set, as a LeaseStatus object. */ - public void setLeaseStatus(final LeaseStatus leaseStatus) { + protected void setLeaseStatus(final LeaseStatus leaseStatus) { this.leaseStatus = leaseStatus; } /** - * Sets the lease status on the container. Reserved for internal use. + * Sets the lease status on the container. * * @param leaseState * The lease state to set, as a LeaseState object. */ - public void setLeaseState(final LeaseState leaseState) { + protected void setLeaseState(final LeaseState leaseState) { this.leaseState = leaseState; } /** - * Sets the lease duration on the container. Reserved for internal use. + * Sets the lease duration on the container. * * @param leaseDuration * The lease duration to set, as a LeaseDuration object. */ - public void setLeaseDuration(final LeaseDuration leaseDuration) { + protected void setLeaseDuration(final LeaseDuration leaseDuration) { this.leaseDuration = leaseDuration; } } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobContainerPublicAccessType.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobContainerPublicAccessType.java similarity index 57% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobContainerPublicAccessType.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobContainerPublicAccessType.java index 3e846165b94a6..a0f5ef7862a3a 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobContainerPublicAccessType.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobContainerPublicAccessType.java @@ -12,11 +12,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; /** * Specifies the level of public access that is allowed on the container. - * + *

+ * The public access setting indicates whether the container and its blobs can be read via an anonymous request. + *

+ * The {@link BlobContainerPublicAccessType} enumeration provides three levels of anonymous read access: + *

    + *
  • {@link BlobContainerPublicAccessType#OFF}, which prevents anonymous access.
  • + *
  • {@link BlobContainerPublicAccessType#BLOB}, which permits anonymous read access to blob resources, but not to + * container metadata or to the list of blobs in the container.
  • + *
  • {@link BlobContainerPublicAccessType#CONTAINER}, which permits anonymous read access to blob resources, container + * metadata, and the list of blobs in the container.
  • + *
+ * For more information on managing anonymous access to Blob service resources, see Setting Access Control for Containers. */ public enum BlobContainerPublicAccessType { /** diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobInputStream.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobInputStream.java similarity index 97% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobInputStream.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobInputStream.java index c03e748dc6b04..c3c50d64bc290 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobInputStream.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobInputStream.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -21,16 +21,16 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import com.microsoft.windowsazure.storage.AccessCondition; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.DoesServiceRequest; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageErrorCode; -import com.microsoft.windowsazure.storage.StorageErrorCodeStrings; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.core.Base64; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.AccessCondition; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.DoesServiceRequest; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.StorageErrorCode; +import com.microsoft.azure.storage.StorageErrorCodeStrings; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.core.Base64; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; /** * Provides an input stream to read a given blob resource. 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 new file mode 100644 index 0000000000000..ec1e66ec22242 --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobListHandler.java @@ -0,0 +1,310 @@ +/** + * 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 java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.text.ParseException; +import java.util.HashMap; +import java.util.Stack; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.core.ListResponse; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; + +/** + * RESERVED FOR INTERNAL USE. A class used to deserialize a list of blobs. + */ +final class BlobListHandler extends DefaultHandler { + + private final Stack elementStack = new Stack(); + private StringBuilder bld = new StringBuilder(); + + private final ListBlobsResponse response = new ListBlobsResponse(); + + private final CloudBlobContainer container; + + private BlobProperties properties; + private HashMap metadata; + private CopyState copyState; + private String blobName; + private String snapshotID; + + private BlobListHandler(CloudBlobContainer container) { + this.container = container; + } + + /** + * Parse and return the response. + * + * @param stream + * @param container + * @return + * @throws ParserConfigurationException + * @throws SAXException + * @throws IOException + */ + public static ListBlobsResponse getBlobList(final InputStream stream, final CloudBlobContainer container) + throws ParserConfigurationException, SAXException, IOException { + SAXParser saxParser = Utility.getSAXParser(); + BlobListHandler handler = new BlobListHandler(container); + saxParser.parse(stream, handler); + + return handler.response; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + this.elementStack.push(localName); + + if (BlobConstants.BLOB_ELEMENT.equals(localName) || BlobConstants.BLOB_PREFIX_ELEMENT.equals(localName)) { + this.blobName = Constants.EMPTY_STRING; + this.snapshotID = null; + this.properties = new BlobProperties(); + this.metadata = new HashMap(); + this.copyState = null; + } + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + String currentNode = this.elementStack.pop(); + + // if the node popped from the stack and the localName don't match, the xml document is improperly formatted + if (!localName.equals(currentNode)) { + throw new SAXException(SR.INVALID_RESPONSE_RECEIVED); + } + + String parentNode = null; + if (!this.elementStack.isEmpty()) { + parentNode = this.elementStack.peek(); + } + + String value = this.bld.toString(); + if (value.isEmpty()) { + value = null; + } + + if (BlobConstants.BLOB_ELEMENT.equals(currentNode)) { + CloudBlob retBlob = null; + try { + if (this.properties.getBlobType() == BlobType.BLOCK_BLOB) { + retBlob = this.container.getBlockBlobReference(this.blobName); + } + else if (this.properties.getBlobType() == BlobType.PAGE_BLOB) { + retBlob = this.container.getPageBlobReference(this.blobName); + } + else { + throw new SAXException(SR.INVALID_RESPONSE_RECEIVED); + } + } + catch (StorageException e) { + throw new SAXException(e); + } + catch (URISyntaxException e) { + throw new SAXException(e); + } + + retBlob.snapshotID = this.snapshotID; + retBlob.properties = this.properties; + retBlob.metadata = this.metadata; + retBlob.properties.setCopyState(this.copyState); + + this.response.getResults().add(retBlob); + } + else if (BlobConstants.BLOB_PREFIX_ELEMENT.equals(currentNode)) { + try { + this.response.getResults().add(this.container.getDirectoryReference(this.blobName)); + } + catch (URISyntaxException e) { + throw new SAXException(e); + } + } + else if (ListResponse.ENUMERATION_RESULTS.equals(parentNode)) { + if (Constants.PREFIX_ELEMENT.equals(currentNode)) { + this.response.setPrefix(value); + } + else if (Constants.MARKER_ELEMENT.equals(currentNode)) { + this.response.setMarker(value); + } + else if (Constants.NEXT_MARKER_ELEMENT.equals(currentNode)) { + this.response.setNextMarker(value); + } + else if (Constants.MAX_RESULTS_ELEMENT.equals(currentNode)) { + this.response.setMaxResults(Integer.parseInt(value)); + } + else if (Constants.DELIMITER_ELEMENT.equals(currentNode)) { + this.response.setDelimiter(value); + } + } + else if (BlobConstants.BLOB_ELEMENT.equals(parentNode)) { + if (Constants.NAME_ELEMENT.equals(currentNode)) { + this.blobName = value; + } + else if (BlobConstants.SNAPSHOT_ELEMENT.equals(currentNode)) { + this.snapshotID = value; + } + } + else if (BlobConstants.BLOB_PREFIX_ELEMENT.equals(parentNode)) { + // Blob or BlobPrefix + if (Constants.NAME_ELEMENT.equals(currentNode)) { + this.blobName = value; + } + } + else if (BlobConstants.PROPERTIES.equals(parentNode)) { + try { + this.setProperties(currentNode, value); + } + catch (ParseException e) { + throw new SAXException(e); + } + catch (URISyntaxException e) { + throw new SAXException(e); + } + } + else if (Constants.METADATA_ELEMENT.equals(parentNode)) { + this.metadata.put(currentNode, value); + } + + this.bld = new StringBuilder(); + } + + @Override + public void characters(char ch[], int start, int length) throws SAXException { + this.bld.append(ch, start, length); + } + + private void setProperties(String currentNode, String value) throws ParseException, URISyntaxException, + SAXException { + + if (Constants.LAST_MODIFIED_ELEMENT.equals(currentNode)) { + this.properties.setLastModified(Utility.parseRFC1123DateFromStringInGMT(value)); + } + else if (Constants.ETAG_ELEMENT.equals(currentNode)) { + this.properties.setEtag(Utility.formatETag(value)); + } + else if (Constants.HeaderConstants.CONTENT_LENGTH.equals(currentNode)) { + this.properties.setLength(Long.parseLong(value)); + } + else if (Constants.HeaderConstants.CONTENT_TYPE.equals(currentNode)) { + this.properties.setContentType(value); + } + else if (Constants.HeaderConstants.CONTENT_ENCODING.equals(currentNode)) { + this.properties.setContentEncoding(value); + } + else if (Constants.HeaderConstants.CONTENT_LANGUAGE.equals(currentNode)) { + this.properties.setContentLanguage(value); + } + else if (Constants.HeaderConstants.CONTENT_MD5.equals(currentNode)) { + this.properties.setContentMD5(value); + } + else if (Constants.HeaderConstants.CACHE_CONTROL.equals(currentNode)) { + this.properties.setCacheControl(value); + } + else if (Constants.HeaderConstants.CONTENT_DISPOSITION.equals(currentNode)) { + this.properties.setContentDisposition(value); + } + else if (BlobConstants.BLOB_TYPE_ELEMENT.equals(currentNode)) { + final String tempString = value; + if (tempString.equals(BlobConstants.BLOCK_BLOB_VALUE)) { + this.properties.setBlobType(BlobType.BLOCK_BLOB); + } + else if (tempString.equals(BlobConstants.PAGE_BLOB_VALUE.toString())) { + this.properties.setBlobType(BlobType.PAGE_BLOB); + } + else { + throw new SAXException(SR.INVALID_RESPONSE_RECEIVED); + } + } + else if (Constants.LEASE_STATUS_ELEMENT.equals(currentNode)) { + final LeaseStatus tempStatus = LeaseStatus.parse(value); + if (!tempStatus.equals(LeaseStatus.UNSPECIFIED)) { + this.properties.setLeaseStatus(tempStatus); + } + else { + throw new SAXException(SR.INVALID_RESPONSE_RECEIVED); + } + } + else if (Constants.LEASE_STATE_ELEMENT.equals(currentNode)) { + final LeaseState tempState = LeaseState.parse(value); + if (!tempState.equals(LeaseState.UNSPECIFIED)) { + this.properties.setLeaseState(tempState); + } + else { + throw new SAXException(SR.INVALID_RESPONSE_RECEIVED); + } + } + else if (Constants.LEASE_DURATION_ELEMENT.equals(currentNode)) { + final LeaseDuration tempDuration = LeaseDuration.parse(value); + if (!tempDuration.equals(LeaseDuration.UNSPECIFIED)) { + this.properties.setLeaseDuration(tempDuration); + } + else { + throw new SAXException(SR.INVALID_RESPONSE_RECEIVED); + } + } + else if (Constants.COPY_ID_ELEMENT.equals(currentNode)) { + if (this.copyState == null) { + this.copyState = new CopyState(); + } + this.copyState.setCopyId(value); + } + else if (Constants.COPY_COMPLETION_TIME_ELEMENT.equals(currentNode)) { + if (this.copyState == null) { + this.copyState = new CopyState(); + } + this.copyState.setCompletionTime(Utility.parseRFC1123DateFromStringInGMT(value)); + } + else if (Constants.COPY_STATUS_ELEMENT.equals(currentNode)) { + if (this.copyState == null) { + this.copyState = new CopyState(); + } + this.copyState.setStatus(CopyStatus.parse(value)); + } + else if (Constants.COPY_SOURCE_ELEMENT.equals(currentNode)) { + if (this.copyState == null) { + this.copyState = new CopyState(); + } + this.copyState.setSource(new URI(value)); + } + else if (Constants.COPY_PROGRESS_ELEMENT.equals(currentNode)) { + if (this.copyState == null) { + this.copyState = new CopyState(); + } + + final String tempString = value; + String[] progressSequence = tempString.split("/"); + this.copyState.setBytesCopied(Long.parseLong(progressSequence[0])); + this.copyState.setTotalBytes(Long.parseLong(progressSequence[1])); + } + else if (Constants.COPY_STATUS_DESCRIPTION_ELEMENT.equals(currentNode)) { + if (this.copyState == null) { + this.copyState = new CopyState(); + } + this.copyState.setStatusDescription(value); + } + } +} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobListingContext.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobListingContext.java similarity index 84% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobListingContext.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobListingContext.java index 47555a85c32cb..f29bbb904dc35 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobListingContext.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobListingContext.java @@ -12,11 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import java.util.EnumSet; -import com.microsoft.windowsazure.storage.core.ListingContext; +import com.microsoft.azure.storage.core.ListingContext; /** * RESERVED FOR INTERNAL USE. Provides the listing context for blobs including the delimiter and listingdetails @@ -49,7 +49,7 @@ final class BlobListingContext extends ListingContext { * @param listingDetails * the BlobListingDetails to use. */ - protected BlobListingContext(final String prefix, final Integer maxResults, final String delimiter, + BlobListingContext(final String prefix, final Integer maxResults, final String delimiter, final EnumSet listingDetails) { super(prefix, maxResults); this.setDelimiter(delimiter); @@ -59,14 +59,14 @@ protected BlobListingContext(final String prefix, final Integer maxResults, fina /** * @return the delimiter */ - protected String getDelimiter() { + String getDelimiter() { return this.delimiter; } /** * @return the listingDetails */ - protected EnumSet getListingDetails() { + EnumSet getListingDetails() { return this.listingDetails; } @@ -74,7 +74,7 @@ protected EnumSet getListingDetails() { * @param delimiter * the delimiter to set */ - protected void setDelimiter(final String delimiter) { + void setDelimiter(final String delimiter) { this.delimiter = delimiter; } @@ -82,7 +82,7 @@ protected void setDelimiter(final String delimiter) { * @param listingDetails * the listingDetails to set */ - protected void setListingDetails(final EnumSet listingDetails) { + void setListingDetails(final EnumSet listingDetails) { this.listingDetails = listingDetails; } } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobListingDetails.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobListingDetails.java similarity index 96% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobListingDetails.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobListingDetails.java index c52979920c9b7..8dfa24575ba28 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobListingDetails.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobListingDetails.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; /** * Specifies which items to include when listing a set of blobs. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobOutputStream.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobOutputStream.java similarity index 96% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobOutputStream.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobOutputStream.java index 486300704add1..e7c20939853f2 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobOutputStream.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobOutputStream.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -30,15 +30,13 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; -import javax.xml.stream.XMLStreamException; - -import com.microsoft.windowsazure.storage.AccessCondition; -import com.microsoft.windowsazure.storage.DoesServiceRequest; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.core.Base64; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.AccessCondition; +import com.microsoft.azure.storage.DoesServiceRequest; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.core.Base64; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; /** * The class is an append-only stream for writing into storage. @@ -302,10 +300,6 @@ public void close() throws IOException { * * @throws StorageException * an exception representing any error which occurred during the operation. - * @throws IOException - * if an I/O error occurs. In particular, an IOException may be thrown if the output stream has been - * closed. - * @throws XMLStreamException */ @DoesServiceRequest private void commit() throws StorageException { diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobProperties.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobProperties.java similarity index 87% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobProperties.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobProperties.java index bd0cf895f90f4..d0f250a4628a4 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobProperties.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobProperties.java @@ -12,14 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import java.util.Date; -import com.microsoft.windowsazure.storage.AccessCondition; -import com.microsoft.windowsazure.storage.LeaseDuration; -import com.microsoft.windowsazure.storage.LeaseState; -import com.microsoft.windowsazure.storage.LeaseStatus; +import com.microsoft.azure.storage.AccessCondition; /** * Represents the system properties for a blob. @@ -38,8 +35,7 @@ public final class BlobProperties { /** * Represents the content-disposition value stored for the blob. If this field has not been set for the blob, the - * field - * returns null. + * field returns null. */ private String contentDisposition; @@ -73,12 +69,6 @@ public final class BlobProperties { /** * Represents the blob's ETag value. - *

- * The ETag value is a unique identifier that is updated when a write operation is performed against the container. - * It may be used to perform operations conditionally, providing concurrency control and improved efficiency. - *

- * The {@link AccessCondition#ifMatch} and {@link AccessCondition#ifNoneMatch} methods take an ETag value and return - * an {@link AccessCondition} object that may be specified on the request. */ private String etag; @@ -90,7 +80,7 @@ public final class BlobProperties { /** * Represents the blob's lease status. */ - private LeaseStatus leaseStatus = com.microsoft.windowsazure.storage.LeaseStatus.UNLOCKED; + private LeaseStatus leaseStatus = LeaseStatus.UNLOCKED; /** * Represents the blob's lease state. @@ -146,7 +136,7 @@ public BlobProperties(final BlobType type) { } /** - * Returns the blob type for the blob. + * Gets the blob type for the blob. * * @return A {@link BlobType} value that represents the blob type. */ @@ -155,7 +145,7 @@ public BlobType getBlobType() { } /** - * Returns the cache control value for the blob. + * Gets the cache control value for the blob. * * @return A string that represents the cache control value for the blob. */ @@ -212,7 +202,7 @@ public String getContentType() { } /** - * Returns the blob's copy state. + * Gets the blob's copy state. * * @return A {@link CopyState} object that represents the copy state of the blob. */ @@ -222,6 +212,12 @@ public CopyState getCopyState() { /** * Gets the ETag value for the blob. + *

+ * The ETag value is a unique identifier that is updated when a write operation is performed against the container. + * It may be used to perform operations conditionally, providing concurrency control and improved efficiency. + *

+ * The {@link AccessCondition#ifMatch} and {@link AccessCondition#ifNoneMatch} methods take an ETag value and return + * an {@link AccessCondition} object that may be specified on the request. * * @return A string containing the ETag value. */ @@ -239,7 +235,7 @@ public Date getLastModified() { } /** - * Gets the lease status for the blob. Reserved for internal use. + * Gets the lease status for the blob. * * @return A LeaseStatus object representing the lease status. */ @@ -274,16 +270,6 @@ public long getLength() { return this.length; } - /** - * Sets the blob type. Reserved for internal use. - * - * @param blobType - * The blob type to set, represented by a BlobType object. - */ - protected void setBlobType(final BlobType blobType) { - this.blobType = blobType; - } - /** * Sets the cache control value for the blob. * @@ -345,72 +331,82 @@ public void setContentType(final String contentType) { } /** - * Reserved for internal use. + * Sets the blob type. + * + * @param blobType + * The blob type to set, represented by a BlobType object. + */ + protected void setBlobType(final BlobType blobType) { + this.blobType = blobType; + } + + /** + * Sets the copy state value for the blob * * @param copyState * the copyState to set */ - public void setCopyState(final CopyState copyState) { + protected void setCopyState(final CopyState copyState) { this.copyState = copyState; } /** - * Sets the ETag value for the blob. Reserved for internal use. + * Sets the ETag value for the blob. * * @param etag * The ETag value to set. */ - public void setEtag(final String etag) { + protected void setEtag(final String etag) { this.etag = etag; } /** - * Sets the last modified time for the blob. Reserved for internal use. + * Sets the last modified time for the blob. * * @param lastModified * The last modified time to set. */ - public void setLastModified(final Date lastModified) { + protected void setLastModified(final Date lastModified) { this.lastModified = lastModified; } /** - * Sets the lease status for the blob. Reserved for internal use. + * Sets the lease status for the blob. * * @param leaseStatus * The lease status to set, represented by a LeaseStatus object. */ - public void setLeaseStatus(final LeaseStatus leaseStatus) { + protected void setLeaseStatus(final LeaseStatus leaseStatus) { this.leaseStatus = leaseStatus; } /** - * Sets the lease state for the blob. Reserved for internal use. + * Sets the lease state for the blob. * * @param leaseState * The lease state to set, represented by a LeaseState object. */ - public void setLeaseState(final LeaseState leaseState) { + protected void setLeaseState(final LeaseState leaseState) { this.leaseState = leaseState; } /** - * Sets the lease duration for the blob. Reserved for internal use. + * Sets the lease duration for the blob. * * @param leaseDuration * The lease duration value to set, represented by a LeaseDuration object. */ - public void setLeaseDuration(final LeaseDuration leaseDuration) { + protected void setLeaseDuration(final LeaseDuration leaseDuration) { this.leaseDuration = leaseDuration; } /** - * Sets the content length, in bytes, for the blob. Reserved for internal use. + * Sets the content length, in bytes, for the blob. * * @param length * The length to set. */ - public void setLength(final long length) { + protected void setLength(final long length) { this.length = length; } diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobRequest.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobRequest.java new file mode 100644 index 0000000000000..a6cc5e823ba7c --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobRequest.java @@ -0,0 +1,1468 @@ +/** + * 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 java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.HashMap; + +import com.microsoft.azure.storage.AccessCondition; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.Constants.HeaderConstants; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.core.BaseRequest; +import com.microsoft.azure.storage.core.ListingContext; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.UriQueryBuilder; +import com.microsoft.azure.storage.core.Utility; + +/** + * RESERVED FOR INTERNAL USE. Provides a set of methods for constructing requests for blob operations. + */ +final class BlobRequest { + + private static final String BLOCK_QUERY_ELEMENT_NAME = "block"; + + private static final String BLOCK_ID_QUERY_ELEMENT_NAME = "blockid"; + + private static final String BLOCK_LIST_QUERY_ELEMENT_NAME = "blocklist"; + + private static final String BLOCK_LIST_TYPE_QUERY_ELEMENT_NAME = "blocklisttype"; + + private static final String COPY_QUERY_ELEMENT_NAME = "copy"; + + private static final String PAGE_QUERY_ELEMENT_NAME = "page"; + + private static final String PAGE_LIST_QUERY_ELEMENT_NAME = "pagelist"; + + private static final String SNAPSHOTS_QUERY_ELEMENT_NAME = "snapshots"; + + private static final String UNCOMMITTED_BLOBS_QUERY_ELEMENT_NAME = "uncommittedblobs"; + + /** + * Generates a web request to abort a copy operation. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * The access condition to apply to the request. Only lease conditions are supported for this operation. + * @param copyId + * A String object that identifying the copy operation. + * @return a HttpURLConnection configured for the operation. + * @throws StorageException + * an exception representing any error which occurred during the operation. + * @throws IllegalArgumentException + * @throws IOException + * @throws URISyntaxException + */ + public static HttpURLConnection abortCopy(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition accessCondition, final String copyId) + throws StorageException, IOException, URISyntaxException { + + final UriQueryBuilder builder = new UriQueryBuilder(); + + builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.COPY); + builder.add(Constants.QueryConstants.COPY_ID, copyId); + + final HttpURLConnection request = BaseRequest.createURLConnection(uri, blobOptions, builder, opContext); + + request.setFixedLengthStreamingMode(0); + request.setDoOutput(true); + request.setRequestMethod(Constants.HTTP_PUT); + + request.setRequestProperty(Constants.HeaderConstants.COPY_ACTION_HEADER, + Constants.HeaderConstants.COPY_ACTION_ABORT); + + if (accessCondition != null) { + accessCondition.applyConditionToRequest(request, true); + } + + return request; + } + + /** + * Adds the metadata. + * + * @param request + * The request. + * @param metadata + * The metadata. + */ + public static void addMetadata(final HttpURLConnection request, final HashMap metadata, + final OperationContext opContext) { + BaseRequest.addMetadata(request, metadata, opContext); + } + + /** + * Adds the metadata. + * + * @param request + * The request. + * @param name + * The metadata name. + * @param value + * The metadata value. + */ + private static void addProperties(final HttpURLConnection request, BlobProperties properties) { + BaseRequest.addOptionalHeader(request, Constants.HeaderConstants.CACHE_CONTROL_HEADER, + properties.getCacheControl()); + BaseRequest.addOptionalHeader(request, BlobConstants.CONTENT_DISPOSITION_HEADER, + properties.getContentDisposition()); + BaseRequest.addOptionalHeader(request, BlobConstants.CONTENT_ENCODING_HEADER, properties.getContentEncoding()); + BaseRequest.addOptionalHeader(request, BlobConstants.CONTENT_LANGUAGE_HEADER, properties.getContentLanguage()); + BaseRequest.addOptionalHeader(request, BlobConstants.BLOB_CONTENT_MD5_HEADER, properties.getContentMD5()); + BaseRequest.addOptionalHeader(request, BlobConstants.CONTENT_TYPE_HEADER, properties.getContentType()); + } + + /** + * Adds the snapshot. + * + * @param builder + * a query builder. + * @param snapshotVersion + * the snapshot version to the query builder. + * @throws StorageException + */ + private static void addSnapshot(final UriQueryBuilder builder, final String snapshotVersion) + throws StorageException { + if (snapshotVersion != null) { + builder.add(Constants.QueryConstants.SNAPSHOT, snapshotVersion); + } + } + + /** + * Creates a request to copy a blob, Sign with 0 length. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param source + * The canonical path to the source blob, in the form ///. + * @param sourceSnapshotID + * The snapshot version, if the source blob is a snapshot. + * @param sourceAccessConditionType + * A type of condition to check on the source blob. + * @param sourceAccessConditionValue + * The value of the condition to check on the source blob + * @return a HttpURLConnection configured for the operation. + * @throws StorageException + * an exception representing any error which occurred during the operation. + * @throws IllegalArgumentException + * @throws IOException + * @throws URISyntaxException + */ + public static HttpURLConnection copyFrom(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition sourceAccessCondition, + final AccessCondition destinationAccessCondition, String source, final String sourceSnapshotID) + throws StorageException, IOException, URISyntaxException { + + if (sourceSnapshotID != null) { + source = source.concat("?snapshot="); + source = source.concat(sourceSnapshotID); + } + + final HttpURLConnection request = BaseRequest.createURLConnection(uri, blobOptions, null, opContext); + + request.setFixedLengthStreamingMode(0); + request.setDoOutput(true); + request.setRequestMethod(Constants.HTTP_PUT); + + request.setRequestProperty(Constants.HeaderConstants.COPY_SOURCE_HEADER, source); + + if (sourceAccessCondition != null) { + sourceAccessCondition.applyConditionToRequest(request, true); + } + + if (destinationAccessCondition != null) { + destinationAccessCondition.applyConditionToRequest(request); + } + + return request; + } + + /** + * Constructs a web request to create a new container. Sign with 0 length. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @return a HttpURLConnection configured for the operation. + * @throws StorageException + * @throws IllegalArgumentException + */ + public static HttpURLConnection createContainer(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext) throws IOException, URISyntaxException, StorageException { + final UriQueryBuilder containerBuilder = getContainerUriQueryBuilder(); + return BaseRequest.create(uri, blobOptions, containerBuilder, opContext); + } + + /** + * Creates the web request. + * + * @param uri + * The absolute URI to the container. + * @param timeout + * The server timeout interval. + * @param query + * The query builder to use. + * @param blobOptions + * the options to use for the request. + * @param opContext + * a tracking object for the request + * @return a HttpURLConnection configured for the operation. + * @throws StorageException + * an exception representing any error which occurred during the operation. + * @throws IllegalArgumentException + */ + private static HttpURLConnection createURLConnection(final URI uri, final UriQueryBuilder query, + final BlobRequestOptions blobOptions, final OperationContext opContext) throws IOException, + URISyntaxException, StorageException { + return BaseRequest.createURLConnection(uri, blobOptions, query, opContext); + } + + /** + * Constructs a HttpURLConnection to delete the blob, Sign with no length specified. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the blob. + * @param snapshotVersion + * The snapshot version, if the blob is a snapshot. + * @param deleteSnapshotsOption + * A set of options indicating whether to delete only blobs, only snapshots, or both. + * @return a HttpURLConnection to use to perform the operation. + * @throws IOException + * if there is an error opening the connection + * @throws URISyntaxException + * if the resource URI is invalid + * @throws StorageException + * an exception representing any error which occurred during the operation. + * @throws IllegalArgumentException + */ + public static HttpURLConnection deleteBlob(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition accessCondition, final String snapshotVersion, + final DeleteSnapshotsOption deleteSnapshotsOption) throws IOException, URISyntaxException, StorageException { + + if (snapshotVersion != null && deleteSnapshotsOption != DeleteSnapshotsOption.NONE) { + throw new IllegalArgumentException(String.format(SR.DELETE_SNAPSHOT_NOT_VALID_ERROR, + "deleteSnapshotsOption", "snapshot")); + } + + final UriQueryBuilder builder = new UriQueryBuilder(); + BlobRequest.addSnapshot(builder, snapshotVersion); + final HttpURLConnection request = BaseRequest.delete(uri, blobOptions, builder, opContext); + + if (accessCondition != null) { + accessCondition.applyConditionToRequest(request); + } + + switch (deleteSnapshotsOption) { + case NONE: + // nop + break; + case INCLUDE_SNAPSHOTS: + request.setRequestProperty(Constants.HeaderConstants.DELETE_SNAPSHOT_HEADER, + BlobConstants.INCLUDE_SNAPSHOTS_VALUE); + break; + case DELETE_SNAPSHOTS_ONLY: + request.setRequestProperty(Constants.HeaderConstants.DELETE_SNAPSHOT_HEADER, + BlobConstants.SNAPSHOTS_ONLY_VALUE); + break; + default: + break; + } + + return request; + } + + /** + * Constructs a web request to delete the container and all of blobs within it. Sign with no length specified. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the container. + * @return a HttpURLConnection configured for the operation. + * @throws StorageException + * @throws IllegalArgumentException + */ + public static HttpURLConnection deleteContainer(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition accessCondition) throws IOException, + URISyntaxException, StorageException { + final UriQueryBuilder containerBuilder = getContainerUriQueryBuilder(); + HttpURLConnection request = BaseRequest.delete(uri, blobOptions, containerBuilder, opContext); + if (accessCondition != null) { + accessCondition.applyConditionToRequest(request); + } + + return request; + } + + /** + * Constructs a web request to return the ACL for this container. Sign with no length specified. + * + * @param uri + * The absolute URI to the container. + * @param timeout + * The server timeout interval. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the container. + * @param opContext + * An {@link OperationContext} object that 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. + * @return a HttpURLConnection configured for the operation. + * @throws StorageException + */ + public static HttpURLConnection getAcl(final URI uri, final BlobRequestOptions blobOptions, + final AccessCondition accessCondition, final OperationContext opContext) throws IOException, + URISyntaxException, StorageException { + final UriQueryBuilder builder = getContainerUriQueryBuilder(); + builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.ACL); + + final HttpURLConnection request = createURLConnection(uri, builder, blobOptions, opContext); + + request.setRequestMethod(Constants.HTTP_GET); + + if (accessCondition != null && !Utility.isNullOrEmpty(accessCondition.getLeaseID())) { + BaseRequest.addLeaseId(request, accessCondition.getLeaseID()); + } + + return request; + } + + /** + * Constructs a HttpURLConnection to download the blob, Sign with no length specified. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the blob. + * @param snapshotVersion + * The snapshot version, if the blob is a snapshot. + * @param offset + * The offset at which to begin returning content. + * @param count + * The number of bytes to return. + * @param requestRangeContentMD5 + * If set to true, request an MD5 header for the specified range. + * @return a HttpURLConnection to use to perform the operation. + * @throws IOException + * if there is an error opening the connection + * @throws URISyntaxException + * if the resource URI is invalid + * @throws StorageException + * an exception representing any error which occurred during the operation. + * @throws IllegalArgumentException + */ + public static HttpURLConnection getBlob(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition accessCondition, final String snapshotVersion, + final Long offset, final Long count, boolean requestRangeContentMD5) throws IOException, + URISyntaxException, StorageException { + + if (offset != null && requestRangeContentMD5) { + Utility.assertNotNull("count", count); + Utility.assertInBounds("count", count, 1, Constants.MAX_BLOCK_SIZE); + } + + final UriQueryBuilder builder = new UriQueryBuilder(); + BlobRequest.addSnapshot(builder, snapshotVersion); + final HttpURLConnection request = BaseRequest.createURLConnection(uri, blobOptions, builder, opContext); + request.setRequestMethod(Constants.HTTP_GET); + + if (accessCondition != null) { + accessCondition.applyConditionToRequest(request); + } + + if (offset != null) { + long rangeStart = offset; + long rangeEnd; + if (count != null) { + rangeEnd = offset + count - 1; + request.setRequestProperty(Constants.HeaderConstants.STORAGE_RANGE_HEADER, String.format( + Utility.LOCALE_US, Constants.HeaderConstants.RANGE_HEADER_FORMAT, rangeStart, rangeEnd)); + } + else { + request.setRequestProperty(Constants.HeaderConstants.STORAGE_RANGE_HEADER, String.format( + Utility.LOCALE_US, Constants.HeaderConstants.BEGIN_RANGE_HEADER_FORMAT, rangeStart)); + } + } + + if (offset != null && requestRangeContentMD5) { + request.setRequestProperty(Constants.HeaderConstants.RANGE_GET_CONTENT_MD5, Constants.TRUE); + } + + return request; + } + + /** + * Constructs a HttpURLConnection to return the blob's system properties, Sign with no length specified. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the blob. + * @param snapshotVersion + * The snapshot version, if the blob is a snapshot. + * @return a HttpURLConnection to use to perform the operation. + * @throws IOException + * if there is an error opening the connection + * @throws URISyntaxException + * if the resource URI is invalid + * @throws StorageException + * an exception representing any error which occurred during the operation. + * @throws IllegalArgumentException + */ + public static HttpURLConnection getBlobProperties(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition accessCondition, final String snapshotVersion) + throws StorageException, IOException, URISyntaxException { + final UriQueryBuilder builder = new UriQueryBuilder(); + BlobRequest.addSnapshot(builder, snapshotVersion); + return getProperties(uri, blobOptions, opContext, accessCondition, builder); + } + + /** + * Constructs a HttpURLConnection to return a list of the block blobs blocks. Sign with no length specified. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the blob. + * @param snapshotVersion + * The snapshot version, if the blob is a snapshot. + * @param blockFilter + * The types of blocks to include in the list: committed, uncommitted, or both. + * @return a HttpURLConnection to use to perform the operation. + * @throws IOException + * if there is an error opening the connection + * @throws URISyntaxException + * if the resource URI is invalid + * @throws StorageException + * an exception representing any error which occurred during the operation. + * @throws IllegalArgumentException + */ + public static HttpURLConnection getBlockList(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition accessCondition, final String snapshotVersion, + final BlockListingFilter blockFilter) throws StorageException, IOException, URISyntaxException { + + final UriQueryBuilder builder = new UriQueryBuilder(); + + builder.add(Constants.QueryConstants.COMPONENT, BLOCK_LIST_QUERY_ELEMENT_NAME); + builder.add(BLOCK_LIST_TYPE_QUERY_ELEMENT_NAME, blockFilter.toString()); + BlobRequest.addSnapshot(builder, snapshotVersion); + + final HttpURLConnection request = BaseRequest.createURLConnection(uri, blobOptions, builder, opContext); + request.setRequestMethod(Constants.HTTP_GET); + + if (accessCondition != null) { + accessCondition.applyConditionToRequest(request); + } + + return request; + } + + /** + * Constructs a web request to return the user-defined metadata for this container. Sign with no length specified. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the container. + * @return a HttpURLConnection configured for the operation. + * @throws StorageException + * */ + public static HttpURLConnection getContainerProperties(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, AccessCondition accessCondition) throws IOException, URISyntaxException, + StorageException { + final UriQueryBuilder containerBuilder = getContainerUriQueryBuilder(); + return getProperties(uri, blobOptions, opContext, accessCondition, containerBuilder); + } + + /** + * Gets the container Uri query builder. + * + * A UriQueryBuilder for the container. + * + * @throws StorageException + */ + private static UriQueryBuilder getContainerUriQueryBuilder() throws StorageException { + final UriQueryBuilder uriBuilder = new UriQueryBuilder(); + try { + uriBuilder.add(Constants.QueryConstants.RESOURCETYPE, "container"); + } + catch (final IllegalArgumentException e) { + throw Utility.generateNewUnexpectedStorageException(e); + } + return uriBuilder; + } + + /** + * Constructs a HttpURLConnection to return a list of the PageBlob's page ranges. Sign with no length specified. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the blob. + * @param snapshotVersion + * The snapshot version, if the blob is a snapshot. + * @return a HttpURLConnection to use to perform the operation. + * @throws IOException + * if there is an error opening the connection + * @throws URISyntaxException + * if the resource URI is invalid + * @throws StorageException + * an exception representing any error which occurred during the operation. + * @throws IllegalArgumentException + */ + public static HttpURLConnection getPageRanges(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition accessCondition, final String snapshotVersion) + throws StorageException, IOException, URISyntaxException { + + final UriQueryBuilder builder = new UriQueryBuilder(); + builder.add(Constants.QueryConstants.COMPONENT, PAGE_LIST_QUERY_ELEMENT_NAME); + BlobRequest.addSnapshot(builder, snapshotVersion); + + final HttpURLConnection request = createURLConnection(uri, builder, blobOptions, opContext); + request.setRequestMethod(Constants.HTTP_GET); + + if (accessCondition != null) { + accessCondition.applyConditionToRequest(request); + } + + BaseRequest.addOptionalHeader(request, BlobConstants.SNAPSHOT, snapshotVersion); + return request; + } + + /** + * Constructs a web request to return the user-defined metadata for this container. Sign with no length specified. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the container. + * @return a HttpURLConnection configured for the operation. + * @throws StorageException + * */ + private static HttpURLConnection getProperties(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, AccessCondition accessCondition, final UriQueryBuilder builder) + throws IOException, URISyntaxException, StorageException { + HttpURLConnection request = BaseRequest.getProperties(uri, blobOptions, builder, opContext); + + if (accessCondition != null && !Utility.isNullOrEmpty(accessCondition.getLeaseID())) { + BaseRequest.addLeaseId(request, accessCondition.getLeaseID()); + } + + return request; + } + + /** + * Constructs a HttpURLConnection to Acquire,Release,Break, or Renew a blob/container lease. Sign with 0 length. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the blob. + * @param action + * the LeaseAction to perform + * @param proposedLeaseId + * A String that represents the proposed lease ID for the new lease, + * or null if no lease ID is proposed. + * @param breakPeriodInSeconds + * Specifies the amount of time to allow the lease to remain, in seconds. + * If null, the break period is the remainder of the current lease, or zero for infinite leases. + * @param visibilityTimeoutInSeconds + * Specifies the the span of time for which to acquire the lease, in seconds. + * If null, an infinite lease will be acquired. If not null, this must be greater than zero. + * @return a HttpURLConnection to use to perform the operation. + * @throws IOException + * if there is an error opening the connection + * @throws URISyntaxException + * if the resource URI is invalid + * @throws StorageException + * an exception representing any error which occurred during the operation. + * @throws IllegalArgumentException + */ + private static HttpURLConnection lease(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition accessCondition, final LeaseAction action, + final Integer leaseTimeInSeconds, final String proposedLeaseId, final Integer breakPeriodInSeconds, + final UriQueryBuilder builder) throws IOException, URISyntaxException, StorageException { + final HttpURLConnection request = createURLConnection(uri, builder, blobOptions, opContext); + + request.setDoOutput(true); + request.setRequestMethod(Constants.HTTP_PUT); + request.setFixedLengthStreamingMode(0); + request.setRequestProperty(HeaderConstants.LEASE_ACTION_HEADER, action.toString()); + + request.setRequestProperty(HeaderConstants.LEASE_DURATION, leaseTimeInSeconds == null ? "-1" + : leaseTimeInSeconds.toString()); + + if (proposedLeaseId != null) { + request.setRequestProperty(HeaderConstants.PROPOSED_LEASE_ID_HEADER, proposedLeaseId); + } + + if (breakPeriodInSeconds != null) { + request.setRequestProperty(HeaderConstants.LEASE_BREAK_PERIOD_HEADER, breakPeriodInSeconds.toString()); + } + + if (accessCondition != null) { + accessCondition.applyConditionToRequest(request); + } + return request; + } + + /** + * Constructs a HttpURLConnection to Acquire,Release,Break, or Renew a blob lease. Sign with 0 length. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the blob. + * @param action + * the LeaseAction to perform + * @param proposedLeaseId + * A String that represents the proposed lease ID for the new lease, + * or null if no lease ID is proposed. + * @param breakPeriodInSeconds + * Specifies the amount of time to allow the lease to remain, in seconds. + * If null, the break period is the remainder of the current lease, or zero for infinite leases. + * @param visibilityTimeoutInSeconds + * Specifies the the span of time for which to acquire the lease, in seconds. + * If null, an infinite lease will be acquired. If not null, this must be greater than zero. + * @return a HttpURLConnection to use to perform the operation. + * @throws IOException + * if there is an error opening the connection + * @throws URISyntaxException + * if the resource URI is invalid + * @throws StorageException + * an exception representing any error which occurred during the operation. + * @throws IllegalArgumentException + */ + public static HttpURLConnection leaseBlob(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition accessCondition, final LeaseAction action, + final Integer leaseTimeInSeconds, final String proposedLeaseId, final Integer breakPeriodInSeconds) + throws IOException, URISyntaxException, StorageException { + UriQueryBuilder builder = new UriQueryBuilder(); + builder.add(Constants.QueryConstants.COMPONENT, BlobConstants.LEASE); + + return lease(uri, blobOptions, opContext, accessCondition, action, leaseTimeInSeconds, proposedLeaseId, + breakPeriodInSeconds, builder); + } + + /** + * Constructs a HttpURLConnection to Acquire,Release,Break, or Renew a container lease. Sign with 0 length. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the container. + * @param action + * the LeaseAction to perform + * @param proposedLeaseId + * A String that represents the proposed lease ID for the new lease, + * or null if no lease ID is proposed. + * @param breakPeriodInSeconds + * Specifies the amount of time to allow the lease to remain, in seconds. + * If null, the break period is the remainder of the current lease, or zero for infinite leases. + * @param visibilityTimeoutInSeconds + * Specifies the the span of time for which to acquire the lease, in seconds. + * If null, an infinite lease will be acquired. If not null, this must be greater than zero. + * @return a HttpURLConnection to use to perform the operation. + * @throws IOException + * if there is an error opening the connection + * @throws URISyntaxException + * if the resource URI is invalid + * @throws StorageException + * an exception representing any error which occurred during the operation. + * @throws IllegalArgumentException + */ + public static HttpURLConnection leaseContainer(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition accessCondition, final LeaseAction action, + final Integer leaseTimeInSeconds, final String proposedLeaseId, final Integer breakPeriodInSeconds) + throws IOException, URISyntaxException, StorageException { + + final UriQueryBuilder builder = getContainerUriQueryBuilder(); + builder.add(Constants.QueryConstants.COMPONENT, BlobConstants.LEASE); + + return lease(uri, blobOptions, opContext, accessCondition, action, leaseTimeInSeconds, proposedLeaseId, + breakPeriodInSeconds, builder); + } + + /** + * Constructs a HttpURLConnection to list blobs. Sign with no length specified. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param listingContext + * A set of parameters for the listing operation. + * @return a HttpURLConnection configured for the operation. + * @throws IOException + * if there is an error opening the connection + * @throws URISyntaxException + * if the resource URI is invalid + * @throws StorageException + * an exception representing any error which occurred during the operation. + * @throws IllegalArgumentException + * */ + public static HttpURLConnection listBlobs(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final BlobListingContext listingContext) throws URISyntaxException, + IOException, StorageException { + + final UriQueryBuilder builder = getContainerUriQueryBuilder(); + builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.LIST); + + if (listingContext != null) { + if (!Utility.isNullOrEmpty(listingContext.getPrefix())) { + builder.add(Constants.QueryConstants.PREFIX, listingContext.getPrefix()); + } + + if (!Utility.isNullOrEmpty(listingContext.getDelimiter())) { + builder.add(Constants.QueryConstants.DELIMITER, listingContext.getDelimiter()); + } + + if (!Utility.isNullOrEmpty(listingContext.getMarker())) { + builder.add(Constants.QueryConstants.MARKER, listingContext.getMarker()); + } + + if (listingContext.getMaxResults() != null && listingContext.getMaxResults() > 0) { + builder.add(Constants.QueryConstants.MAX_RESULTS, listingContext.getMaxResults().toString()); + } + + if (listingContext.getListingDetails().size() > 0) { + final StringBuilder sb = new StringBuilder(); + + boolean started = false; + + if (listingContext.getListingDetails().contains(BlobListingDetails.SNAPSHOTS)) { + if (!started) { + started = true; + } + else { + sb.append(","); + } + + sb.append(SNAPSHOTS_QUERY_ELEMENT_NAME); + } + + if (listingContext.getListingDetails().contains(BlobListingDetails.UNCOMMITTED_BLOBS)) { + if (!started) { + started = true; + } + else { + sb.append(","); + } + + sb.append(UNCOMMITTED_BLOBS_QUERY_ELEMENT_NAME); + } + + if (listingContext.getListingDetails().contains(BlobListingDetails.COPY)) { + if (!started) { + started = true; + } + else { + sb.append(","); + } + + sb.append(COPY_QUERY_ELEMENT_NAME); + } + + if (listingContext.getListingDetails().contains(BlobListingDetails.METADATA)) { + if (!started) { + started = true; + } + else { + sb.append(","); + } + + sb.append(Constants.QueryConstants.METADATA); + } + + builder.add(Constants.QueryConstants.INCLUDE, sb.toString()); + } + } + + final HttpURLConnection request = createURLConnection(uri, builder, blobOptions, opContext); + + request.setRequestMethod(Constants.HTTP_GET); + + return request; + } + + /** + * Constructs a request to return a listing of all containers in this storage account. Sign with no length + * specified. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param listingContext + * A set of parameters for the listing operation. + * @param detailsIncluded + * Additional details to return with the listing. + * @return a HttpURLConnection configured for the operation. + * @throws IOException + * @throws URISyntaxException + * @throws StorageException + * @throws IllegalArgumentException + */ + public static HttpURLConnection listContainers(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final ListingContext listingContext, + final ContainerListingDetails detailsIncluded) throws URISyntaxException, IOException, StorageException { + + final UriQueryBuilder builder = getContainerUriQueryBuilder(); + builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.LIST); + + if (listingContext != null) { + if (!Utility.isNullOrEmpty(listingContext.getPrefix())) { + builder.add(Constants.QueryConstants.PREFIX, listingContext.getPrefix()); + } + + if (!Utility.isNullOrEmpty(listingContext.getMarker())) { + builder.add(Constants.QueryConstants.MARKER, listingContext.getMarker()); + } + + if (listingContext.getMaxResults() != null && listingContext.getMaxResults() > 0) { + builder.add(Constants.QueryConstants.MAX_RESULTS, listingContext.getMaxResults().toString()); + } + } + + if (detailsIncluded == ContainerListingDetails.ALL || detailsIncluded == ContainerListingDetails.METADATA) { + builder.add(Constants.QueryConstants.INCLUDE, Constants.QueryConstants.METADATA); + } + + final HttpURLConnection request = createURLConnection(uri, builder, blobOptions, opContext); + + request.setRequestMethod(Constants.HTTP_GET); + + return request; + } + + /** + * Constructs a HttpURLConnection to upload a blob. Sign with blob length, or -1 for pageblob create. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the blob. + * @param properties + * The properties to set for the blob. + * @param blobType + * The type of the blob. + * @param pageBlobSize + * For a page blob, the size of the blob. This parameter is ignored for block blobs. + * @return a HttpURLConnection to use to perform the operation. + * @throws IOException + * if there is an error opening the connection + * @throws URISyntaxException + * if the resource URI is invalid + * @throws StorageException + * an exception representing any error which occurred during the operation. + * @throws IllegalArgumentException + */ + public static HttpURLConnection putBlob(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition accessCondition, final BlobProperties properties, + final BlobType blobType, final long pageBlobSize) throws IOException, URISyntaxException, StorageException { + if (blobType == BlobType.UNSPECIFIED) { + throw new IllegalArgumentException(SR.BLOB_TYPE_NOT_DEFINED); + } + + final HttpURLConnection request = createURLConnection(uri, null, blobOptions, opContext); + + request.setDoOutput(true); + + request.setRequestMethod(Constants.HTTP_PUT); + + addProperties(request, properties); + + if (blobType == BlobType.PAGE_BLOB) { + request.setFixedLengthStreamingMode(0); + request.setRequestProperty(Constants.HeaderConstants.CONTENT_LENGTH, "0"); + + request.setRequestProperty(BlobConstants.BLOB_TYPE_HEADER, BlobConstants.PAGE_BLOB); + request.setRequestProperty(BlobConstants.SIZE, String.valueOf(pageBlobSize)); + + properties.setLength(pageBlobSize); + } + else { + request.setRequestProperty(BlobConstants.BLOB_TYPE_HEADER, BlobConstants.BLOCK_BLOB); + } + + if (accessCondition != null) { + accessCondition.applyConditionToRequest(request); + } + + return request; + } + + /** + * Constructs a HttpURLConnection to upload a block. Sign with length of block data. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the blob. + * @param blockId + * the Base64 ID for the block + * @return a HttpURLConnection to use to perform the operation. + * @throws IOException + * if there is an error opening the connection + * @throws URISyntaxException + * if the resource URI is invalid + * @throws StorageException + * an exception representing any error which occurred during the operation. + * @throws IllegalArgumentException + */ + public static HttpURLConnection putBlock(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition accessCondition, final String blockId) + throws IOException, URISyntaxException, StorageException { + final UriQueryBuilder builder = new UriQueryBuilder(); + builder.add(Constants.QueryConstants.COMPONENT, BLOCK_QUERY_ELEMENT_NAME); + builder.add(BLOCK_ID_QUERY_ELEMENT_NAME, blockId); + + final HttpURLConnection request = createURLConnection(uri, builder, blobOptions, opContext); + + request.setDoOutput(true); + request.setRequestMethod(Constants.HTTP_PUT); + + if (accessCondition != null) { + accessCondition.applyConditionToRequest(request); + } + + return request; + } + + /** + * Constructs a HttpURLConnection to write a blob by specifying the list of block IDs that make up the blob. Sign + * with length of block list data. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the blob. + * @return a HttpURLConnection to use to perform the operation. + * @throws IOException + * if there is an error opening the connection + * @throws URISyntaxException + * if the resource URI is invalid + * @throws StorageException + * an exception representing any error which occurred during the operation. + * @throws IllegalArgumentException + */ + public static HttpURLConnection putBlockList(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition accessCondition, final BlobProperties properties) + throws IOException, URISyntaxException, StorageException { + + final UriQueryBuilder builder = new UriQueryBuilder(); + builder.add(Constants.QueryConstants.COMPONENT, BLOCK_LIST_QUERY_ELEMENT_NAME); + + final HttpURLConnection request = createURLConnection(uri, builder, blobOptions, opContext); + + request.setDoOutput(true); + request.setRequestMethod(Constants.HTTP_PUT); + + if (accessCondition != null) { + accessCondition.applyConditionToRequest(request); + } + + addProperties(request, properties); + + return request; + } + + /** + * Constructs a HttpURLConnection to upload a page. Sign with page length for update, or 0 for clear. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the blob. + * @param properties + * the page properties + * @return a HttpURLConnection to use to perform the operation. + * @throws IOException + * if there is an error opening the connection + * @throws URISyntaxException + * if the resource URI is invalid + * @throws StorageException + * an exception representing any error which occurred during the operation. + * @throws IllegalArgumentException + */ + public static HttpURLConnection putPage(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition accessCondition, final PageProperties properties) + throws IOException, URISyntaxException, StorageException { + final UriQueryBuilder builder = new UriQueryBuilder(); + builder.add(Constants.QueryConstants.COMPONENT, PAGE_QUERY_ELEMENT_NAME); + + final HttpURLConnection request = createURLConnection(uri, builder, blobOptions, opContext); + + request.setDoOutput(true); + request.setRequestMethod(Constants.HTTP_PUT); + + if (properties.getPageOperation() == PageOperationType.CLEAR) { + request.setFixedLengthStreamingMode(0); + } + + // Page write is either update or clean; required + request.setRequestProperty(BlobConstants.PAGE_WRITE, properties.getPageOperation().toString()); + request.setRequestProperty(Constants.HeaderConstants.STORAGE_RANGE_HEADER, properties.getRange().toString()); + + if (accessCondition != null) { + accessCondition.applyConditionToRequest(request); + } + + return request; + } + + /** + * Constructs a HttpURLConnection to set the page blob's size, Sign with zero length specified. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the blob. + * @param newBlobSize + * The new blob size, if the blob is a page blob. Set this parameter to null to keep the existing blob + * size. + * @return a HttpURLConnection to use to perform the operation. + * @throws IOException + * if there is an error opening the connection + * @throws URISyntaxException + * if the resource URI is invalid + * @throws StorageException + * an exception representing any error which occurred during the operation. + * @throws IllegalArgumentException + */ + public static HttpURLConnection resize(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition accessCondition, final Long newBlobSize) + throws IOException, URISyntaxException, StorageException { + final UriQueryBuilder builder = new UriQueryBuilder(); + builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.PROPERTIES); + + final HttpURLConnection request = createURLConnection(uri, builder, blobOptions, opContext); + + request.setFixedLengthStreamingMode(0); + request.setDoOutput(true); + request.setRequestMethod(Constants.HTTP_PUT); + + if (accessCondition != null) { + accessCondition.applyConditionToRequest(request); + } + + if (newBlobSize != null) { + request.setRequestProperty(BlobConstants.SIZE, newBlobSize.toString()); + } + + return request; + } + + /** + * Sets the ACL for the container. Sign with length of aclBytes. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the container. + * @param publicAccess + * The type of public access to allow for the container. + * @return a HttpURLConnection configured for the operation. + * @throws StorageException + * */ + public static HttpURLConnection setAcl(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition accessCondition, + final BlobContainerPublicAccessType publicAccess) throws IOException, URISyntaxException, StorageException { + final UriQueryBuilder builder = getContainerUriQueryBuilder(); + builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.ACL); + + final HttpURLConnection request = createURLConnection(uri, builder, blobOptions, opContext); + + request.setRequestMethod(Constants.HTTP_PUT); + request.setDoOutput(true); + + if (publicAccess != BlobContainerPublicAccessType.OFF) { + request.setRequestProperty(BlobConstants.BLOB_PUBLIC_ACCESS_HEADER, publicAccess.toString().toLowerCase()); + } + + if (accessCondition != null && !Utility.isNullOrEmpty(accessCondition.getLeaseID())) { + BaseRequest.addLeaseId(request, accessCondition.getLeaseID()); + } + + return request; + } + + /** + * Constructs a HttpURLConnection to set the blob's metadata, Sign with 0 length. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the blob. + * @return a HttpURLConnection to use to perform the operation. + * @throws IOException + * if there is an error opening the connection + * @throws URISyntaxException + * if the resource URI is invalid + * @throws StorageException + * an exception representing any error which occurred during the operation. + * @throws IllegalArgumentException + */ + public static HttpURLConnection setBlobMetadata(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition accessCondition) throws IOException, + URISyntaxException, StorageException { + return setMetadata(uri, blobOptions, opContext, accessCondition, null); + } + + /** + * Constructs a HttpURLConnection to set the blob's properties, Sign with zero length specified. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the blob. + * @param properties + * The properties to upload. + * @return a HttpURLConnection to use to perform the operation. + * @throws IOException + * if there is an error opening the connection + * @throws URISyntaxException + * if the resource URI is invalid + * @throws StorageException + * an exception representing any error which occurred during the operation. + * @throws IllegalArgumentException + */ + public static HttpURLConnection setBlobProperties(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition accessCondition, final BlobProperties properties) + throws IOException, URISyntaxException, StorageException { + final UriQueryBuilder builder = new UriQueryBuilder(); + builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.PROPERTIES); + + final HttpURLConnection request = createURLConnection(uri, builder, blobOptions, opContext); + + request.setFixedLengthStreamingMode(0); + request.setDoOutput(true); + request.setRequestMethod(Constants.HTTP_PUT); + + if (accessCondition != null) { + accessCondition.applyConditionToRequest(request); + } + + if (properties != null) { + addProperties(request, properties); + } + + return request; + } + + /** + * Constructs a web request to set user-defined metadata for the container, Sign with 0 Length. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the container. + * @return a HttpURLConnection configured for the operation. + * @throws StorageException + * */ + public static HttpURLConnection setContainerMetadata(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition accessCondition) throws IOException, + URISyntaxException, StorageException { + final UriQueryBuilder containerBuilder = getContainerUriQueryBuilder(); + return setMetadata(uri, blobOptions, opContext, accessCondition, containerBuilder); + } + + /** + * Constructs a HttpURLConnection to set the blob's metadata, Sign with 0 length. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the blob. + * @return a HttpURLConnection to use to perform the operation. + * @throws IOException + * if there is an error opening the connection + * @throws URISyntaxException + * if the resource URI is invalid + * @throws StorageException + * an exception representing any error which occurred during the operation. + * @throws IllegalArgumentException + */ + private static HttpURLConnection setMetadata(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition accessCondition, final UriQueryBuilder builder) + throws IOException, URISyntaxException, StorageException { + final HttpURLConnection request = BaseRequest.setMetadata(uri, blobOptions, builder, opContext); + + if (accessCondition != null) { + accessCondition.applyConditionToRequest(request); + } + + return request; + } + + /** + * Constructs a HttpURLConnection to create a snapshot of the blob. Sign with 0 length. + * + * @param uri + * A URI object that specifies the absolute URI. + * @param blobOptions + * A {@link BlobRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudBlobClient}. + * @param opContext + * An {@link OperationContext} object that 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. + * @param accessCondition + * An {@link AccessCondition} object that represents the access conditions for the blob. + * @return a HttpURLConnection to use to perform the operation. + * @throws IOException + * if there is an error opening the connection + * @throws URISyntaxException + * if the resource URI is invalid + * @throws StorageException + * an exception representing any error which occurred during the operation. + * @throws IllegalArgumentException + */ + public static HttpURLConnection snapshot(final URI uri, final BlobRequestOptions blobOptions, + final OperationContext opContext, final AccessCondition accessCondition) throws IOException, + URISyntaxException, StorageException { + final UriQueryBuilder builder = new UriQueryBuilder(); + builder.add(Constants.QueryConstants.COMPONENT, BlobConstants.SNAPSHOT); + final HttpURLConnection request = createURLConnection(uri, builder, blobOptions, opContext); + + request.setFixedLengthStreamingMode(0); + request.setDoOutput(true); + request.setRequestMethod(Constants.HTTP_PUT); + + if (accessCondition != null) { + accessCondition.applyConditionToRequest(request); + } + + return request; + } + + /** + * Private Default Ctor + */ + private BlobRequest() { + // No op + } +} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobRequestOptions.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobRequestOptions.java similarity index 61% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobRequestOptions.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobRequestOptions.java index b5c1898ff44f9..b62dc04a54626 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobRequestOptions.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobRequestOptions.java @@ -13,12 +13,12 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.RequestOptions; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.RequestOptions; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; /** * Represents a set of options that may be specified on a request. @@ -118,16 +118,20 @@ protected static final BlobRequestOptions applyDefaults(final BlobRequestOptions protected static final BlobRequestOptions applyDefaults(final BlobRequestOptions options, final BlobType blobType, final CloudBlobClient client, final boolean setStartTime) { BlobRequestOptions modifiedOptions = new BlobRequestOptions(options); + BlobRequestOptions.populateRequestOptions(modifiedOptions, client.getDefaultRequestOptions(), setStartTime); return BlobRequestOptions.applyDefaultsInternal(modifiedOptions, blobType, client, setStartTime); } private static final BlobRequestOptions applyDefaultsInternal(final BlobRequestOptions modifiedOptions, final BlobType blobtype, final CloudBlobClient client, final boolean setStartTime) { Utility.assertNotNull("modifiedOptions", modifiedOptions); - RequestOptions.applyBaseDefaultsInternal(modifiedOptions, client, setStartTime); - + RequestOptions.applyBaseDefaultsInternal(modifiedOptions); if (modifiedOptions.getConcurrentRequestCount() == null) { - modifiedOptions.setConcurrentRequestCount(client.getConcurrentRequestCount()); + modifiedOptions.setConcurrentRequestCount(BlobConstants.DEFAULT_CONCURRENT_REQUEST_COUNT); + } + + if (modifiedOptions.getSingleBlobPutThresholdInBytes() == null) { + modifiedOptions.setSingleBlobPutThresholdInBytes(BlobConstants.DEFAULT_SINGLE_BLOB_PUT_THRESHOLD_IN_BYTES); } if (modifiedOptions.getUseTransactionalContentMD5() == null) { @@ -142,14 +146,42 @@ private static final BlobRequestOptions applyDefaultsInternal(final BlobRequestO modifiedOptions.setDisableContentMD5Validation(false); } + return modifiedOptions; + } + + /** + * Populates any null fields in the first requestOptions object with values from the second requestOptions object. + */ + private static final BlobRequestOptions populateRequestOptions(BlobRequestOptions modifiedOptions, + final BlobRequestOptions clientOptions, final boolean setStartTime) { + RequestOptions.populateRequestOptions(modifiedOptions, clientOptions, setStartTime); + if (modifiedOptions.getConcurrentRequestCount() == null) { + modifiedOptions.setConcurrentRequestCount(clientOptions.getConcurrentRequestCount()); + } + if (modifiedOptions.getSingleBlobPutThresholdInBytes() == null) { - modifiedOptions.setSingleBlobPutThresholdInBytes(client.getSingleBlobPutThresholdInBytes()); + modifiedOptions.setSingleBlobPutThresholdInBytes(clientOptions.getSingleBlobPutThresholdInBytes()); + } + + if (modifiedOptions.getUseTransactionalContentMD5() == null) { + modifiedOptions.setUseTransactionalContentMD5(clientOptions.getUseTransactionalContentMD5()); + } + + if (modifiedOptions.getStoreBlobContentMD5() == null) { + modifiedOptions.setStoreBlobContentMD5(clientOptions.getStoreBlobContentMD5()); + } + + if (modifiedOptions.getDisableContentMD5Validation() == null) { + modifiedOptions.setDisableContentMD5Validation(clientOptions.getDisableContentMD5Validation()); } return modifiedOptions; } /** + * Gets the concurrent number of simultaneous requests per operation. For more information about concurrent request + * count defaults, see {@link #setConcurrentRequestCount(Integer)}. + * * @return the concurrentRequestCount */ public Integer getConcurrentRequestCount() { @@ -157,6 +189,10 @@ public Integer getConcurrentRequestCount() { } /** + * Gets whether a range PUT or GET operation will use the Content-MD5 header to enforce transactional security. + * All partial blob uploads or downloads will be restricted to 4 MB. For more information about transactional + * content MD5 defaults, see {@link #setUseTransactionalContentMD5(Boolean)}. + * * @return the useTransactionalContentMD5 */ public Boolean getUseTransactionalContentMD5() { @@ -164,6 +200,10 @@ public Boolean getUseTransactionalContentMD5() { } /** + * Gets whether the blob's ContentMD5 header should be set on uploads. This field is not supported for page + * blobs. For more information about storing blob content MD5 defaults, see {@link #setStoreBlobContentMD5(Boolean)} + * . + * * @return the storeBlobContentMD5 */ public Boolean getStoreBlobContentMD5() { @@ -171,25 +211,35 @@ public Boolean getStoreBlobContentMD5() { } /** + * Gets whether download and {@link BlobInputStream} methods should ignore the blob's ContentMD5 header. For more + * information about disabling content MD5 validation defaults, see {@link #setDisableContentMD5Validation(Boolean)} + * . + * * @return the disableContentMD5Validation */ - protected Boolean getDisableContentMD5Validation() { + public Boolean getDisableContentMD5Validation() { return this.disableContentMD5Validation; } /** - * Returns the threshold size used for writing a single blob. + * Gets the threshold size used for writing a single blob. For more information about the threshold size defaults, + * see {@link #setSingleBlobPutThresholdInBytes(Integer)}. * * @return The maximum size, in bytes, of a blob that may be uploaded as a single blob, ranging from 1 to 64 MB - * inclusive. The default value is 32 MBs. - *

- * If a blob size is above the threshold, it will be uploaded as blocks. + * inclusive. If a blob size is above the threshold, it will be uploaded as blocks. */ public Integer getSingleBlobPutThresholdInBytes() { return this.singleBlobPutThresholdInBytes; } /** + * Sets the concurrent number of simultaneous requests per operation. + *

+ * The default concurrent request count is set in the client and is by default 1, indicating no concurrency. You can + * change the concurrent request count on this request by setting this property. You can also change the value on + * the {@link BlobServiceClient#getDefaultRequestOptions()} object so that all subsequent requests made via the + * service client will use that concurrent request count. + * * @param concurrentRequestCount * the concurrentRequestCount to set */ @@ -198,6 +248,14 @@ public void setConcurrentRequestCount(final Integer concurrentRequestCount) { } /** + * Sets whether a range PUT or GET operation will use the Content-MD5 header to enforce transactional security. + * All partial blob uploads or downloads will be restricted to 4 MB. + *

+ * The default useTransactionalContentMD5 value is set in the client and is by default false. You can + * change the useTransactionalContentMD5 value on this request by setting this property. You can also change the + * value on the {@link BlobServiceClient#getDefaultRequestOptions()} object so that all subsequent requests made via + * the service client will use that useTransactionalContentMD5 value. + * * @param useTransactionalContentMD5 * the useTransactionalContentMD5 to set */ @@ -206,6 +264,14 @@ public void setUseTransactionalContentMD5(final Boolean useTransactionalContentM } /** + * Sets whether the blob's ContentMD5 header should be set on uploads. This field is not supported for page + * blobs. + *

+ * The default storeBlobContentMD5 value is set in the client and is by default true for block blobs. + * You can change the storeBlobContentMD5 value on this request by setting this property. You can also change the + * value on the {@link BlobServiceClient#getDefaultRequestOptions()} object so that all subsequent requests made via + * the service client will use that storeBlobContentMD5 value. + * * @param storeBlobContentMD5 * the storeBlobContentMD5 to set */ @@ -214,6 +280,13 @@ public void setStoreBlobContentMD5(final Boolean storeBlobContentMD5) { } /** + * Sets whether download and {@link BlobInputStream} methods should ignore the blob's ContentMD5 header. + *

+ * The default disableContentMD5Validation value is set in the client and is by default false. You can + * change the disableContentMD5Validation value on this request by setting this property. You can also change the + * value on the {@link BlobServiceClient#getDefaultRequestOptions()} object so that all subsequent requests made via + * the service client will use that disableContentMD5Validation value. + * * @param disableContentMD5Validation * the disableContentMD5Validation to set */ @@ -223,6 +296,11 @@ public void setDisableContentMD5Validation(final Boolean disableContentMD5Valida /** * Sets the threshold size used for writing a single blob to use. + *

+ * The default threshold size is set in the client and is by default 32MB. You can change the threshold size on this + * request by setting this property. You can also change the value on the + * {@link BlobServiceClient#getDefaultRequestOptions()} object so that all subsequent requests made via the service + * client will use that threshold size. * * @param singleBlobPutThresholdInBytes * The maximum size, in bytes, of a blob that may be uploaded as a single blob, ranging from 1 MB to 64 diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobResponse.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobResponse.java similarity index 54% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobResponse.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobResponse.java index 41ddc0a06114b..a3a20d8626783 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobResponse.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobResponse.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import java.net.HttpURLConnection; import java.net.URI; @@ -21,16 +21,29 @@ import java.util.Calendar; import java.util.Date; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.StorageUri; -import com.microsoft.windowsazure.storage.core.BaseResponse; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.StorageUri; +import com.microsoft.azure.storage.core.BaseResponse; +import com.microsoft.azure.storage.core.PathUtility; +import com.microsoft.azure.storage.core.Utility; /** - * RESERVED FOR INTERNAL USE. A class for parsing various responses from the blob service + * RESERVED FOR INTERNAL USE. A class used to parse the response from blob and container operations. */ final class BlobResponse extends BaseResponse { + /** + * Gets the ACL for the container from the response. + * + * @param request + * the request object for this operation + * @return the ACL value indicating the public access level for the container + */ + public static String getAcl(final HttpURLConnection request) { + return request.getHeaderField(BlobConstants.BLOB_PUBLIC_ACCESS_HEADER); + } + /** * Gets the BlobAttributes from the given request * @@ -44,7 +57,7 @@ final class BlobResponse extends BaseResponse { * @throws ParseException * @throws URISyntaxException */ - public static BlobAttributes getAttributes(final HttpURLConnection request, final StorageUri resourceURI, + public static BlobAttributes getBlobAttributes(final HttpURLConnection request, final StorageUri resourceURI, final String snapshotID) throws URISyntaxException, ParseException { final String blobType = request.getHeaderField(BlobConstants.BLOB_TYPE_HEADER); @@ -64,9 +77,9 @@ public static BlobAttributes getAttributes(final HttpURLConnection request, fina lastModifiedCalendar.setTime(new Date(request.getLastModified())); properties.setLastModified(lastModifiedCalendar.getTime()); - properties.setLeaseStatus(BaseResponse.getLeaseStatus(request)); - properties.setLeaseState(BaseResponse.getLeaseState(request)); - properties.setLeaseDuration(BaseResponse.getLeaseDuration(request)); + properties.setLeaseStatus(getLeaseStatus(request)); + properties.setLeaseState(getLeaseState(request)); + properties.setLeaseDuration(getLeaseDuration(request)); final String rangeHeader = request.getHeaderField(Constants.HeaderConstants.CONTENT_RANGE); final String xContentLengthHeader = request.getHeaderField(BlobConstants.CONTENT_LENGTH_HEADER); @@ -96,6 +109,42 @@ else if (!Utility.isNullOrEmpty(xContentLengthHeader)) { return attributes; } + /** + * Gets the BlobContainerAttributes from the given request. + * + * @param request + * the request to get attributes from. + * @param usePathStyleUris + * a value indicating if the account is using pathSytleUris. + * @return the BlobContainerAttributes from the given request. + * @throws StorageException + */ + public static BlobContainerAttributes getBlobContainerAttributes(final HttpURLConnection request, + final boolean usePathStyleUris) throws StorageException { + final BlobContainerAttributes containerAttributes = new BlobContainerAttributes(); + URI tempURI; + try { + tempURI = PathUtility.stripSingleURIQueryAndFragment(request.getURL().toURI()); + } + catch (final URISyntaxException e) { + final StorageException wrappedUnexpectedException = Utility.generateNewUnexpectedStorageException(e); + throw wrappedUnexpectedException; + } + + containerAttributes.setName(PathUtility.getContainerNameFromUri(tempURI, usePathStyleUris)); + + final BlobContainerProperties containerProperties = containerAttributes.getProperties(); + containerProperties.setEtag(BaseResponse.getEtag(request)); + containerProperties.setLastModified(new Date(request.getLastModified())); + containerAttributes.setMetadata(getMetadata(request)); + + containerProperties.setLeaseStatus(getLeaseStatus(request)); + containerProperties.setLeaseState(getLeaseState(request)); + containerProperties.setLeaseDuration(getLeaseDuration(request)); + + return containerAttributes; + } + /** * Gets the copyState * @@ -138,6 +187,76 @@ public static CopyState getCopyState(final HttpURLConnection request) throws URI } } + /** + * Gets the LeaseDuration + * + * @param request + * The response from server. + * @return The LeaseDuration. + */ + public static LeaseDuration getLeaseDuration(final HttpURLConnection request) { + final String leaseDuration = request.getHeaderField(Constants.HeaderConstants.LEASE_DURATION); + if (!Utility.isNullOrEmpty(leaseDuration)) { + return LeaseDuration.parse(leaseDuration); + } + + return LeaseDuration.UNSPECIFIED; + } + + /** + * Gets the lease id from the request header. + * + * @param request + * The response from server. + * @return the lease id from the request header. + */ + public static String getLeaseID(final HttpURLConnection request) { + return request.getHeaderField(Constants.HeaderConstants.LEASE_ID_HEADER); + } + + /** + * Gets the LeaseState + * + * @param request + * The response from server. + * @return The LeaseState. + */ + public static LeaseState getLeaseState(final HttpURLConnection request) { + final String leaseState = request.getHeaderField(Constants.HeaderConstants.LEASE_STATE); + if (!Utility.isNullOrEmpty(leaseState)) { + return LeaseState.parse(leaseState); + } + + return LeaseState.UNSPECIFIED; + } + + /** + * Gets the LeaseStatus + * + * @param request + * The response from server. + * @return The Etag. + */ + public static LeaseStatus getLeaseStatus(final HttpURLConnection request) { + final String leaseStatus = request.getHeaderField(Constants.HeaderConstants.LEASE_STATUS); + if (!Utility.isNullOrEmpty(leaseStatus)) { + return LeaseStatus.parse(leaseStatus); + } + + return LeaseStatus.UNSPECIFIED; + } + + /** + * Gets the lease Time from the request header. + * + * @param request + * The response from server. + * @return the lease Time from the request header. + */ + public static String getLeaseTime(final HttpURLConnection request) { + return request.getHeaderField(Constants.HeaderConstants.LEASE_TIME_HEADER); + } + /** * Gets the snapshot ID from the request header. * diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobType.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobType.java similarity index 90% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobType.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobType.java index 39d64fa08a357..254289efa5ecd 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobType.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobType.java @@ -12,11 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import java.util.Locale; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.core.Utility; /** * Specifies the type of a blob. @@ -45,7 +45,7 @@ public enum BlobType { * * @return A BlobType value corresponding to the string specified by typeString. */ - public static BlobType parse(final String typeString) { + protected static BlobType parse(final String typeString) { if (Utility.isNullOrEmpty(typeString)) { return UNSPECIFIED; } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlockEntry.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlockEntry.java similarity index 52% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlockEntry.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlockEntry.java index 4988e946206b8..001899dbe3b48 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlockEntry.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlockEntry.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; /** * A class which is used to list and commit blocks of a {@link CloudBlockBlob}. @@ -31,10 +31,22 @@ public final class BlockEntry { /** * Represents the block search mode. The default value is {@link BlockSearchMode#LATEST}. */ - public BlockSearchMode searchMode = BlockSearchMode.LATEST; + private BlockSearchMode searchMode; /** - * Creates an instance of the BlockEntry class. + * Creates an instance of the BlockEntry class with the specified id and default search mode + * {@link BlockSearchMode#LATEST}. + * + * @param id + * A String that represents the name of the block. + */ + public BlockEntry(final String id) { + this.setId(id); + this.searchMode = BlockSearchMode.LATEST; + } + + /** + * Creates an instance of the BlockEntry class with the specified id and search mode. * * @param id * A String that represents the name of the block. @@ -47,6 +59,10 @@ public BlockEntry(final String id, final BlockSearchMode searchMode) { } /** + * Gets the id of the block. The block id is a valid Base64 string value that identifies the block. Prior to + * encoding, the string must be less than or equal to 64 bytes in size. For a given blob, the length of the block id + * must be the same size for each block. + * * @return the id */ public String getId() { @@ -54,6 +70,8 @@ public String getId() { } /** + * Gets the size, in bytes, of the block. + * * @return the size */ public long getSize() { @@ -61,6 +79,19 @@ public long getSize() { } /** + * Gets the {@link BlockSearchMode}. + * + * @return the block search mode + */ + public BlockSearchMode getSearchMode() { + return searchMode; + } + + /** + * Sets the id of the block. The block id is a valid Base64 string value that identifies the block. Prior to + * encoding, the string must be less than or equal to 64 bytes in size. For a given blob, the length of the block id + * must be the same size for each block. + * * @param id * the id to set */ @@ -69,10 +100,22 @@ public void setId(final String id) { } /** + * Sets the size, in bytes, of the block. + * * @param size * the size to set */ public void setSize(final long size) { this.size = size; } + + /** + * Sets the {@link BlockSearchMode}. + * + * @param searchMode + * the block search mode to set + */ + public void setSearchMode(BlockSearchMode searchMode) { + this.searchMode = searchMode; + } } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlockEntryListSerializer.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlockEntryListSerializer.java similarity index 86% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlockEntryListSerializer.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlockEntryListSerializer.java index eb2398c27b346..7f00ef0d8a65a 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlockEntryListSerializer.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlockEntryListSerializer.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import java.io.StringWriter; import java.io.UnsupportedEncodingException; @@ -21,9 +21,9 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.core.Utility; /** * RESERVED FOR INTERNAL USE. A class used to serialize a block list to a byte array. @@ -54,13 +54,13 @@ public static byte[] writeBlockListToStream(final Iterable blockList xmlw.writeStartElement(BlobConstants.BLOCK_LIST_ELEMENT); for (final BlockEntry block : blockList) { - if (block.searchMode == BlockSearchMode.COMMITTED) { + if (block.getSearchMode() == BlockSearchMode.COMMITTED) { xmlw.writeStartElement(BlobConstants.COMMITTED_ELEMENT); } - else if (block.searchMode == BlockSearchMode.UNCOMMITTED) { + else if (block.getSearchMode() == BlockSearchMode.UNCOMMITTED) { xmlw.writeStartElement(BlobConstants.UNCOMMITTED_ELEMENT); } - else if (block.searchMode == BlockSearchMode.LATEST) { + else if (block.getSearchMode() == BlockSearchMode.LATEST) { xmlw.writeStartElement(BlobConstants.LATEST_ELEMENT); } diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlockListHandler.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlockListHandler.java new file mode 100644 index 0000000000000..f5cd400e7f722 --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlockListHandler.java @@ -0,0 +1,108 @@ +/** + * 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 java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Stack; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; + +/** + * RESERVED FOR INTERNAL USE. A class used to deserialize a list of blocks. + */ +class BlockListHandler extends DefaultHandler { + + private final Stack elementStack = new Stack(); + private StringBuilder bld = new StringBuilder(); + + private final ArrayList blocks = new ArrayList(); + + private BlockSearchMode searchMode; + private String blockName; + private Long blockSize; + + /** + * Parses a list of {@link BlockEntry} items from the given XML stream. + * + * @throws SAXException + * @throws ParserConfigurationException + * @throws IOException + */ + public static ArrayList getBlockList(InputStream streamRef) throws ParserConfigurationException, + SAXException, IOException { + SAXParser saxParser = Utility.getSAXParser(); + BlockListHandler handler = new BlockListHandler(); + saxParser.parse(streamRef, handler); + + return handler.blocks; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + this.elementStack.push(localName); + + if (BlobConstants.UNCOMMITTED_BLOCKS_ELEMENT.equals(localName)) { + this.searchMode = BlockSearchMode.UNCOMMITTED; + } + else if (BlobConstants.COMMITTED_BLOCKS_ELEMENT.equals(localName)) { + this.searchMode = BlockSearchMode.COMMITTED; + } + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + String currentNode = this.elementStack.pop(); + + // if the node popped from the stack and the localName don't match, the xml document is improperly formatted + if (!localName.equals(currentNode)) { + throw new SAXException(SR.INVALID_RESPONSE_RECEIVED); + } + + String value = this.bld.toString(); + if (value.isEmpty()) { + value = null; + } + + if (BlobConstants.BLOCK_ELEMENT.equals(currentNode)) { + final BlockEntry newBlock = new BlockEntry(this.blockName, this.searchMode); + newBlock.setSize(this.blockSize); + this.blocks.add(newBlock); + } + else if (Constants.NAME_ELEMENT.equals(currentNode)) { + this.blockName = value; + } + else if (BlobConstants.SIZE_ELEMENT.equals(currentNode)) { + this.blockSize = Long.parseLong(value); + } + + this.bld = new StringBuilder(); + } + + @Override + public void characters(char ch[], int start, int length) throws SAXException { + this.bld.append(ch, start, length); + } +} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlockListingFilter.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlockListingFilter.java similarity index 95% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlockListingFilter.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlockListingFilter.java index 8f4303828c868..7abd80916554a 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlockListingFilter.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlockListingFilter.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; /** * Specifies whether to list only committed blocks, only uncommitted blocks, or all blocks. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlockSearchMode.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlockSearchMode.java similarity index 95% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlockSearchMode.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlockSearchMode.java index 6a863d79d9687..067229754f1b8 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlockSearchMode.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlockSearchMode.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; /** * Specifies which block lists should be searched to find a specified block. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/CloudBlob.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlob.java similarity index 93% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/CloudBlob.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlob.java index 6ec22b925d5a9..43c026178000e 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/CloudBlob.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlob.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; @@ -33,32 +33,33 @@ import java.util.Calendar; import java.util.Date; import java.util.HashMap; - -import com.microsoft.windowsazure.storage.AccessCondition; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.DoesServiceRequest; -import com.microsoft.windowsazure.storage.LeaseStatus; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageCredentialsSharedAccessSignature; -import com.microsoft.windowsazure.storage.StorageErrorCodeStrings; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.StorageLocation; -import com.microsoft.windowsazure.storage.StorageUri; -import com.microsoft.windowsazure.storage.core.Base64; -import com.microsoft.windowsazure.storage.core.ExecutionEngine; -import com.microsoft.windowsazure.storage.core.Logger; -import com.microsoft.windowsazure.storage.core.NetworkInputStream; -import com.microsoft.windowsazure.storage.core.PathUtility; -import com.microsoft.windowsazure.storage.core.RequestLocationMode; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.SharedAccessSignatureHelper; -import com.microsoft.windowsazure.storage.core.StorageRequest; -import com.microsoft.windowsazure.storage.core.StreamMd5AndLength; -import com.microsoft.windowsazure.storage.core.UriQueryBuilder; -import com.microsoft.windowsazure.storage.core.Utility; +import java.util.concurrent.TimeoutException; + +import com.microsoft.azure.storage.AccessCondition; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.DoesServiceRequest; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.StorageCredentialsSharedAccessSignature; +import com.microsoft.azure.storage.StorageErrorCodeStrings; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.StorageLocation; +import com.microsoft.azure.storage.StorageUri; +import com.microsoft.azure.storage.core.Base64; +import com.microsoft.azure.storage.core.ExecutionEngine; +import com.microsoft.azure.storage.core.Logger; +import com.microsoft.azure.storage.core.NetworkInputStream; +import com.microsoft.azure.storage.core.PathUtility; +import com.microsoft.azure.storage.core.RequestLocationMode; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.SharedAccessSignatureHelper; +import com.microsoft.azure.storage.core.StorageCredentialsHelper; +import com.microsoft.azure.storage.core.StorageRequest; +import com.microsoft.azure.storage.core.StreamMd5AndLength; +import com.microsoft.azure.storage.core.UriQueryBuilder; +import com.microsoft.azure.storage.core.Utility; /** - * Represents a Windows Azure blob. This is the base class for the {@link CloudBlockBlob} and {@link CloudPageBlob} + * Represents a Microsoft Azure blob. This is the base class for the {@link CloudBlockBlob} and {@link CloudPageBlob} * classes. */ public abstract class CloudBlob implements ListBlobItem { @@ -149,7 +150,7 @@ protected CloudBlob(final BlobType type, final StorageUri uri, final CloudBlobCl this.parseURIQueryStringAndVerify( this.storageUri, client, - client == null ? Utility.determinePathStyleFromUri(this.storageUri.getPrimaryUri(), null) : client + client == null ? Utility.determinePathStyleFromUri(this.storageUri.getPrimaryUri()) : client .isUsePathStyleUris()); } @@ -266,7 +267,6 @@ public final void abortCopy(final String copyId) throws StorageException { * * @throws StorageException * If a storage service error occurred. - * */ @DoesServiceRequest public final void abortCopy(final String copyId, final AccessCondition accessCondition, BlobRequestOptions options, @@ -283,7 +283,7 @@ public final void abortCopy(final String copyId, final AccessCondition accessCon } private StorageRequest abortCopyImpl(final String copyId, - final AccessCondition accessCondition, final BlobRequestOptions options) throws StorageException { + final AccessCondition accessCondition, final BlobRequestOptions options) { Utility.assertNotNull("copyId", copyId); final StorageRequest putRequest = new StorageRequest( @@ -293,7 +293,7 @@ private StorageRequest abortCopyImpl(final Str public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, OperationContext context) throws Exception { return BlobRequest.abortCopy(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), copyId, accessCondition, options, context); + options, context, accessCondition, copyId); } @Override @@ -389,17 +389,16 @@ public final String acquireLease(final Integer leaseTimeInSeconds, final String } private StorageRequest acquireLeaseImpl(final Integer leaseTimeInSeconds, - final String proposedLeaseId, final AccessCondition accessCondition, final BlobRequestOptions options) - throws StorageException { + final String proposedLeaseId, final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, OperationContext context) throws Exception { - return BlobRequest.lease(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), LeaseAction.ACQUIRE, leaseTimeInSeconds, proposedLeaseId, - null, accessCondition, options, context); + return BlobRequest.leaseBlob(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), + options, context, accessCondition, LeaseAction.ACQUIRE, leaseTimeInSeconds, proposedLeaseId, + null); } @Override @@ -518,7 +517,7 @@ public final long breakLease(final Integer breakPeriodInSeconds, final AccessCon } private StorageRequest breakLeaseImpl(final Integer breakPeriodInSeconds, - final AccessCondition accessCondition, final BlobRequestOptions options) throws StorageException { + final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @@ -526,9 +525,8 @@ private StorageRequest breakLeaseImpl(final In @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, OperationContext context) throws Exception { - return BlobRequest.lease(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), LeaseAction.BREAK, null, null, breakPeriodInSeconds, - accessCondition, options, context); + return BlobRequest.leaseBlob(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), + options, context, accessCondition, LeaseAction.BREAK, null, null, breakPeriodInSeconds); } @Override @@ -621,16 +619,15 @@ public final String changeLease(final String proposedLeaseId, final AccessCondit } private StorageRequest changeLeaseImpl(final String proposedLeaseId, - final AccessCondition accessCondition, final BlobRequestOptions options) throws StorageException { + final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, OperationContext context) throws Exception { - return BlobRequest.lease(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), LeaseAction.CHANGE, null, proposedLeaseId, null, - accessCondition, options, context); + return BlobRequest.leaseBlob(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), + options, context, accessCondition, LeaseAction.CHANGE, null, proposedLeaseId, null); } @Override @@ -766,7 +763,7 @@ public final String startCopyFromBlob(final URI source, final AccessCondition so private StorageRequest startCopyFromBlobImpl(final URI source, final AccessCondition sourceAccessCondition, final AccessCondition destinationAccessCondition, - final BlobRequestOptions options) throws StorageException { + final BlobRequestOptions options) { if (sourceAccessCondition != null && !Utility.isNullOrEmpty(sourceAccessCondition.getLeaseID())) { throw new IllegalArgumentException(SR.LEASE_CONDITION_ON_SOURCE); @@ -779,8 +776,8 @@ private StorageRequest startCopyFromBlobImpl public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, OperationContext context) throws Exception { return BlobRequest.copyFrom(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), source.toString(), blob.snapshotID, sourceAccessCondition, - destinationAccessCondition, options, context); + options, context, sourceAccessCondition, destinationAccessCondition, source.toString(), + blob.snapshotID); } @Override @@ -893,7 +890,7 @@ public final CloudBlob createSnapshot(final HashMap metadata, private StorageRequest createSnapshotImpl( final HashMap metadata, final AccessCondition accessCondition, - final BlobRequestOptions options) throws StorageException { + final BlobRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @@ -901,7 +898,7 @@ private StorageRequest createSnapshotImpl public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, OperationContext context) throws Exception { return BlobRequest.snapshot(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), accessCondition, options, context); + options, context, accessCondition); } @Override @@ -966,8 +963,8 @@ public final void delete() throws StorageException { * is deleted. * * @param deleteSnapshotsOption - * A {@link DeleteSnapshotsOption} object that indicates whether to delete only blobs, only snapshots, or - * both. + * A {@link DeleteSnapshotsOption} object that indicates whether to delete only snapshots, or the blob + * and its snapshots. * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the blob. * @param options @@ -1028,8 +1025,8 @@ public final boolean deleteIfExists() throws StorageException { * is deleted. * * @param deleteSnapshotsOption - * A {@link DeleteSnapshotsOption} object that indicates whether to delete only blobs, only snapshots, or - * both. + * A {@link DeleteSnapshotsOption} object that indicates whether to delete only snapshots, or the blob + * and its snapshots. * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the blob. * @param options @@ -1076,16 +1073,15 @@ public final boolean deleteIfExists(final DeleteSnapshotsOption deleteSnapshotsO private StorageRequest deleteImpl( final DeleteSnapshotsOption deleteSnapshotsOption, final AccessCondition accessCondition, - final BlobRequestOptions options) throws StorageException { + final BlobRequestOptions options) { final StorageRequest deleteRequest = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, OperationContext context) throws Exception { - return BlobRequest.delete(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), blob.snapshotID, deleteSnapshotsOption, accessCondition, - options, context); + return BlobRequest.deleteBlob(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), + options, context, accessCondition, blob.snapshotID, deleteSnapshotsOption); } @Override @@ -1114,14 +1110,11 @@ public Void preProcessResponse(CloudBlob parentObject, CloudBlobClient client, O * * @param outStream * An OutputStream object that represents the target stream. - * - * @throws IOException - * If an I/O exception occurred. * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest - public final void download(final OutputStream outStream) throws StorageException, IOException { + public final void download(final OutputStream outStream) throws StorageException { this.download(outStream, null /* accessCondition */, null /* options */, null /* opContext */); } @@ -1140,15 +1133,12 @@ public final void download(final OutputStream outStream) throws StorageException * An {@link OperationContext} object that 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 IOException - * If an I/O exception occurred. * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public final void download(final OutputStream outStream, final AccessCondition accessCondition, - BlobRequestOptions options, OperationContext opContext) throws StorageException, IOException { + BlobRequestOptions options, OperationContext opContext) throws StorageException { if (opContext == null) { opContext = new OperationContext(); } @@ -1170,15 +1160,12 @@ public final void download(final OutputStream outStream, final AccessCondition a * The number of bytes to read or null. * @param outStream * An OutputStream object that represents the target stream. - * - * @throws IOException - * If an I/O exception occurred. * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public final void downloadRange(final long offset, final Long length, final OutputStream outStream) - throws StorageException, IOException { + throws StorageException { this.downloadRange(offset, length, outStream, null /* accessCondition */, null /* options */, null /* opContext */); } @@ -1201,16 +1188,13 @@ public final void downloadRange(final long offset, final Long length, final Outp * An {@link OperationContext} object that 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 IOException - * If an I/O exception occurred. * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public final void downloadRange(final long offset, final Long length, final OutputStream outStream, final AccessCondition accessCondition, BlobRequestOptions options, OperationContext opContext) - throws StorageException, IOException { + throws StorageException { if (offset < 0 || (length != null && length <= 0)) { throw new IndexOutOfBoundsException(); } @@ -1234,9 +1218,9 @@ public final void downloadRange(final long offset, final Long length, final Outp /** * Populates a blob's properties and metadata. *

- * This method populates the blob's system properties and user-defined metadata. Before reading a blob's properties - * or metadata, call this method or its overload to retrieve the latest values for the blob's properties and - * metadata from the Windows Azure storage service. + * This method populates the blob's system properties and user-defined metadata. Before reading or modifying a + * blob's properties or metadata, call this method or its overload to retrieve the latest values for the blob's + * properties and metadata from the Microsoft Azure storage service. * * @throws StorageException * If a storage service error occurred. @@ -1249,9 +1233,9 @@ public final void downloadAttributes() throws StorageException { /** * Populates a blob's properties and metadata using the specified request options and operation context. *

- * This method populates the blob's system properties and user-defined metadata. Before reading a blob's properties - * or metadata, call this method or its overload to retrieve the latest values for the blob's properties and - * metadata from the Windows Azure storage service. + * This method populates the blob's system properties and user-defined metadata. Before reading or modifying a + * blob's properties or metadata, call this method or its overload to retrieve the latest values for the blob's + * properties and metadata from the Microsoft Azure storage service. * * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the blob. @@ -1281,7 +1265,7 @@ public final void downloadAttributes(final AccessCondition accessCondition, Blob } private StorageRequest downloadAttributesImpl( - final AccessCondition accessCondition, final BlobRequestOptions options) throws StorageException { + final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest getRequest = new StorageRequest( options, this.getStorageUri()) { @@ -1293,8 +1277,9 @@ public void setRequestLocationMode() { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, OperationContext context) throws Exception { - return BlobRequest.getProperties(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), blob.snapshotID, accessCondition, options, context); + return BlobRequest.getBlobProperties( + blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), options, context, + accessCondition, blob.snapshotID); } @Override @@ -1312,7 +1297,7 @@ public Void preProcessResponse(CloudBlob blob, CloudBlobClient client, Operation } // Set attributes - final BlobAttributes retrievedAttributes = BlobResponse.getAttributes(this.getConnection(), + final BlobAttributes retrievedAttributes = BlobResponse.getBlobAttributes(this.getConnection(), blob.getStorageUri(), blob.snapshotID); if (retrievedAttributes.getProperties().getBlobType() != blob.properties.getBlobType()) { @@ -1334,7 +1319,7 @@ public Void preProcessResponse(CloudBlob blob, CloudBlobClient client, Operation @DoesServiceRequest private final StorageRequest downloadToStreamImpl(final Long blobOffset, final Long length, final OutputStream outStream, final AccessCondition accessCondition, - final BlobRequestOptions options, OperationContext opContext) throws StorageException, IOException { + final BlobRequestOptions options, OperationContext opContext) { final long startingOffset = blobOffset == null ? 0 : blobOffset; final boolean isRangeGet = blobOffset != null; @@ -1362,10 +1347,9 @@ public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, Op AccessCondition tempCondition = (this.getETagLockCondition() != null) ? this.getETagLockCondition() : accessCondition; - return BlobRequest.get(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), blob.snapshotID, this.getBlobOffset(), this.getLength(), - (options.getUseTransactionalContentMD5() && !this.getArePropertiesPopulated()), tempCondition, - options, context); + return BlobRequest.getBlob(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), + options, context, tempCondition, blob.snapshotID, this.getBlobOffset(), this.getLength(), + (options.getUseTransactionalContentMD5() && !this.getArePropertiesPopulated())); } @Override @@ -1625,7 +1609,7 @@ public final int downloadToByteArray(final byte[] buffer, final int bufferOffset private StorageRequest downloadToByteArrayImpl(final Long blobOffset, final Long length, final byte[] buffer, final int bufferOffset, final AccessCondition accessCondition, - final BlobRequestOptions options, OperationContext opContext) throws StorageException { + final BlobRequestOptions options, OperationContext opContext) { final long startingOffset = blobOffset == null ? 0 : blobOffset; final boolean isRangeGet = blobOffset != null; final StorageRequest getRequest = new StorageRequest( @@ -1650,10 +1634,9 @@ public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, Op AccessCondition tempCondition = (this.getETagLockCondition() != null) ? this.getETagLockCondition() : accessCondition; - return BlobRequest.get(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), blob.snapshotID, this.getBlobOffset(), this.getLength(), - (options.getUseTransactionalContentMD5() && !this.getArePropertiesPopulated()), tempCondition, - options, context); + return BlobRequest.getBlob(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), + options, context, tempCondition, blob.snapshotID, this.getBlobOffset(), this.getLength(), + (options.getUseTransactionalContentMD5() && !this.getArePropertiesPopulated())); } @Override @@ -1686,6 +1669,14 @@ public Integer postProcessResponse(HttpURLConnection connection, CloudBlob blob, int count = sourceStream.read(buffer, bufferOffset, nextRead); while (count > 0) { + // if maximum execution time would be exceeded + if (Utility.validateMaxExecutionTimeout(options.getOperationExpiryTimeInMs())) { + // throw an exception + TimeoutException timeoutException = new TimeoutException( + SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION); + throw Utility.initIOException(timeoutException); + } + totalRead += count; this.setCurrentRequestByteCount(this.getCurrentRequestByteCount() + count); @@ -1944,7 +1935,7 @@ private final boolean exists(final boolean primaryOnly, final AccessCondition ac } private StorageRequest existsImpl(final boolean primaryOnly, - final AccessCondition accessCondition, final BlobRequestOptions options) throws StorageException { + final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest getRequest = new StorageRequest( options, this.getStorageUri()) { @Override @@ -1956,8 +1947,9 @@ public void setRequestLocationMode() { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, OperationContext context) throws Exception { - return BlobRequest.getProperties(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), blob.snapshotID, accessCondition, options, context); + return BlobRequest.getBlobProperties( + blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), options, context, + accessCondition, blob.snapshotID); } @Override @@ -1970,7 +1962,7 @@ public void signRequest(HttpURLConnection connection, CloudBlobClient client, Op public Boolean preProcessResponse(CloudBlob blob, CloudBlobClient client, OperationContext context) throws Exception { if (this.getResult().getStatusCode() == HttpURLConnection.HTTP_OK) { - final BlobAttributes retrievedAttributes = BlobResponse.getAttributes(this.getConnection(), + final BlobAttributes retrievedAttributes = BlobResponse.getBlobAttributes(this.getConnection(), blob.getStorageUri(), blob.snapshotID); blob.properties = retrievedAttributes.getProperties(); blob.metadata = retrievedAttributes.getMetadata(); @@ -2041,7 +2033,7 @@ public String generateSharedAccessSignature(final SharedAccessBlobPolicy policy, final SharedAccessBlobHeaders headers, final String groupPolicyIdentifier) throws InvalidKeyException, StorageException { - if (!this.blobServiceClient.getCredentials().canCredentialsSignRequest()) { + if (!StorageCredentialsHelper.canCredentialsSignRequest(this.blobServiceClient.getCredentials())) { throw new IllegalArgumentException(SR.CANNOT_CREATE_SAS_WITHOUT_ACCOUNT_KEY); } @@ -2278,19 +2270,7 @@ public final int getStreamMinimumReadSizeInBytes() { */ protected final StorageUri getTransformedAddress(final OperationContext opContext) throws URISyntaxException, StorageException { - if (this.blobServiceClient.getCredentials().doCredentialsNeedTransformUri()) { - if (this.getStorageUri().isAbsolute()) { - return this.blobServiceClient.getCredentials().transformUri(this.getStorageUri(), opContext); - } - else { - final StorageException ex = Utility.generateNewUnexpectedStorageException(null); - ex.getExtendedErrorInformation().setErrorMessage("Blob Object relative URIs not supported."); - throw ex; - } - } - else { - return this.getStorageUri(); - } + return this.blobServiceClient.getCredentials().transformUri(this.getStorageUri(), opContext); } /** @@ -2419,12 +2399,9 @@ protected void parseURIQueryStringAndVerify(final StorageUri completeUri, final } if (existingClient != null && !sameCredentials) { - this.blobServiceClient.setSingleBlobPutThresholdInBytes(existingClient.getSingleBlobPutThresholdInBytes()); - this.blobServiceClient.setConcurrentRequestCount(existingClient.getConcurrentRequestCount()); + this.blobServiceClient.setDefaultRequestOptions(new BlobRequestOptions(existingClient + .getDefaultRequestOptions())); this.blobServiceClient.setDirectoryDelimiter(existingClient.getDirectoryDelimiter()); - this.blobServiceClient.setRetryPolicyFactory(existingClient.getRetryPolicyFactory()); - this.blobServiceClient.setTimeoutInMs(existingClient.getTimeoutInMs()); - this.blobServiceClient.setLocationMode(existingClient.getLocationMode()); } } @@ -2479,18 +2456,16 @@ public final void releaseLease(final AccessCondition accessCondition, BlobReques } private StorageRequest releaseLeaseImpl(final AccessCondition accessCondition, - final BlobRequestOptions options) throws StorageException { + final BlobRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, OperationContext context) throws Exception { - return BlobRequest - .lease(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), LeaseAction.RELEASE, null /* leaseTimeInSeconds */, - null /* proposedLeaseId */, null /*breakPeriodInSeconds */, accessCondition, options, - context); + return BlobRequest.leaseBlob(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), + options, context, accessCondition, LeaseAction.RELEASE, null /* leaseTimeInSeconds */, + null /* proposedLeaseId */, null /*breakPeriodInSeconds */); } @Override @@ -2568,17 +2543,15 @@ public final void renewLease(final AccessCondition accessCondition, BlobRequestO } private StorageRequest renewLeaseImpl(final AccessCondition accessCondition, - final BlobRequestOptions options) throws StorageException { + final BlobRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, OperationContext context) throws Exception { - return BlobRequest - .lease(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), LeaseAction.RENEW, null /* leaseTimeInSeconds */, - null /* proposedLeaseId */, null /*breakPeriodInSeconds */, accessCondition, options, - context); + return BlobRequest.leaseBlob(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), + options, context, accessCondition, LeaseAction.RENEW, null /* leaseTimeInSeconds */, + null /* proposedLeaseId */, null /*breakPeriodInSeconds */); } @Override @@ -2764,16 +2737,13 @@ public abstract void upload(InputStream sourceStream, long length, final AccessC * An {@link OperationContext} object that 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 IOException - * If an I/O exception occurred. * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest protected final void uploadFullBlob(final InputStream sourceStream, final long length, final AccessCondition accessCondition, final BlobRequestOptions options, final OperationContext opContext) - throws StorageException, IOException { + throws StorageException { assertNoWriteOperationForSnapshot(); // Mark sourceStream for current position. @@ -2800,9 +2770,9 @@ public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, Op throws Exception { this.setSendStream(sourceStream); this.setLength(length); - return BlobRequest.put(blob.getTransformedAddress(opContext).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), blob.properties, blob.properties.getBlobType(), - this.getLength(), accessCondition, options, opContext); + return BlobRequest.putBlob(blob.getTransformedAddress(opContext).getUri(this.getCurrentLocation()), + options, opContext, accessCondition, blob.properties, blob.properties.getBlobType(), + this.getLength()); } @Override @@ -2850,6 +2820,9 @@ public void validateStreamWrite(StreamMd5AndLength descriptor) throws StorageExc /** * Uploads the blob's metadata to the storage service. + *

+ * Use {@link CloudBlob#downloadAttributes} to retrieve the latest values for the blob's properties and metadata + * from the Microsoft Azure storage service. * * @throws StorageException * If a storage service error occurred. @@ -2862,6 +2835,9 @@ public final void uploadMetadata() throws StorageException { /** * Uploads the blob's metadata to the storage service using the specified lease ID, request options, and operation * context. + *

+ * Use {@link CloudBlob#downloadAttributes} to retrieve the latest values for the blob's properties and metadata + * from the Microsoft Azure storage service. * * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the blob. @@ -2894,15 +2870,15 @@ public final void uploadMetadata(final AccessCondition accessCondition, BlobRequ } private StorageRequest uploadMetadataImpl(final AccessCondition accessCondition, - final BlobRequestOptions options) throws StorageException { + final BlobRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, OperationContext context) throws Exception { - return BlobRequest.setMetadata(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), accessCondition, options, context); + return BlobRequest.setBlobMetadata(blob.getTransformedAddress(context) + .getUri(this.getCurrentLocation()), options, context, accessCondition); } @Override @@ -2934,6 +2910,9 @@ public Void preProcessResponse(CloudBlob blob, CloudBlobClient client, Operation /** * Updates the blob's properties to the storage service. + *

+ * Use {@link CloudBlob#downloadAttributes} to retrieve the latest values for the blob's properties and metadata + * from the Microsoft Azure storage service. * * @throws StorageException * If a storage service error occurred. @@ -2945,6 +2924,9 @@ public final void uploadProperties() throws StorageException { /** * Updates the blob's properties using the specified lease ID, request options, and operation context. + *

+ * Use {@link CloudBlob#downloadAttributes} to retrieve the latest values for the blob's properties and metadata + * from the Microsoft Azure storage service. * * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the blob. @@ -2977,15 +2959,16 @@ public final void uploadProperties(final AccessCondition accessCondition, BlobRe } private StorageRequest uploadPropertiesImpl( - final AccessCondition accessCondition, final BlobRequestOptions options) throws StorageException { + final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, OperationContext context) throws Exception { - return BlobRequest.setProperties(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), blob.properties, accessCondition, options, context); + return BlobRequest.setBlobProperties( + blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), options, context, + accessCondition, blob.properties); } @Override @@ -3029,7 +3012,7 @@ private Integer preProcessDownloadResponse(final StorageRequest * This class provides a point of access to the Blob service. The service client encapsulates the base URI for the Blob * service. If the service client will be used for authenticated access, it also encapsulates the credentials for * accessing the storage account. */ public final class CloudBlobClient extends ServiceClient { - /** - * Holds the maximum size of a blob in bytes that may be uploaded as a single blob. - */ - private int singleBlobPutThresholdInBytes = BlobConstants.DEFAULT_SINGLE_BLOB_PUT_THRESHOLD_IN_BYTES; /** - * Holds the number of simultaneous operations a given blob operation may perform. + * Holds the default delimiter that may be used to create a virtual directory structure of blobs. */ - private int concurrentRequestCount = BlobConstants.DEFAULT_CONCURRENT_REQUEST_COUNT; + private String directoryDelimiter = BlobConstants.DEFAULT_DELIMITER; /** - * Holds the default delimiter that may be used to create a virtual directory structure of blobs. + * Holds the default request option values associated with this Service Client. */ - private String directoryDelimiter = BlobConstants.DEFAULT_DELIMITER; + private BlobRequestOptions defaultRequestOptions; /** - * Creates an instance of the CloudBlobClient class using the specified Blob service endpoint. + * Creates an instance of the CloudBlobClient class using the specified Blob service endpoint and + * anonymous credentials. * * @param baseUri * A java.net.URI object that represents the Blob service endpoint used to create the * client. */ public CloudBlobClient(final URI baseUri) { - this(new StorageUri(baseUri), StorageCredentialsAnonymous.ANONYMOUS); + this(new StorageUri(baseUri), null /* credentials */); + } + + /** + * Creates an instance of the CloudBlobClient class using the specified Blob service endpoint and + * anonymous credentials. + * + * @param baseUri + * A {@link StorageUri} object that represents the Blob service endpoint used to create the + * client. + */ + public CloudBlobClient(final StorageUri baseUri) { + this(baseUri, null /* credentials */); } /** @@ -99,16 +108,26 @@ public CloudBlobClient(final URI baseUri, StorageCredentials credentials) { */ public CloudBlobClient(final StorageUri storageUri, StorageCredentials credentials) { super(storageUri, credentials); - this.directoryDelimiter = BlobConstants.DEFAULT_DELIMITER; + this.defaultRequestOptions = new BlobRequestOptions(); + this.defaultRequestOptions.setLocationMode(LocationMode.PRIMARY_ONLY); + this.defaultRequestOptions.setRetryPolicyFactory(new RetryExponentialRetry()); + this.defaultRequestOptions.setConcurrentRequestCount(BlobConstants.DEFAULT_CONCURRENT_REQUEST_COUNT); + this.defaultRequestOptions.setDisableContentMD5Validation(false); + this.defaultRequestOptions + .setSingleBlobPutThresholdInBytes(BlobConstants.DEFAULT_SINGLE_BLOB_PUT_THRESHOLD_IN_BYTES); + this.defaultRequestOptions.setUseTransactionalContentMD5(false); } /** * Returns the number of maximum concurrent requests allowed. * * @return The number of maximum concurrent requests allowed. + * + * @deprecated use {@link #getDefaultRequestOptions().getConcurrentRequestCount()} instead. */ + @Deprecated public int getConcurrentRequestCount() { - return this.concurrentRequestCount; + return this.defaultRequestOptions.getConcurrentRequestCount(); } /** @@ -124,8 +143,8 @@ public int getConcurrentRequestCount() { * If the resource URI constructed based on the containerName is invalid. * @throws StorageException * If a storage service error occurred. - * @see Naming and Referencing - * Containers, Blobs, and Metadata + * @see Naming and Referencing Containers, + * Blobs, and Metadata */ public CloudBlobContainer getContainerReference(final String containerName) throws URISyntaxException, StorageException { @@ -148,9 +167,12 @@ public String getDirectoryDelimiter() { * inclusive. The default value is 32 MBs. *

* If a blob size is above the threshold, it will be uploaded as blocks. + * + * @deprecated use {@link #getDefaultRequestOptions().getSingleBlobPutThresholdInBytes()} instead. */ + @Deprecated public int getSingleBlobPutThresholdInBytes() { - return this.singleBlobPutThresholdInBytes; + return this.getDefaultRequestOptions().getSingleBlobPutThresholdInBytes(); } /** @@ -159,10 +181,9 @@ public int getSingleBlobPutThresholdInBytes() { * @return An enumerable collection of {@link CloudBlobContainer} objects retrieved lazily that represent the * containers for this * client. - * @throws StorageException */ @DoesServiceRequest - public Iterable listContainers() throws StorageException { + public Iterable listContainers() { return this .listContainersWithPrefix(null, ContainerListingDetails.NONE, null /* options */, null /* opContext */); } @@ -177,10 +198,9 @@ public Iterable listContainers() throws StorageException { * @return An enumerable collection of {@link CloudBlobContainer} objects retrieved lazily that represent the * containers for this * client whose names begin with the specified prefix. - * @throws StorageException */ @DoesServiceRequest - public Iterable listContainers(final String prefix) throws StorageException { + public Iterable listContainers(final String prefix) { return this .listContainersWithPrefix(prefix, ContainerListingDetails.NONE, null /* options */, null /* opContext */); } @@ -205,12 +225,11 @@ public Iterable listContainers(final String prefix) throws S * @return An enumerable collection of {@link CloudBlobContainer} objects retrieved lazily that represents the * containers for this * client. - * @throws StorageException */ @DoesServiceRequest public Iterable listContainers(final String prefix, final ContainerListingDetails detailsIncluded, final BlobRequestOptions options, - final OperationContext opContext) throws StorageException { + final OperationContext opContext) { return this.listContainersWithPrefix(prefix, detailsIncluded, options, opContext); } @@ -307,11 +326,9 @@ public ResultSegment listContainersSegmented(final String pr * @return An enumerable collection of {@link CloudBlobContainer} objects retrieved lazily that represent the * containers whose names * begin with the specified prefix. - * @throws StorageException */ private Iterable listContainersWithPrefix(final String prefix, - final ContainerListingDetails detailsIncluded, BlobRequestOptions options, OperationContext opContext) - throws StorageException { + final ContainerListingDetails detailsIncluded, BlobRequestOptions options, OperationContext opContext) { if (opContext == null) { opContext = new OperationContext(); } @@ -376,7 +393,7 @@ private ResultSegment listContainersWithPrefixSegmented(fina private StorageRequest> listContainersWithPrefixSegmentedImpl( final String prefix, final ContainerListingDetails detailsIncluded, final int maxResults, - final BlobRequestOptions options, final SegmentedStorageRequest segmentedRequest) throws StorageException { + final BlobRequestOptions options, final SegmentedStorageRequest segmentedRequest) { Utility.assertContinuationType(segmentedRequest.getToken(), ResultContinuationType.CONTAINER); @@ -395,8 +412,8 @@ public HttpURLConnection buildRequest(CloudBlobClient client, Void parentObject, throws Exception { listingContext.setMarker(segmentedRequest.getToken() != null ? segmentedRequest.getToken() .getNextMarker() : null); - return ContainerRequest.list(client.getEndpoint(), options.getTimeoutIntervalInMs(), listingContext, - detailsIncluded, context); + return BlobRequest.listContainers(client.getEndpoint(), options, context, listingContext, + detailsIncluded); } @Override @@ -418,7 +435,7 @@ public ResultSegment preProcessResponse(Void parentObject, C public ResultSegment postProcessResponse(HttpURLConnection connection, Void container, CloudBlobClient client, OperationContext context, ResultSegment storageObject) throws Exception { - final ListResponse response = BlobDeserializer.getContainerList(this + final ListResponse response = ContainerListHandler.getContainerList(this .getConnection().getInputStream(), client); ResultContinuation newToken = null; @@ -442,10 +459,11 @@ public ResultSegment postProcessResponse(HttpURLConnection c } /** - * Queries the service to get the service statistics + * Queries the service for the {@link ServiceStats}. * - * @return ServiceStats for the given storage service + * @return {@link ServiceStats} for the given storage service * @throws StorageException + * If a storage service error occurred. */ @DoesServiceRequest public ServiceStats getServiceStats() throws StorageException { @@ -453,7 +471,7 @@ public ServiceStats getServiceStats() throws StorageException { } /** - * Queries the service to get the service statistics + * Queries the given storage service for the {@link ServiceStats}. * * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying @@ -463,8 +481,9 @@ public ServiceStats getServiceStats() throws StorageException { * An {@link OperationContext} object that 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. - * @return ServiceStats for the given storage service + * @return {@link ServiceStats} for the given storage service * @throws StorageException + * If a storage service error occurred. */ @DoesServiceRequest public ServiceStats getServiceStats(BlobRequestOptions options, OperationContext opContext) throws StorageException { @@ -476,15 +495,16 @@ public ServiceStats getServiceStats(BlobRequestOptions options, OperationContext options = BlobRequestOptions.applyDefaults(options, BlobType.UNSPECIFIED, this); return ExecutionEngine.executeWithRetry(this, null, this.getServiceStatsImpl(options, false), - this.getRetryPolicyFactory(), opContext); + options.getRetryPolicyFactory(), opContext); } /** - * Retrieves the current ServiceProperties for the given storage service. This includes Metrics and Logging - * Configurations. + * Retrieves the current {@link ServiceProperties} for the given storage service. This includes Logging, + * HourMetrics, MinuteMetrics and CORS configurations. * - * @return the ServiceProperties object representing the current configuration of the service. + * @return the {@link ServiceProperties} object representing the current configuration of the service. * @throws StorageException + * If a storage service error occurred. */ @DoesServiceRequest public final ServiceProperties downloadServiceProperties() throws StorageException { @@ -492,8 +512,8 @@ public final ServiceProperties downloadServiceProperties() throws StorageExcepti } /** - * Retrieves the current ServiceProperties for the given storage service. This includes Metrics and Logging - * Configurations. + * Retrieves the current {@link ServiceProperties} for the given storage service. This includes Logging, + * HourMetrics, MinuteMetrics and CORS configurations. * * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying @@ -503,7 +523,8 @@ public final ServiceProperties downloadServiceProperties() throws StorageExcepti * An {@link OperationContext} object that 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. - * @return the ServiceProperties object representing the current configuration of the service. + * + * @return the {@link ServiceProperties} object representing the current configuration of the service. * @throws StorageException * If a storage service error occurred. */ @@ -522,10 +543,11 @@ public final ServiceProperties downloadServiceProperties(BlobRequestOptions opti } /** - * Uploads a new configuration to the storage service. This includes Metrics and Logging Configuration. + * Uploads a new {@link ServiceProperties} configuration to the given storage service. This includes Logging, + * HourMetrics, MinuteMetrics and CORS configurations. * * @param properties - * The ServiceProperties to upload. + * The {@link ServiceProperties} to upload. * @throws StorageException * If a storage service error occurred. */ @@ -535,10 +557,11 @@ public void uploadServiceProperties(final ServiceProperties properties) throws S } /** - * Uploads a new configuration to the storage service. This includes Metrics and Logging Configuration. + * Uploads a new {@link ServiceProperties} configuration to the given storage service. This includes Logging, + * HourMetrics, MinuteMetrics and CORS configurations. * * @param properties - * The ServiceProperties to upload. + * The {@link ServiceProperties} to upload. * @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 ( @@ -573,9 +596,12 @@ public void uploadServiceProperties(final ServiceProperties properties, BlobRequ * @param concurrentRequestCount * The value being assigned as the maximum number of concurrent requests allowed for the Blob service * client. + * + * @deprecated use {@link #getDefaultRequestOptions().setConcurrentRequestCount()} instead. */ + @Deprecated public void setConcurrentRequestCount(final int concurrentRequestCount) { - this.concurrentRequestCount = concurrentRequestCount; + this.defaultRequestOptions.setConcurrentRequestCount(concurrentRequestCount); } /** @@ -598,13 +624,42 @@ public void setDirectoryDelimiter(final String directoryDelimiter) { * * @throws IllegalArgumentException * If minimumReadSize is less than 1 MB or greater than 64 MB. + * + * @deprecated use {@link #getDefaultRequestOptions().setSingleBlobPutThresholdInBytes()} instead. */ + @Deprecated public void setSingleBlobPutThresholdInBytes(final int singleBlobPutThresholdInBytes) { - if (singleBlobPutThresholdInBytes > BlobConstants.MAX_SINGLE_UPLOAD_BLOB_SIZE_IN_BYTES - || singleBlobPutThresholdInBytes < 1 * Constants.MB) { - throw new IllegalArgumentException("SingleBlobUploadThresholdInBytes"); - } + this.defaultRequestOptions.setSingleBlobPutThresholdInBytes(singleBlobPutThresholdInBytes); + } + + /** + * Gets the {@link BlobRequestOptions} that is used for requests associated with this CloudBlobClient + * + * @return + * The {@link BlobRequestOptions} object containing the values used by this CloudBlobClient + */ + @Override + public BlobRequestOptions getDefaultRequestOptions() { + return this.defaultRequestOptions; + } - this.singleBlobPutThresholdInBytes = singleBlobPutThresholdInBytes; + /** + * Sets the {@link BlobRequestOptions} that is used for any requests associated with this + * CloudBlobClient object. + * + * @param defaultRequestOptions + * The BlobRequestOptions to use. + */ + public void setDefaultRequestOptions(BlobRequestOptions defaultRequestOptions) { + Utility.assertNotNull("defaultRequestOptions", defaultRequestOptions); + this.defaultRequestOptions = defaultRequestOptions; + } + + /** + * @return the usePathStyleUris + */ + @Override + protected boolean isUsePathStyleUris() { + return super.isUsePathStyleUris(); } } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/CloudBlobContainer.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlobContainer.java similarity index 91% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/CloudBlobContainer.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlobContainer.java index 1e77f562a6a18..0b8d38438af16 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/CloudBlobContainer.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlobContainer.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import java.io.ByteArrayInputStream; import java.io.StringWriter; @@ -28,33 +28,34 @@ import javax.xml.stream.XMLStreamException; -import com.microsoft.windowsazure.storage.AccessCondition; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.DoesServiceRequest; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.ResultContinuation; -import com.microsoft.windowsazure.storage.ResultContinuationType; -import com.microsoft.windowsazure.storage.ResultSegment; -import com.microsoft.windowsazure.storage.StorageCredentialsSharedAccessSignature; -import com.microsoft.windowsazure.storage.StorageErrorCode; -import com.microsoft.windowsazure.storage.StorageErrorCodeStrings; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.StorageUri; -import com.microsoft.windowsazure.storage.core.ExecutionEngine; -import com.microsoft.windowsazure.storage.core.LazySegmentedIterable; -import com.microsoft.windowsazure.storage.core.PathUtility; -import com.microsoft.windowsazure.storage.core.RequestLocationMode; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.SegmentedStorageRequest; -import com.microsoft.windowsazure.storage.core.SharedAccessPolicyDeserializer; -import com.microsoft.windowsazure.storage.core.SharedAccessPolicySerializer; -import com.microsoft.windowsazure.storage.core.SharedAccessSignatureHelper; -import com.microsoft.windowsazure.storage.core.StorageRequest; -import com.microsoft.windowsazure.storage.core.UriQueryBuilder; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.AccessCondition; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.DoesServiceRequest; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.ResultContinuation; +import com.microsoft.azure.storage.ResultContinuationType; +import com.microsoft.azure.storage.ResultSegment; +import com.microsoft.azure.storage.SharedAccessPolicyHandler; +import com.microsoft.azure.storage.SharedAccessPolicySerializer; +import com.microsoft.azure.storage.StorageCredentialsSharedAccessSignature; +import com.microsoft.azure.storage.StorageErrorCode; +import com.microsoft.azure.storage.StorageErrorCodeStrings; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.StorageUri; +import com.microsoft.azure.storage.core.ExecutionEngine; +import com.microsoft.azure.storage.core.LazySegmentedIterable; +import com.microsoft.azure.storage.core.PathUtility; +import com.microsoft.azure.storage.core.RequestLocationMode; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.SegmentedStorageRequest; +import com.microsoft.azure.storage.core.SharedAccessSignatureHelper; +import com.microsoft.azure.storage.core.StorageCredentialsHelper; +import com.microsoft.azure.storage.core.StorageRequest; +import com.microsoft.azure.storage.core.UriQueryBuilder; +import com.microsoft.azure.storage.core.Utility; /** - * Represents a container in the Windows Azure Blob service. + * Represents a container in the Microsoft Azure Blob service. *

* Containers hold directories, which are encapsulated as {@link CloudBlobDirectory} objects, and directories hold block * blobs and page blobs. Directories can also contain sub-directories. @@ -127,6 +128,38 @@ private CloudBlobContainer(final CloudBlobClient client) { this.blobServiceClient = client; } + /** + * Creates an instance of the CloudBlobContainer class using the specified URI. The blob URI should + * include a SAS token unless anonymous access is to be used. + * + * @param uri + * A java.net.URI object that represents the URI of the container. + * + * @throws StorageException + * If a storage service error occurred. + * @throws URISyntaxException + * If the resource URI is invalid. + */ + public CloudBlobContainer(final URI uri) throws URISyntaxException, StorageException { + this(new StorageUri(uri)); + } + + /** + * Creates an instance of the CloudBlobContainer class using the specified URI. The blob URI should + * include a SAS token unless anonymous access is to be used. + * + * @param storageUri + * A StorageUri object that represents the URI of the container. + * + * @throws StorageException + * If a storage service error occurred. + * @throws URISyntaxException + * If the resource URI is invalid. + */ + public CloudBlobContainer(final StorageUri storageUri) throws URISyntaxException, StorageException { + this(storageUri, (CloudBlobClient) null /* client */); + } + /** * Creates an instance of the CloudBlobContainer class using the specified name and client. * @@ -142,8 +175,8 @@ private CloudBlobContainer(final CloudBlobClient client) { * If a storage service error occurred. * @throws URISyntaxException * If the resource URI constructed based on the containerName is invalid. - * @see Naming and Referencing - * Containers, Blobs, and Metadata + * @see Naming and Referencing Containers, + * Blobs, and Metadata */ public CloudBlobContainer(final String containerName, final CloudBlobClient client) throws URISyntaxException, StorageException { @@ -161,7 +194,7 @@ public CloudBlobContainer(final String containerName, final CloudBlobClient clie * Creates an instance of the CloudBlobContainer class using the specified URI and client. * * @param uri - * A java.net.URI object that represents the URI of the container. + * A java.net.URI object that represents the absolute URI of the container. * @param client * A {@link CloudBlobClient} object that represents the associated service client, and that specifies the * endpoint for the Blob service. @@ -179,7 +212,7 @@ public CloudBlobContainer(final URI uri, final CloudBlobClient client) throws UR * Creates an instance of the CloudBlobContainer class using the specified URI and client. * * @param storageUri - * A StorageUri object that represents the URI of the container. + * A StorageUri object that represents the absolute URI of the container. * @param client * A {@link CloudBlobClient} object that represents the associated service client, and that specifies the * endpoint for the Blob service. @@ -197,8 +230,7 @@ public CloudBlobContainer(final StorageUri storageUri, final CloudBlobClient cli this.storageUri = storageUri; - boolean usePathStyleUris = client == null ? Utility.determinePathStyleFromUri(this.storageUri.getPrimaryUri(), - null) : client.isUsePathStyleUris(); + boolean usePathStyleUris = client == null ? Utility.determinePathStyleFromUri(this.storageUri.getPrimaryUri()) : client.isUsePathStyleUris(); this.name = PathUtility.getContainerNameFromUri(storageUri.getPrimaryUri(), usePathStyleUris); @@ -251,15 +283,14 @@ private StorageRequest createImpl(fin @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { - final HttpURLConnection request = ContainerRequest.create( - container.getStorageUri().getUri(this.getCurrentLocation()), options.getTimeoutIntervalInMs(), - context); + final HttpURLConnection request = BlobRequest.createContainer( + container.getStorageUri().getUri(this.getCurrentLocation()), options, context); return request; } @Override public void setHeaders(HttpURLConnection connection, CloudBlobContainer container, OperationContext context) { - ContainerRequest.addMetadata(connection, container.metadata, context); + BlobRequest.addMetadata(connection, container.metadata, context); } @Override @@ -277,8 +308,8 @@ public Void preProcessResponse(CloudBlobContainer container, CloudBlobClient cli } // Set attributes - final BlobContainerAttributes attributes = ContainerResponse.getAttributes(this.getConnection(), - client.isUsePathStyleUris()); + final BlobContainerAttributes attributes = BlobResponse.getBlobContainerAttributes( + this.getConnection(), client.isUsePathStyleUris()); container.properties = attributes.getProperties(); container.name = attributes.getName(); return null; @@ -392,8 +423,8 @@ private StorageRequest deleteImpl(fin @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { - return ContainerRequest.delete(container.getStorageUri().getPrimaryUri(), - options.getTimeoutIntervalInMs(), accessCondition, context); + return BlobRequest.deleteContainer(container.getStorageUri().getPrimaryUri(), options, context, + accessCondition); } @Override @@ -518,7 +549,7 @@ public void downloadAttributes(AccessCondition accessCondition, BlobRequestOptio } private StorageRequest downloadAttributesImpl( - final AccessCondition accessCondition, final BlobRequestOptions options) throws StorageException { + final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest getRequest = new StorageRequest( options, this.getStorageUri()) { @@ -530,8 +561,8 @@ public void setRequestLocationMode() { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { - return ContainerRequest.getProperties(container.getStorageUri().getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), accessCondition, context); + return BlobRequest.getContainerProperties(container.getStorageUri().getUri(this.getCurrentLocation()), + options, context, accessCondition); } @Override @@ -549,8 +580,8 @@ public Void preProcessResponse(CloudBlobContainer container, CloudBlobClient cli } // Set attributes - final BlobContainerAttributes attributes = ContainerResponse.getAttributes(this.getConnection(), - client.isUsePathStyleUris()); + final BlobContainerAttributes attributes = BlobResponse.getBlobContainerAttributes( + this.getConnection(), client.isUsePathStyleUris()); container.metadata = attributes.getMetadata(); container.properties = attributes.getProperties(); container.name = attributes.getName(); @@ -620,8 +651,8 @@ public void setRequestLocationMode() { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { - return ContainerRequest.getAcl(container.getStorageUri().getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), accessCondition, context); + return BlobRequest.getAcl(container.getStorageUri().getUri(this.getCurrentLocation()), options, + accessCondition, context); } @Override @@ -638,7 +669,7 @@ public BlobContainerPermissions preProcessResponse(CloudBlobContainer container, } container.updatePropertiesFromResponse(this.getConnection()); - final String aclString = ContainerResponse.getAcl(this.getConnection()); + final String aclString = BlobResponse.getAcl(this.getConnection()); final BlobContainerPermissions containerAcl = getContainerAcl(aclString); return containerAcl; } @@ -647,8 +678,8 @@ public BlobContainerPermissions preProcessResponse(CloudBlobContainer container, public BlobContainerPermissions postProcessResponse(HttpURLConnection connection, CloudBlobContainer container, CloudBlobClient client, OperationContext context, BlobContainerPermissions containerAcl) throws Exception { - HashMap accessIds = SharedAccessPolicyDeserializer - .getAccessIdentifiers(this.getConnection().getInputStream(), SharedAccessBlobPolicy.class); + HashMap accessIds = SharedAccessPolicyHandler.getAccessIdentifiers(this + .getConnection().getInputStream(), SharedAccessBlobPolicy.class); for (final String key : accessIds.keySet()) { containerAcl.getSharedAccessPolicies().put(key, accessIds.get(key)); @@ -715,7 +746,7 @@ private boolean exists(final boolean primaryOnly, final AccessCondition accessCo } private StorageRequest existsImpl(final boolean primaryOnly, - final AccessCondition accessCondition, final BlobRequestOptions options) throws StorageException { + final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest getRequest = new StorageRequest( options, this.getStorageUri()) { @@ -728,8 +759,8 @@ public void setRequestLocationMode() { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { - return ContainerRequest.getProperties(container.getStorageUri().getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), accessCondition, context); + return BlobRequest.getContainerProperties(container.getStorageUri().getUri(this.getCurrentLocation()), + options, context, accessCondition); } @Override @@ -767,14 +798,15 @@ else if (this.getResult().getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) { * @param groupPolicyIdentifier * A container-level access policy. * @return a shared access signature for the container. - * @throws InvalidKeyException * @throws StorageException - * @throws IllegalArgumentException + * If a storage service error occurred. + * @throws InvalidKeyException + * If the key is invalid. */ public String generateSharedAccessSignature(final SharedAccessBlobPolicy policy, final String groupPolicyIdentifier) throws InvalidKeyException, StorageException { - if (!this.blobServiceClient.getCredentials().canCredentialsSignRequest()) { + if (!StorageCredentialsHelper.canCredentialsSignRequest(this.blobServiceClient.getCredentials())) { final String errorMessage = SR.CANNOT_CREATE_SAS_WITHOUT_ACCOUNT_KEY; throw new IllegalArgumentException(errorMessage); } @@ -846,13 +878,10 @@ public CloudBlockBlob getBlockBlobReference(final String blobName, final String * A String that represents the name of the virtual blob directory. If the root directory * (the directory representing the container itself) is desired, use an empty string. * @return A {@link CloudBlobDirectory} that represents a virtual blob directory within this container. - * - * @throws StorageException - * If a storage service error occurred. * @throws URISyntaxException * If the resource URI is invalid. */ - public CloudBlobDirectory getDirectoryReference(String directoryName) throws URISyntaxException, StorageException { + public CloudBlobDirectory getDirectoryReference(String directoryName) throws URISyntaxException { Utility.assertNotNull("directoryName", directoryName); // if the directory name does not end in the delimiter, add the delimiter @@ -866,7 +895,8 @@ public CloudBlobDirectory getDirectoryReference(String directoryName) throws URI } /** - * Returns the metadata for the container. + * Returns the metadata for the container. This value is initialized with the metadata from the queue by a call to + * {@link #downloadAttributes}, and is set on the queue with a call to {@link #uploadMetadata}. * * @return A java.util.HashMap object that represents the metadata for the container. */ @@ -888,7 +918,7 @@ public String getName() { * * @return A StorageUri that represents the list of URIs for all locations.. */ - public final StorageUri getStorageUri() { + public StorageUri getStorageUri() { return this.storageUri; } @@ -983,19 +1013,7 @@ private String getSharedAccessCanonicalName() { * If the resource URI is invalid. */ private StorageUri getTransformedAddress() throws URISyntaxException, StorageException { - if (this.blobServiceClient.getCredentials().doCredentialsNeedTransformUri()) { - if (this.getStorageUri().isAbsolute()) { - return this.blobServiceClient.getCredentials().transformUri(this.storageUri); - } - else { - final StorageException ex = Utility.generateNewUnexpectedStorageException(null); - ex.getExtendedErrorInformation().setErrorMessage("Blob Object relative URIs not supported."); - throw ex; - } - } - else { - return this.storageUri; - } + return this.blobServiceClient.getCredentials().transformUri(this.storageUri); } /** @@ -1012,11 +1030,9 @@ public URI getUri() { * * @return An enumerable collection of {@link ListBlobItem} objects retrieved lazily that represents the items in * this container. - * @throws StorageException - * If a storage service error occurred. */ @DoesServiceRequest - public Iterable listBlobs() throws StorageException { + public Iterable listBlobs() { return this.listBlobs(null, false, EnumSet.noneOf(BlobListingDetails.class), null, null); } @@ -1030,11 +1046,9 @@ public Iterable listBlobs() throws StorageException { * @return An enumerable collection of {@link ListBlobItem} objects retrieved lazily that represents the items whose * names begin with * the specified prefix in this container. - * @throws StorageException - * If a storage service error occurred. */ @DoesServiceRequest - public Iterable listBlobs(final String prefix) throws StorageException { + public Iterable listBlobs(final String prefix) { return this.listBlobs(prefix, false, EnumSet.noneOf(BlobListingDetails.class), null, null); } @@ -1064,16 +1078,10 @@ public Iterable listBlobs(final String prefix) throws StorageExcep * @return An enumerable collection of {@link ListBlobItem} objects retrieved lazily that represent the block items * whose names begin * with the specified prefix in this directory. - * - * @throws StorageException - * If a storage service error occurred. - * @throws URISyntaxException - * If the resource URI is invalid. */ @DoesServiceRequest public Iterable listBlobs(final String prefix, final boolean useFlatBlobListing, - final EnumSet listingDetails, BlobRequestOptions options, OperationContext opContext) - throws StorageException { + final EnumSet listingDetails, BlobRequestOptions options, OperationContext opContext) { if (opContext == null) { opContext = new OperationContext(); } @@ -1186,8 +1194,7 @@ public ResultSegment listBlobsSegmented(final String prefix, final private StorageRequest> listBlobsSegmentedImpl( final String prefix, final boolean useFlatBlobListing, final EnumSet listingDetails, - final int maxResults, final BlobRequestOptions options, final SegmentedStorageRequest segmentedRequest) - throws StorageException { + final int maxResults, final BlobRequestOptions options, final SegmentedStorageRequest segmentedRequest) { Utility.assertContinuationType(segmentedRequest.getToken(), ResultContinuationType.BLOB); Utility.assertNotNull("options", options); @@ -1209,8 +1216,8 @@ public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer OperationContext context) throws Exception { listingContext.setMarker(segmentedRequest.getToken() != null ? segmentedRequest.getToken() .getNextMarker() : null); - return BlobRequest.list(container.getTransformedAddress().getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), listingContext, options, context); + return BlobRequest.listBlobs(container.getTransformedAddress().getUri(this.getCurrentLocation()), + options, context, listingContext); } @Override @@ -1233,8 +1240,7 @@ public ResultSegment preProcessResponse(CloudBlobContainer contain public ResultSegment postProcessResponse(HttpURLConnection connection, CloudBlobContainer container, CloudBlobClient client, OperationContext context, ResultSegment storageObject) throws Exception { - final ListBlobsResponse response = BlobDeserializer.getBlobList(connection.getInputStream(), client, - container); + final ListBlobsResponse response = BlobListHandler.getBlobList(connection.getInputStream(), container); ResultContinuation newToken = null; @@ -1264,10 +1270,9 @@ public ResultSegment postProcessResponse(HttpURLConnection connect * @return An enumerable collection of {@link CloudBlobContainer} objects retrieved lazily that represent the * containers for the * service client associated with this container. - * @throws StorageException */ @DoesServiceRequest - public Iterable listContainers() throws StorageException { + public Iterable listContainers() { return this.blobServiceClient.listContainers(); } @@ -1281,10 +1286,9 @@ public Iterable listContainers() throws StorageException { * @return An enumerable collection of {@link CloudBlobContainer} objects retrieved lazily that represent the * containers whose names * begin with the specified prefix for the service client associated with this container. - * @throws StorageException */ @DoesServiceRequest - public Iterable listContainers(final String prefix) throws StorageException { + public Iterable listContainers(final String prefix) { return this.blobServiceClient.listContainers(prefix); } @@ -1308,12 +1312,11 @@ public Iterable listContainers(final String prefix) throws S * @return An enumerable collection of {@link CloudBlobContainer} objects retrieved lazily that represents the * containers for the * service client associated with this container. - * @throws StorageException */ @DoesServiceRequest public Iterable listContainers(final String prefix, final ContainerListingDetails detailsIncluded, final BlobRequestOptions options, - final OperationContext opContext) throws StorageException { + final OperationContext opContext) { return this.blobServiceClient.listContainers(prefix, detailsIncluded, options, opContext); } @@ -1405,8 +1408,10 @@ public ResultSegment listContainersSegmented(final String pr * The client to use. * @param usePathStyleUris * If true, path style Uris are used. - * @throws URISyntaxException * @throws StorageException + * If a storage service error occurred. + * @throws URISyntaxException + * If the resource URI is invalid. */ private void parseQueryAndVerify(final StorageUri completeUri, final CloudBlobClient existingClient, final boolean usePathStyleUris) throws URISyntaxException, StorageException { @@ -1424,6 +1429,10 @@ private void parseQueryAndVerify(final StorageUri completeUri, final CloudBlobCl .parseQuery(queryParameters); if (sasCreds == null) { + if (existingClient == null) { + this.blobServiceClient = new CloudBlobClient(new URI(PathUtility.getServiceClientBaseAddress( + this.getUri(), usePathStyleUris))); + } return; } @@ -1436,12 +1445,9 @@ private void parseQueryAndVerify(final StorageUri completeUri, final CloudBlobCl } if (existingClient != null && !sameCredentials) { - this.blobServiceClient.setSingleBlobPutThresholdInBytes(existingClient.getSingleBlobPutThresholdInBytes()); - this.blobServiceClient.setConcurrentRequestCount(existingClient.getConcurrentRequestCount()); + this.blobServiceClient.setDefaultRequestOptions(new BlobRequestOptions(existingClient + .getDefaultRequestOptions())); this.blobServiceClient.setDirectoryDelimiter(existingClient.getDirectoryDelimiter()); - this.blobServiceClient.setRetryPolicyFactory(existingClient.getRetryPolicyFactory()); - this.blobServiceClient.setTimeoutInMs(existingClient.getTimeoutInMs()); - this.blobServiceClient.setLocationMode(existingClient.getLocationMode()); } } @@ -1459,7 +1465,9 @@ void updatePropertiesFromResponse(HttpURLConnection request) { } /** - * Sets the metadata for the container. + * Sets the metadata collection of name-value pairs to be set on the container with an {@link #uploadMetadata} call. + * This collection will overwrite any existing container metadata. If this is set to an empty collection, the + * container metadata will be cleared on an {@link #uploadMetadata} call. * * @param metadata * A java.util.HashMap object that represents the metadata being assigned to the container. @@ -1544,20 +1552,20 @@ public void uploadMetadata(AccessCondition accessCondition, BlobRequestOptions o @DoesServiceRequest private StorageRequest uploadMetadataImpl( - final AccessCondition accessCondition, final BlobRequestOptions options) throws StorageException { + final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { - return ContainerRequest.setMetadata(container.getStorageUri().getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), accessCondition, context); + return BlobRequest.setContainerMetadata(container.getStorageUri().getUri(this.getCurrentLocation()), + options, context, accessCondition); } @Override public void setHeaders(HttpURLConnection connection, CloudBlobContainer container, OperationContext context) { - ContainerRequest.addMetadata(connection, container.metadata, context); + BlobRequest.addMetadata(connection, container.metadata, context); } @Override @@ -1644,8 +1652,8 @@ public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer OperationContext context) throws Exception { this.setSendStream(new ByteArrayInputStream(aclBytes)); this.setLength((long) aclBytes.length); - return ContainerRequest.setAcl(container.getStorageUri().getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), permissions.getPublicAccess(), accessCondition, context); + return BlobRequest.setAcl(container.getStorageUri().getUri(this.getCurrentLocation()), options, + context, accessCondition, permissions.getPublicAccess()); } @Override @@ -1758,16 +1766,16 @@ public final String acquireLease(final Integer leaseTimeInSeconds, final String private StorageRequest acquireLeaseImpl( final Integer leaseTimeInSeconds, final String proposedLeaseId, final AccessCondition accessCondition, - final BlobRequestOptions options) throws StorageException { + final BlobRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { - return ContainerRequest.lease(container.getStorageUri().getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), LeaseAction.ACQUIRE, leaseTimeInSeconds, proposedLeaseId, - null /* breakPeriodInSeconds */, accessCondition, options, context); + return BlobRequest + .leaseContainer(container.getStorageUri().getUri(this.getCurrentLocation()), options, context, + accessCondition, LeaseAction.ACQUIRE, leaseTimeInSeconds, proposedLeaseId, null /* breakPeriodInSeconds */); } @Override @@ -1847,17 +1855,16 @@ public final void renewLease(final AccessCondition accessCondition, BlobRequestO } private StorageRequest renewLeaseImpl( - final AccessCondition accessCondition, final BlobRequestOptions options) throws StorageException { + final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { - return ContainerRequest.lease(container.getStorageUri().getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), LeaseAction.RENEW, null /* leaseTimeInSeconds */, - null /* proposedLeaseId */, null /* breakPeriodInseconds */, accessCondition, options, - context); + return BlobRequest.leaseContainer(container.getStorageUri().getUri(this.getCurrentLocation()), options, + context, accessCondition, LeaseAction.RENEW, null /* leaseTimeInSeconds */, + null /* proposedLeaseId */, null /* breakPeriodInseconds */); } @Override @@ -1936,16 +1943,15 @@ public final void releaseLease(final AccessCondition accessCondition, BlobReques } private StorageRequest releaseLeaseImpl( - final AccessCondition accessCondition, final BlobRequestOptions options) throws StorageException { + final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { - return ContainerRequest.lease(container.getStorageUri().getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), LeaseAction.RELEASE, null, null, null, accessCondition, - options, context); + return BlobRequest.leaseContainer(container.getStorageUri().getUri(this.getCurrentLocation()), options, + context, accessCondition, LeaseAction.RELEASE, null, null, null); } @Override @@ -2032,17 +2038,15 @@ public final long breakLease(final Integer breakPeriodInSeconds, final AccessCon } private final StorageRequest breakLeaseImpl( - final Integer breakPeriodInSeconds, final AccessCondition accessCondition, final BlobRequestOptions options) - throws StorageException { + final Integer breakPeriodInSeconds, final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest putCmd = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { - return ContainerRequest.lease(container.getStorageUri().getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), LeaseAction.BREAK, null, null, breakPeriodInSeconds, - accessCondition, options, context); + return BlobRequest.leaseContainer(container.getStorageUri().getUri(this.getCurrentLocation()), options, + context, accessCondition, LeaseAction.BREAK, null, null, breakPeriodInSeconds); } @Override @@ -2134,17 +2138,15 @@ public final String changeLease(final String proposedLeaseId, final AccessCondit } private final StorageRequest changeLeaseImpl( - final String proposedLeaseId, final AccessCondition accessCondition, final BlobRequestOptions options) - throws StorageException { + final String proposedLeaseId, final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { - return ContainerRequest.lease(container.getStorageUri().getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), LeaseAction.CHANGE, null, proposedLeaseId, null, - accessCondition, options, context); + return BlobRequest.leaseContainer(container.getStorageUri().getUri(this.getCurrentLocation()), options, + context, accessCondition, LeaseAction.CHANGE, null, proposedLeaseId, null); } @Override diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/CloudBlobDirectory.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlobDirectory.java similarity index 95% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/CloudBlobDirectory.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlobDirectory.java index 7886b3fa6b16e..a985dd719fc41 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/CloudBlobDirectory.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlobDirectory.java @@ -12,21 +12,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import java.net.URI; import java.net.URISyntaxException; import java.util.EnumSet; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.DoesServiceRequest; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.ResultContinuation; -import com.microsoft.windowsazure.storage.ResultSegment; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.StorageUri; -import com.microsoft.windowsazure.storage.core.PathUtility; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.DoesServiceRequest; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.ResultContinuation; +import com.microsoft.azure.storage.ResultSegment; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.StorageUri; +import com.microsoft.azure.storage.core.PathUtility; +import com.microsoft.azure.storage.core.Utility; /** * Represents a virtual directory of blobs, designated by a delimiter character. @@ -244,13 +244,8 @@ public CloudBlobDirectory getParent() throws URISyntaxException, StorageExceptio * Returns the prefix for this directory. * * @return A String that represents the prefix for this directory. - * - * @throws StorageException - * If a storage service error occurred. - * @throws URISyntaxException - * If the resource URI is invalid. */ - public String getPrefix() throws StorageException, URISyntaxException { + public String getPrefix() { return this.prefix; } @@ -271,13 +266,10 @@ public CloudBlobClient getServiceClient() { * * @return A CloudBlobDirectory object that represents a virtual blob directory beneath this directory. * - * @throws StorageException - * If a storage service error occurred. * @throws URISyntaxException * If the resource URI is invalid. */ - public CloudBlobDirectory getSubDirectoryReference(String directoryName) throws StorageException, - URISyntaxException { + public CloudBlobDirectory getSubDirectoryReference(String directoryName) throws URISyntaxException { Utility.assertNotNullOrEmpty("directoryName", directoryName); if (!directoryName.endsWith(this.blobServiceClient.getDirectoryDelimiter())) { diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/CloudBlockBlob.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlockBlob.java similarity index 88% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/CloudBlockBlob.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlockBlob.java index acfffe541eeca..bee5d0b3283b2 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/CloudBlockBlob.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlockBlob.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -24,19 +24,19 @@ import javax.xml.stream.XMLStreamException; -import com.microsoft.windowsazure.storage.AccessCondition; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.DoesServiceRequest; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.StorageUri; -import com.microsoft.windowsazure.storage.core.Base64; -import com.microsoft.windowsazure.storage.core.ExecutionEngine; -import com.microsoft.windowsazure.storage.core.RequestLocationMode; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.StorageRequest; -import com.microsoft.windowsazure.storage.core.StreamMd5AndLength; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.AccessCondition; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.DoesServiceRequest; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.StorageUri; +import com.microsoft.azure.storage.core.Base64; +import com.microsoft.azure.storage.core.ExecutionEngine; +import com.microsoft.azure.storage.core.RequestLocationMode; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.StorageRequest; +import com.microsoft.azure.storage.core.StreamMd5AndLength; +import com.microsoft.azure.storage.core.Utility; /** * Represents a blob that is uploaded as a set of blocks. @@ -44,37 +44,34 @@ public final class CloudBlockBlob extends CloudBlob { /** - * Creates an instance of the CloudBlockBlob class using the specified relative URI and storage service - * client. + * Creates an instance of the CloudBlockBlob class using the specified absolute URI. * - * @param uri - * A java.net.URI object that represents the relative URI to the blob, beginning with the - * container name. + * @param blobAbsoluteUri + * A java.net.URI object that represents the absolute URI to the blob. * * @throws StorageException * If a storage service error occurred. */ - public CloudBlockBlob(final URI uri) throws StorageException { - this(new StorageUri(uri)); + public CloudBlockBlob(final URI blobAbsoluteUri) throws StorageException { + this(new StorageUri(blobAbsoluteUri)); } /** - * Creates an instance of the CloudBlockBlob class using the specified relative URI and storage service - * client. + * Creates an instance of the CloudBlockBlob class using the specified absolute StorageUri. * - * @param uri - * A StorageUri object that represents the relative URI to the blob, beginning with the - * container name. + * @param blobAbsoluteUri + * A StorageUri object that represents the absolute URI to the blob. * * @throws StorageException * If a storage service error occurred. */ - public CloudBlockBlob(final StorageUri uri) throws StorageException { + public CloudBlockBlob(final StorageUri blobAbsoluteUri) throws StorageException { super(BlobType.BLOCK_BLOB); - Utility.assertNotNull("blobAbsoluteUri", uri); - this.setStorageUri(uri); - this.parseURIQueryStringAndVerify(uri, null, Utility.determinePathStyleFromUri(uri.getPrimaryUri(), null)); + Utility.assertNotNull("blobAbsoluteUri", blobAbsoluteUri); + this.setStorageUri(blobAbsoluteUri); + this.parseURIQueryStringAndVerify(blobAbsoluteUri, null, + Utility.determinePathStyleFromUri(blobAbsoluteUri.getPrimaryUri())); } /** @@ -82,54 +79,49 @@ public CloudBlockBlob(final StorageUri uri) throws StorageException { * * @param otherBlob * A CloudBlockBlob object that represents the block blob to copy. - * - * @throws StorageException - * If a storage service error occurs. */ - public CloudBlockBlob(final CloudBlockBlob otherBlob) throws StorageException { + public CloudBlockBlob(final CloudBlockBlob otherBlob) { super(otherBlob); } /** - * Creates an instance of the CloudBlockBlob class using the specified relative URI and storage service + * Creates an instance of the CloudBlockBlob class using the specified absolute URI and storage service * client. * - * @param uri - * A java.net.URI object that represents the relative URI to the blob, beginning with the - * container name. + * @param blobAbsoluteUri + * A java.net.URI object that represents the absolute URI to the blob. * @param client * A {@link CloudBlobClient} object that specifies the endpoint for the Blob service. * * @throws StorageException * If a storage service error occurred. */ - public CloudBlockBlob(final URI uri, final CloudBlobClient client) throws StorageException { - this(new StorageUri(uri), client); + public CloudBlockBlob(final URI blobAbsoluteUri, final CloudBlobClient client) throws StorageException { + this(new StorageUri(blobAbsoluteUri), client); } /** - * Creates an instance of the CloudBlockBlob class using the specified relative URI and storage service - * client. + * Creates an instance of the CloudBlockBlob class using the specified absolute StorageUri and storage + * service client. * - * @param uri - * A StorageUri object that represents the relative URI to the blob, beginning with the - * container name. + * @param blobAbsoluteUri + * A StorageUri object that represents the absolute URI to the blob. * @param client * A {@link CloudBlobClient} object that specifies the endpoint for the Blob service. * * @throws StorageException * If a storage service error occurred. */ - public CloudBlockBlob(final StorageUri uri, final CloudBlobClient client) throws StorageException { - super(BlobType.BLOCK_BLOB, uri, client); + public CloudBlockBlob(final StorageUri blobAbsoluteUri, final CloudBlobClient client) throws StorageException { + super(BlobType.BLOCK_BLOB, blobAbsoluteUri, client); } /** - * Creates an instance of the CloudBlockBlob class using the specified relative URI, storage service + * Creates an instance of the CloudBlockBlob class using the specified absolute URI, storage service * client and container. * - * @param uri - * A java.net.URI object that represents the relative URI to the blob. + * @param blobAbsoluteUri + * A java.net.URI object that represents the absolute URI to the blob. * @param client * A {@link CloudBlobClient} object that specifies the endpoint for the Blob service. * @param container @@ -138,17 +130,17 @@ public CloudBlockBlob(final StorageUri uri, final CloudBlobClient client) throws * @throws StorageException * If a storage service error occurred. */ - public CloudBlockBlob(final URI uri, final CloudBlobClient client, final CloudBlobContainer container) + public CloudBlockBlob(final URI blobAbsoluteUri, final CloudBlobClient client, final CloudBlobContainer container) throws StorageException { - this(new StorageUri(uri), client, container); + this(new StorageUri(blobAbsoluteUri), client, container); } /** - * Creates an instance of the CloudBlockBlob class using the specified relative URI, storage service - * client and container. + * Creates an instance of the CloudBlockBlob class using the specified absolute StorageUri, storage + * service client and container. * - * @param uri - * A StorageUri object that represents the relative URI to the blob. + * @param blobAbsoluteUri + * A StorageUri object that represents the absolute URI to the blob. * @param client * A {@link CloudBlobClient} object that specifies the endpoint for the Blob service. * @param container @@ -157,17 +149,17 @@ public CloudBlockBlob(final URI uri, final CloudBlobClient client, final CloudBl * @throws StorageException * If a storage service error occurred. */ - public CloudBlockBlob(final StorageUri uri, final CloudBlobClient client, final CloudBlobContainer container) - throws StorageException { - super(BlobType.BLOCK_BLOB, uri, client, container); + public CloudBlockBlob(final StorageUri blobAbsoluteUri, final CloudBlobClient client, + final CloudBlobContainer container) throws StorageException { + super(BlobType.BLOCK_BLOB, blobAbsoluteUri, client, container); } /** - * Creates an instance of the CloudBlockBlob class using the specified relative URI, snapshot ID, and + * Creates an instance of the CloudBlockBlob class using the specified absolute URI, snapshot ID, and * storage service client. * - * @param uri - * A java.net.URI object that represents the relative URI to the blob. + * @param blobAbsoluteUri + * A java.net.URI object that represents the absolute URI to the blob. * @param snapshotID * A String that represents the snapshot version, if applicable. * @param client @@ -176,16 +168,17 @@ public CloudBlockBlob(final StorageUri uri, final CloudBlobClient client, final * @throws StorageException * If a storage service error occurred. */ - public CloudBlockBlob(final URI uri, final String snapshotID, final CloudBlobClient client) throws StorageException { - this(new StorageUri(uri), snapshotID, client); + public CloudBlockBlob(final URI blobAbsoluteUri, final String snapshotID, final CloudBlobClient client) + throws StorageException { + this(new StorageUri(blobAbsoluteUri), snapshotID, client); } /** - * Creates an instance of the CloudBlockBlob class using the specified relative URI, snapshot ID, and - * storage service client. + * Creates an instance of the CloudBlockBlob class using the specified absolute StorageUri, snapshot + * ID, and storage service client. * - * @param uri - * A StorageUri object that represents the relative URI to the blob. + * @param blobAbsoluteUri + * A StorageUri object that represents the absolute URI to the blob. * @param snapshotID * A String that represents the snapshot version, if applicable. * @param client @@ -194,13 +187,14 @@ public CloudBlockBlob(final URI uri, final String snapshotID, final CloudBlobCli * @throws StorageException * If a storage service error occurred. */ - public CloudBlockBlob(final StorageUri uri, final String snapshotID, final CloudBlobClient client) + public CloudBlockBlob(final StorageUri blobAbsoluteUri, final String snapshotID, final CloudBlobClient client) throws StorageException { - super(BlobType.BLOCK_BLOB, uri, snapshotID, client); + super(BlobType.BLOCK_BLOB, blobAbsoluteUri, snapshotID, client); } /** - * Commits a block list to the storage service. + * Commits a block list to the storage service. In order to be written as part of a blob, a block must have been + * successfully written to the server in a prior uploadBlock operation. * * @param blockList * An enumerable collection of BlockEntry objects that represents the list block items being @@ -216,6 +210,8 @@ public void commitBlockList(final Iterable blockList) throws Storage /** * Commits a block list to the storage service using the specified lease ID, request options, and operation context. + * In order to be written as part of a blob, a block must have been successfully written to the server in a prior + * uploadBlock operation. * * @param blockList * An enumerable collection of BlockEntry objects that represents the list block items being @@ -273,8 +269,8 @@ public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, Op this.setSendStream(blockListInputStream); this.setLength(descriptor.getLength()); return BlobRequest.putBlockList( - blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), blob.properties, accessCondition, options, context); + blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), options, context, + accessCondition, blob.properties); } @Override @@ -345,6 +341,10 @@ public ArrayList downloadBlockList() throws StorageException { /** * Downloads the block list from the block blob using the specified block listing filter, request options, and * operation context. + *

+ * The committed block list includes the list of blocks that have been successfully committed to the block blob. The + * list of committed blocks is returned in the same order that they were committed to the blob. No block may appear + * more than once in the committed block list. * * @param blockListingFilter * A {@link BlockListingFilter} value that specifies whether to download committed blocks, uncommitted @@ -386,7 +386,7 @@ public ArrayList downloadBlockList(final BlockListingFilter blockLis private StorageRequest> downloadBlockListImpl( final BlockListingFilter blockListingFilter, final AccessCondition accessCondition, - final BlobRequestOptions options) throws StorageException { + final BlobRequestOptions options) { final StorageRequest> getRequest = new StorageRequest>( options, this.getStorageUri()) { @@ -399,8 +399,7 @@ public void setRequestLocationMode() { public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, OperationContext context) throws Exception { return BlobRequest.getBlockList(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), blob.snapshotID, blockListingFilter, accessCondition, - options, context); + options, context, accessCondition, blob.snapshotID, blockListingFilter); } @Override @@ -426,7 +425,7 @@ public ArrayList postProcessResponse(HttpURLConnection connection, C blob.updateEtagAndLastModifiedFromResponse(this.getConnection()); blob.updateLengthFromResponse(this.getConnection()); - return BlobDeserializer.getBlockList(this.getConnection().getInputStream()); + return BlockListHandler.getBlockList(this.getConnection().getInputStream()); } }; @@ -583,7 +582,7 @@ public void upload(final InputStream sourceStream, final long length, final Acce } /** - * Uploads a block to the block blob, using the specified block ID and lease ID. + * Uploads a block to be committed as part of the block blob, using the specified block ID. * * @param blockId * A String that represents the Base-64 encoded block ID. Note for a given blob the length @@ -604,13 +603,12 @@ public void uploadBlock(final String blockId, final InputStream sourceStream, fi } /** - * Uploads a block to the block blob, using the specified block ID, lease ID, request options, and operation - * context. + * Uploads a block to be committed as part of the block blob, using the specified block ID, the specified lease ID, + * request options, and operation context. * * @param blockId * A String that represents the Base-64 encoded block ID. Note for a given blob the length * of all Block IDs must be identical. - * * @param sourceStream * An InputStream object that represents the input stream to write to the block blob. * @param length @@ -708,12 +706,11 @@ else if (length < 0 || options.getUseTransactionalContentMD5()) { * an object used to track the execution of the operation * @throws StorageException * If a storage service error occurred. - * @throws IOException */ @DoesServiceRequest private void uploadBlockInternal(final String blockId, final String md5, final InputStream sourceStream, final long length, final AccessCondition accessCondition, final BlobRequestOptions options, - final OperationContext opContext) throws StorageException, IOException { + final OperationContext opContext) throws StorageException { ExecutionEngine.executeWithRetry(this.blobServiceClient, this, uploadBlockImpl(blockId, md5, sourceStream, length, accessCondition, options, opContext), options.getRetryPolicyFactory(), opContext); @@ -721,7 +718,7 @@ private void uploadBlockInternal(final String blockId, final String md5, final I private StorageRequest uploadBlockImpl(final String blockId, final String md5, final InputStream sourceStream, final long length, final AccessCondition accessCondition, - final BlobRequestOptions options, final OperationContext opContext) throws StorageException, IOException { + final BlobRequestOptions options, final OperationContext opContext) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @@ -732,7 +729,7 @@ public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, Op this.setSendStream(sourceStream); this.setLength(length); return BlobRequest.putBlock(blob.getTransformedAddress(opContext).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), blockId, accessCondition, options, opContext); + options, opContext, accessCondition, blockId); } @Override diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/CloudPageBlob.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudPageBlob.java similarity index 85% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/CloudPageBlob.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudPageBlob.java index b169b8127f9b6..5b30a57a21e02 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/CloudPageBlob.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudPageBlob.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -23,55 +23,54 @@ import java.security.NoSuchAlgorithmException; import java.util.ArrayList; -import com.microsoft.windowsazure.storage.AccessCondition; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.DoesServiceRequest; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.StorageUri; -import com.microsoft.windowsazure.storage.core.Base64; -import com.microsoft.windowsazure.storage.core.ExecutionEngine; -import com.microsoft.windowsazure.storage.core.RequestLocationMode; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.StorageRequest; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.AccessCondition; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.DoesServiceRequest; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.StorageUri; +import com.microsoft.azure.storage.core.Base64; +import com.microsoft.azure.storage.core.ExecutionEngine; +import com.microsoft.azure.storage.core.RequestLocationMode; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.StorageRequest; +import com.microsoft.azure.storage.core.Utility; /** - * Represents a Windows Azure page blob. + * Represents a Microsoft Azure page blob. */ public final class CloudPageBlob extends CloudBlob { /** - * Creates an instance of the CloudPageBlob class using the specified relative URI and storage service + * Creates an instance of the CloudPageBlob class using the specified absolute URI and storage service * client. * - * @param uri - * A java.net.URI object that represents the relative URI to the blob, beginning with the - * container name. + * @param blobAbsoluteUri + * A java.net.URI object that represents the absolute URI to the blob. * * @throws StorageException * If a storage service error occurred. */ - public CloudPageBlob(final URI uri) throws StorageException { - this(new StorageUri(uri)); + public CloudPageBlob(final URI blobAbsoluteUri) throws StorageException { + this(new StorageUri(blobAbsoluteUri)); } /** - * Creates an instance of the CloudPageBlob class using the specified relative URI and storage service + * Creates an instance of the CloudPageBlob class using the specified absolute URI and storage service * client. * - * @param uri - * A StorageUri object that represents the relative URI to the blob, beginning with the - * container name. + * @param blobAbsoluteUri + * A StorageUri object that represents the absolute URI to the blob. * * @throws StorageException * If a storage service error occurred. */ - public CloudPageBlob(final StorageUri uri) throws StorageException { + public CloudPageBlob(final StorageUri blobAbsoluteUri) throws StorageException { super(BlobType.PAGE_BLOB); - Utility.assertNotNull("blobAbsoluteUri", uri); - this.setStorageUri(uri); - this.parseURIQueryStringAndVerify(uri, null, Utility.determinePathStyleFromUri(uri.getPrimaryUri(), null));; + Utility.assertNotNull("blobAbsoluteUri", blobAbsoluteUri); + this.setStorageUri(blobAbsoluteUri); + this.parseURIQueryStringAndVerify(blobAbsoluteUri, null, + Utility.determinePathStyleFromUri(blobAbsoluteUri.getPrimaryUri()));; } /** @@ -79,53 +78,47 @@ public CloudPageBlob(final StorageUri uri) throws StorageException { * * @param otherBlob * A CloudPageBlob object that represents the page blob to copy. - * - * @throws StorageException - * If a storage service error occurred. */ - public CloudPageBlob(final CloudPageBlob otherBlob) throws StorageException { + public CloudPageBlob(final CloudPageBlob otherBlob) { super(otherBlob); } /** * Creates an instance of the CloudPageBlob class using the specified URI and cloud blob client. * - * @param uri - * A java.net.URI object that represents the absolute URI to the blob, beginning with the - * container name. + * @param blobAbsoluteUri + * A java.net.URI object that represents the absolute URI to the blob. * @param client * A {@link CloudBlobClient} object that specifies the endpoint for the Blob service. * * @throws StorageException * If a storage service error occurred. */ - public CloudPageBlob(final URI uri, final CloudBlobClient client) throws StorageException { - this(new StorageUri(uri), client); + public CloudPageBlob(final URI blobAbsoluteUri, final CloudBlobClient client) throws StorageException { + this(new StorageUri(blobAbsoluteUri), client); } /** * Creates an instance of the CloudPageBlob class using the specified URI and cloud blob client. * - * @param uri - * A StorageUri object that represents the absolute URI to the blob, beginning with the - * container name. + * @param blobAbsoluteUri + * A StorageUri object that represents the absolute URI to the blob. * @param client * A {@link CloudBlobClient} object that specifies the endpoint for the Blob service. * * @throws StorageException * If a storage service error occurred. */ - public CloudPageBlob(final StorageUri uri, final CloudBlobClient client) throws StorageException { - super(BlobType.PAGE_BLOB, uri, client); + public CloudPageBlob(final StorageUri blobAbsoluteUri, final CloudBlobClient client) throws StorageException { + super(BlobType.PAGE_BLOB, blobAbsoluteUri, client); } /** * Creates an instance of the CloudPageBlob class using the specified URI, cloud blob client, and cloud * blob container. * - * @param uri - * A java.net.URI object that represents the relative URI to the blob, beginning with the - * container name. + * @param blobAbsoluteUri + * A java.net.URI object that represents the absolute URI to the blob. * @param client * A {@link CloudBlobClient} object that specifies the endpoint for the Blob service. * @param container @@ -134,18 +127,17 @@ public CloudPageBlob(final StorageUri uri, final CloudBlobClient client) throws * @throws StorageException * If a storage service error occurred. */ - public CloudPageBlob(final URI uri, final CloudBlobClient client, final CloudBlobContainer container) + public CloudPageBlob(final URI blobAbsoluteUri, final CloudBlobClient client, final CloudBlobContainer container) throws StorageException { - this(new StorageUri(uri), client, container); + this(new StorageUri(blobAbsoluteUri), client, container); } /** * Creates an instance of the CloudPageBlob class using the specified URI, cloud blob client, and cloud * blob container. * - * @param uri - * A StorageUri object that represents the relative URI to the blob, beginning with the - * container name. + * @param blobAbsoluteUri + * A StorageUri object that represents the absolute URI to the blob. * @param client * A {@link CloudBlobClient} object that specifies the endpoint for the Blob service. * @param container @@ -154,18 +146,17 @@ public CloudPageBlob(final URI uri, final CloudBlobClient client, final CloudBlo * @throws StorageException * If a storage service error occurred. */ - public CloudPageBlob(final StorageUri uri, final CloudBlobClient client, final CloudBlobContainer container) - throws StorageException { - super(BlobType.PAGE_BLOB, uri, client, container); + public CloudPageBlob(final StorageUri blobAbsoluteUri, final CloudBlobClient client, + final CloudBlobContainer container) throws StorageException { + super(BlobType.PAGE_BLOB, blobAbsoluteUri, client, container); } /** * Creates an instance of the CloudPageBlob class using the specified URI, snapshot ID, and cloud blob * client. * - * @param uri - * A java.net.URI object that represents the absolute URI to the blob, beginning with the - * container name. + * @param blobAbsoluteUri + * A java.net.URI object that represents the absolute URI to the blob. * @param snapshotID * A String that represents the snapshot version, if applicable. * @param client @@ -174,17 +165,17 @@ public CloudPageBlob(final StorageUri uri, final CloudBlobClient client, final C * @throws StorageException * If a storage service error occurred. */ - public CloudPageBlob(final URI uri, final String snapshotID, final CloudBlobClient client) throws StorageException { - this(new StorageUri(uri), snapshotID, client); + public CloudPageBlob(final URI blobAbsoluteUri, final String snapshotID, final CloudBlobClient client) + throws StorageException { + this(new StorageUri(blobAbsoluteUri), snapshotID, client); } /** * Creates an instance of the CloudPageBlob class using the specified URI, snapshot ID, and cloud blob * client. * - * @param uri - * A StorageUri object that represents the absolute URI to the blob, beginning with the - * container name. + * @param blobAbsoluteUri + * A StorageUri object that represents the absolute URI to the blob. * @param snapshotID * A String that represents the snapshot version, if applicable. * @param client @@ -193,9 +184,9 @@ public CloudPageBlob(final URI uri, final String snapshotID, final CloudBlobClie * @throws StorageException * If a storage service error occurred. */ - public CloudPageBlob(final StorageUri uri, final String snapshotID, final CloudBlobClient client) + public CloudPageBlob(final StorageUri blobAbsoluteUri, final String snapshotID, final CloudBlobClient client) throws StorageException { - super(BlobType.PAGE_BLOB, uri, snapshotID, client); + super(BlobType.PAGE_BLOB, blobAbsoluteUri, snapshotID, client); } /** @@ -209,13 +200,11 @@ public CloudPageBlob(final StorageUri uri, final String snapshotID, final CloudB * @param length * The length, in bytes, of the data range to be cleared. This value must be a multiple of 512. * - * @throws IOException - * If an I/O exception occurred. * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest - public void clearPages(final long offset, final long length) throws StorageException, IOException { + public void clearPages(final long offset, final long length) throws StorageException { this.clearPages(offset, length, null /* accessCondition */, null /* options */, null /* opContext */); } @@ -240,14 +229,12 @@ public void clearPages(final long offset, final long length) throws StorageExcep * is used to track requests to the storage service, and to provide additional runtime information about * the operation. * - * @throws IOException - * If an I/O exception occurred. * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public void clearPages(final long offset, final long length, final AccessCondition accessCondition, - BlobRequestOptions options, OperationContext opContext) throws StorageException, IOException { + BlobRequestOptions options, OperationContext opContext) throws StorageException { if (offset % BlobConstants.PAGE_SIZE != 0) { throw new IllegalArgumentException(SR.INVALID_PAGE_START_OFFSET); } @@ -327,16 +314,15 @@ public void create(final long length, final AccessCondition accessCondition, Blo } private StorageRequest createImpl(final long length, - final AccessCondition accessCondition, final BlobRequestOptions options) throws StorageException { + final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, OperationContext context) throws Exception { - return BlobRequest.put(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), blob.properties, BlobType.PAGE_BLOB, length, accessCondition, - options, context); + return BlobRequest.putBlob(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), + options, context, accessCondition, blob.properties, BlobType.PAGE_BLOB, length); } @Override @@ -419,7 +405,7 @@ public ArrayList downloadPageRanges(final AccessCondition accessCondi } private StorageRequest> downloadPageRangesImpl( - final AccessCondition accessCondition, final BlobRequestOptions options) throws StorageException { + final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest> getRequest = new StorageRequest>( options, this.getStorageUri()) { @@ -432,7 +418,7 @@ public void setRequestLocationMode() { public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, OperationContext context) throws Exception { return BlobRequest.getPageRanges(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), blob.snapshotID, accessCondition, options, context); + options, context, accessCondition, blob.snapshotID); } @Override @@ -458,7 +444,7 @@ public ArrayList postProcessResponse(HttpURLConnection connection, Cl blob.updateEtagAndLastModifiedFromResponse(this.getConnection()); blob.updateLengthFromResponse(this.getConnection()); - return BlobDeserializer.getPageRanges(this.getConnection().getInputStream()); + return PageRangeHandler.getPageRanges(this.getConnection().getInputStream()); } }; @@ -507,59 +493,6 @@ public BlobOutputStream openWriteExisting(AccessCondition accessCondition, BlobR .openOutputStreamInternal(null /* length */, null /* accessCondition */, null /* options */, null /* opContext */); } - /** - * Opens an output stream object to write data to the page blob. The page blob does not need to yet exist and will - * be created with the length specified. - * - * @deprecated As of release 0.6.0, replaced by {@link CloudPageBlob#openWriteNew(long)} - * - * @param length - * The length, in bytes, of the stream to create. This value must be a multiple of 512. - * - * @return A {@link BlobOutputStream} object used to write data to the blob. - * - * @throws StorageException - * If a storage service error occurred. - */ - @Deprecated - @DoesServiceRequest - public BlobOutputStream openOutputStream(final long length) throws StorageException { - return this - .openOutputStreamInternal(length, null /* accessCondition */, null /* options */, null /* opContext */); - } - - /** - * Opens an output stream object to write data to the page blob, using the specified lease ID, request options and - * operation context. The page blob does not need to yet exist and will be created with the length specified. - * - * @deprecated As of release 0.6.0, replaced by - * {@link CloudPageBlob#openWriteNew(long, AccessCondition, BlobRequestOptions, OperationContext)} - * - * @param length - * The length, in bytes, of the stream to create. This value must be a multiple of 512. - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for 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 that 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. - * - * @return A {@link BlobOutputStream} object used to write data to the blob. - * - * @throws StorageException - * If a storage service error occurred. - */ - @Deprecated - @DoesServiceRequest - public BlobOutputStream openOutputStream(final long length, AccessCondition accessCondition, - BlobRequestOptions options, OperationContext opContext) throws StorageException { - return openOutputStreamInternal(length, accessCondition, options, opContext); - } - /** * Opens an output stream object to write data to the page blob. The page blob does not need to yet exist and will * be created with the length specified. @@ -699,7 +632,7 @@ private void putPagesInternal(final PageProperties pageProperties, final byte[] private StorageRequest putPagesImpl(final PageProperties pageProperties, final byte[] data, final long length, final String md5, final AccessCondition accessCondition, - final BlobRequestOptions options, final OperationContext opContext) throws StorageException { + final BlobRequestOptions options, final OperationContext opContext) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @@ -712,7 +645,7 @@ public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, Op } return BlobRequest.putPage(blob.getTransformedAddress(opContext).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), pageProperties, accessCondition, options, opContext); + options, opContext, accessCondition, pageProperties); } @Override @@ -801,7 +734,7 @@ public void resize(long size, AccessCondition accessCondition, BlobRequestOption } private StorageRequest resizeImpl(final long size, - final AccessCondition accessCondition, final BlobRequestOptions options) throws StorageException { + final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @@ -809,7 +742,7 @@ private StorageRequest resizeImpl(final long s public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlob blob, OperationContext context) throws Exception { return BlobRequest.resize(blob.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), size, accessCondition, options, context); + options, context, accessCondition, size); } @Override diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/ContainerListHandler.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/ContainerListHandler.java new file mode 100644 index 0000000000000..f50cdb65aec8c --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/ContainerListHandler.java @@ -0,0 +1,197 @@ +/** + * 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 java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.text.ParseException; +import java.util.Stack; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.core.ListResponse; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; + +/** + * RESERVED FOR INTERNAL USE. A class used to deserialize a list of containers. + */ +final class ContainerListHandler extends DefaultHandler { + + private final Stack elementStack = new Stack(); + private StringBuilder bld = new StringBuilder(); + + private final CloudBlobClient serviceClient; + + private final ListResponse response = new ListResponse(); + private BlobContainerAttributes attributes; + private String containerName; + + private ContainerListHandler(CloudBlobClient serviceClient) { + this.serviceClient = serviceClient; + } + + /** + * Parses a {@link ContainerListResponse} form the given XML stream. + * + * @param serviceClient + * a reference to the client object associated with this object. + * @param stream + * the stream from which to parse the container list + * @throws SAXException + * @throws ParserConfigurationException + * @throws IOException + */ + protected static ListResponse getContainerList(final InputStream stream, + final CloudBlobClient serviceClient) throws ParserConfigurationException, SAXException, IOException { + SAXParser saxParser = Utility.getSAXParser(); + ContainerListHandler handler = new ContainerListHandler(serviceClient); + saxParser.parse(stream, handler); + + return handler.response; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + this.elementStack.push(localName); + + if (BlobConstants.CONTAINER_ELEMENT.equals(localName)) { + this.containerName = Constants.EMPTY_STRING; + this.attributes = new BlobContainerAttributes(); + } + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + String currentNode = this.elementStack.pop(); + + // if the node popped from the stack and the localName don't match, the xml document is improperly formatted + if (!localName.equals(currentNode)) { + throw new SAXException(SR.INVALID_RESPONSE_RECEIVED); + } + + String parentNode = null; + if (!this.elementStack.isEmpty()) { + parentNode = this.elementStack.peek(); + } + + String value = this.bld.toString(); + if (value.isEmpty()) { + value = null; + } + + if (BlobConstants.CONTAINER_ELEMENT.equals(currentNode)) { + try { + CloudBlobContainer retContainer = this.serviceClient.getContainerReference(this.containerName); + retContainer.setMetadata(this.attributes.getMetadata()); + retContainer.setProperties(this.attributes.getProperties()); + + this.response.getResults().add(retContainer); + } + catch (URISyntaxException e) { + throw new SAXException(e); + } + catch (StorageException e) { + throw new SAXException(e); + } + + } + else if (ListResponse.ENUMERATION_RESULTS.equals(parentNode)) { + if (Constants.PREFIX_ELEMENT.equals(currentNode)) { + this.response.setPrefix(value); + } + else if (Constants.MARKER_ELEMENT.equals(currentNode)) { + this.response.setMarker(value); + } + else if (Constants.NEXT_MARKER_ELEMENT.equals(currentNode)) { + this.response.setNextMarker(value); + } + else if (Constants.MAX_RESULTS_ELEMENT.equals(currentNode)) { + this.response.setMaxResults(Integer.parseInt(value)); + } + } + else if (BlobConstants.CONTAINER_ELEMENT.equals(parentNode)) { + if (Constants.NAME_ELEMENT.equals(currentNode)) { + this.containerName = value; + } + } + else if (BlobConstants.PROPERTIES.equals(parentNode)) { + try { + getProperties(currentNode, value); + } + catch (ParseException e) { + throw new SAXException(e); + } + } + else if (Constants.METADATA_ELEMENT.equals(parentNode)) { + if (value == null) { + value = ""; + } + this.attributes.getMetadata().put(currentNode, value); + } + + this.bld = new StringBuilder(); + } + + @Override + public void characters(char ch[], int start, int length) throws SAXException { + this.bld.append(ch, start, length); + } + + private void getProperties(String currentNode, String value) throws ParseException, SAXException { + + if (currentNode.equals(Constants.LAST_MODIFIED_ELEMENT)) { + this.attributes.getProperties().setLastModified(Utility.parseRFC1123DateFromStringInGMT(value)); + } + else if (currentNode.equals(Constants.ETAG_ELEMENT)) { + this.attributes.getProperties().setEtag(Utility.formatETag(value)); + } + else if (currentNode.equals(Constants.LEASE_STATUS_ELEMENT)) { + final LeaseStatus tempStatus = LeaseStatus.parse(value); + if (!tempStatus.equals(LeaseStatus.UNSPECIFIED)) { + this.attributes.getProperties().setLeaseStatus(tempStatus); + } + else { + throw new SAXException(SR.INVALID_RESPONSE_RECEIVED); + } + } + else if (currentNode.equals(Constants.LEASE_STATE_ELEMENT)) { + final LeaseState tempState = LeaseState.parse(value); + if (!tempState.equals(LeaseState.UNSPECIFIED)) { + this.attributes.getProperties().setLeaseState(tempState); + } + else { + throw new SAXException(SR.INVALID_RESPONSE_RECEIVED); + } + } + else if (currentNode.equals(Constants.LEASE_DURATION_ELEMENT)) { + final LeaseDuration tempDuration = LeaseDuration.parse(value); + if (!tempDuration.equals(LeaseDuration.UNSPECIFIED)) { + this.attributes.getProperties().setLeaseDuration(tempDuration); + } + else { + throw new SAXException(SR.INVALID_RESPONSE_RECEIVED); + } + } + } +} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/ContainerListingDetails.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/ContainerListingDetails.java similarity index 96% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/ContainerListingDetails.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/ContainerListingDetails.java index be1036c110a9f..0fdf349c90c3f 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/ContainerListingDetails.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/ContainerListingDetails.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; /** * Specifies which details to include when listing the containers in this storage account. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/CopyState.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CopyState.java similarity index 98% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/CopyState.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CopyState.java index 679f880f1be45..f6d879b7fcb26 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/CopyState.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CopyState.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import java.net.URI; import java.util.Date; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/CopyStatus.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CopyStatus.java similarity index 92% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/CopyStatus.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CopyStatus.java index 928ade2a8410a..dc29a799f6660 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/CopyStatus.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CopyStatus.java @@ -12,11 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import java.util.Locale; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.core.Utility; /** * Represents the status of a copy blob operation. @@ -60,7 +60,7 @@ public enum CopyStatus { * * @return A CopyStatus value that represents the copy status. */ - public static CopyStatus parse(final String typeString) { + protected static CopyStatus parse(final String typeString) { if (Utility.isNullOrEmpty(typeString)) { return UNSPECIFIED; } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/DeleteSnapshotsOption.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/DeleteSnapshotsOption.java similarity index 84% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/DeleteSnapshotsOption.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/DeleteSnapshotsOption.java index e9ce9b3de7a6a..949b956ab2fac 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/DeleteSnapshotsOption.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/DeleteSnapshotsOption.java @@ -15,7 +15,7 @@ /** * */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; /** * Specifies options when calling delete operations. @@ -32,7 +32,8 @@ public enum DeleteSnapshotsOption { INCLUDE_SNAPSHOTS, /** - * Specifies deleting the blob but not its snapshots. + * Specifies deleting the blob only. If the blob has snapshots, this option will result in an error from the + * service. */ NONE } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/LeaseAction.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/LeaseAction.java similarity index 93% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/LeaseAction.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/LeaseAction.java index 1d8f7ae34dd75..9f66cd59d4aba 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/LeaseAction.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/LeaseAction.java @@ -12,9 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; -import com.microsoft.windowsazure.storage.Constants; +import com.microsoft.azure.storage.Constants; /** * RESERVED FOR INTERNAL USE. Describes actions that can be performed on a lease. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/LeaseDuration.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/LeaseDuration.java similarity index 90% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/LeaseDuration.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/LeaseDuration.java index 6e63b103f16e8..fe7a7e9c05c0b 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/LeaseDuration.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/LeaseDuration.java @@ -12,11 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage.blob; import java.util.Locale; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.core.Utility; /** * The lease duration of a resource. @@ -45,7 +45,7 @@ public enum LeaseDuration { * * @return A LeaseStatus value that represents the lease status. */ - public static LeaseDuration parse(final String typeString) { + protected static LeaseDuration parse(final String typeString) { if (Utility.isNullOrEmpty(typeString)) { return UNSPECIFIED; } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/LeaseState.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/LeaseState.java similarity index 89% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/LeaseState.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/LeaseState.java index 4833faf99edc5..9ec32485064d2 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/LeaseState.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/LeaseState.java @@ -12,11 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage.blob; import java.util.Locale; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.core.Utility; /** * The lease state of a resource. @@ -60,14 +60,14 @@ public enum LeaseState { * * @return A LeaseStatus value that represents the lease status. */ - public static LeaseState parse(final String typeString) { + protected static LeaseState parse(final String typeString) { if (Utility.isNullOrEmpty(typeString)) { return UNSPECIFIED; } else if ("available".equals(typeString.toLowerCase(Locale.US))) { return AVAILABLE; } - else if ("locked".equals(typeString.toLowerCase(Locale.US))) { + else if ("leased".equals(typeString.toLowerCase(Locale.US))) { return LEASED; } else if ("expired".equals(typeString.toLowerCase(Locale.US))) { diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/LeaseStatus.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/LeaseStatus.java similarity index 91% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/LeaseStatus.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/LeaseStatus.java index 45d810c79ed37..cd855549ecd5b 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/LeaseStatus.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/LeaseStatus.java @@ -12,11 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage; +package com.microsoft.azure.storage.blob; import java.util.Locale; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.core.Utility; /** * Specifies the lease status of a blob. @@ -48,7 +48,7 @@ public enum LeaseStatus { * * @return A LeaseStatus value that represents the lease status. */ - public static LeaseStatus parse(final String typeString) { + protected static LeaseStatus parse(final String typeString) { if (Utility.isNullOrEmpty(typeString)) { return UNSPECIFIED; } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/ListBlobItem.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/ListBlobItem.java similarity index 92% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/ListBlobItem.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/ListBlobItem.java index 9e9a63ffbfe2b..0a0814bc606bf 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/ListBlobItem.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/ListBlobItem.java @@ -12,13 +12,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import java.net.URI; import java.net.URISyntaxException; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.StorageUri; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.StorageUri; /** * Represents an item that may be returned by a blob listing operation. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/ListBlobsResponse.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/ListBlobsResponse.java similarity index 91% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/ListBlobsResponse.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/ListBlobsResponse.java index 2e782027c5f3c..a303855025cae 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/ListBlobsResponse.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/ListBlobsResponse.java @@ -12,9 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; -import com.microsoft.windowsazure.storage.core.ListResponse; +import com.microsoft.azure.storage.core.ListResponse; /** * RESERVED FOR INTERNAL USE. A class used to parse a list blobs response stream. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/PageOperationType.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/PageOperationType.java similarity index 94% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/PageOperationType.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/PageOperationType.java index c6a4a191aaac4..915bab77ec2ba 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/PageOperationType.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/PageOperationType.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; /** * RESERVED FOR INTERNAL USE. Describes actions that may be used for writing to a page blob or clearing a set of pages. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/PageProperties.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/PageProperties.java similarity index 97% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/PageProperties.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/PageProperties.java index 9aac5cbcc626c..05b0ecaf7aa9e 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/PageProperties.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/PageProperties.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; /** * RESERVED FOR INTERNAL USE. Represents properties for writing to a page blob. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/PageRange.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/PageRange.java similarity index 97% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/PageRange.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/PageRange.java index 742d1f1cb0296..dcc4fbf11152a 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/PageRange.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/PageRange.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; /** * Represents a range of pages in a page blob. diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/PageRangeHandler.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/PageRangeHandler.java new file mode 100644 index 0000000000000..c24b19ef763ce --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/PageRangeHandler.java @@ -0,0 +1,100 @@ +/** + * 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 java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Stack; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; + +/** + * RESERVED FOR INTERNAL USE. A class used to deserialize a list of page ranges. + */ +final class PageRangeHandler extends DefaultHandler { + + private final Stack elementStack = new Stack(); + private StringBuilder bld = new StringBuilder(); + + private final ArrayList pages = new ArrayList(); + + private long startOffset; + private long endOffset; + + /** + * Returns an ArrayList of Page Ranges for the given stream. + * + * @return an ArrayList of Page Ranges for the given stream. + * @throws SAXException + * @throws ParserConfigurationException + * @throws IOException + */ + protected static ArrayList getPageRanges(InputStream streamRef) throws ParserConfigurationException, + SAXException, IOException { + SAXParser saxParser = Utility.getSAXParser(); + PageRangeHandler handler = new PageRangeHandler(); + saxParser.parse(streamRef, handler); + + return handler.pages; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + this.elementStack.push(localName); + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + String currentNode = this.elementStack.pop(); + + // if the node popped from the stack and the localName don't match, the xml document is improperly formatted + if (!localName.equals(currentNode)) { + throw new SAXException(SR.INVALID_RESPONSE_RECEIVED); + } + + String value = this.bld.toString(); + if (value.isEmpty()) { + value = null; + } + + if (BlobConstants.PAGE_RANGE_ELEMENT.equals(currentNode)) { + final PageRange pageRef = new PageRange(this.startOffset, this.endOffset); + this.pages.add(pageRef); + } + else if (BlobConstants.START_ELEMENT.equals(currentNode)) { + this.startOffset = Long.parseLong(value); + } + else if (Constants.END_ELEMENT.equals(currentNode)) { + this.endOffset = Long.parseLong(value); + } + + this.bld = new StringBuilder(); + } + + @Override + public void characters(char ch[], int start, int length) throws SAXException { + this.bld.append(ch, start, length); + } +} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/SharedAccessBlobHeaders.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/SharedAccessBlobHeaders.java similarity index 97% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/SharedAccessBlobHeaders.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/SharedAccessBlobHeaders.java index 2a1cc59911672..264f36143c54c 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/SharedAccessBlobHeaders.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/SharedAccessBlobHeaders.java @@ -12,9 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.core.Utility; /** * Represents the optional headers that can be returned with blobs accessed using SAS. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/SharedAccessBlobPermissions.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/SharedAccessBlobPermissions.java similarity index 97% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/SharedAccessBlobPermissions.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/SharedAccessBlobPermissions.java index b8ed38f3a6bc9..da8747195480e 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/SharedAccessBlobPermissions.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/SharedAccessBlobPermissions.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import java.util.EnumSet; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/SharedAccessBlobPolicy.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/SharedAccessBlobPolicy.java similarity index 62% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/SharedAccessBlobPolicy.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/blob/SharedAccessBlobPolicy.java index a2207a891fb05..10d2b305ce988 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/SharedAccessBlobPolicy.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/SharedAccessBlobPolicy.java @@ -12,106 +12,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.blob; +package com.microsoft.azure.storage.blob; import java.util.EnumSet; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.core.SharedAccessPolicy; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.SharedAccessPolicy; /** * Represents a shared access policy, which specifies the start time, expiry time, and permissions for a shared access * signature. */ public final class SharedAccessBlobPolicy extends SharedAccessPolicy { - - /** - * Assigns shared access permissions using the specified permissions string. - * - * @param value - * A String that represents the shared access permissions. The string must contain one or - * more of the following values. Note they must be lowercase, and the order that they are specified must - * be in the order of "rwdl". - *

    - *
  • d: Delete access.
  • - *
  • l: List access.
  • - *
  • r: Read access.
  • - *
  • w: Write access.
  • - *
- * - * @return A java.util.EnumSet object that contains {@link SharedAccessBlobPermissions} values that - * represents the set of shared access permissions. - * - * @deprecated As of release 0.6.0, replaced by the instance method - * {@link SharedAccessBlobPolicy#setPermissionsFromString(String)}. - */ - @Deprecated - public static EnumSet permissionsFromString(final String value) { - final char[] chars = value.toCharArray(); - final EnumSet retSet = EnumSet.noneOf(SharedAccessBlobPermissions.class); - - for (final char c : chars) { - switch (c) { - case 'r': - retSet.add(SharedAccessBlobPermissions.READ); - break; - case 'w': - retSet.add(SharedAccessBlobPermissions.WRITE); - break; - case 'd': - retSet.add(SharedAccessBlobPermissions.DELETE); - break; - case 'l': - retSet.add(SharedAccessBlobPermissions.LIST); - break; - default: - throw new IllegalArgumentException("value"); - } - } - - return retSet; - } - - /** - * Converts the permissions specified for the shared access policy to a string. - * - * @param permissions - * A {@link SharedAccessBlobPermissions} object that represents the shared access permissions. - * - * @return A String that represents the shared access permissions in the "rwdl" format, which is - * described at {@link SharedAccessBlobPolicy#permissionsFromString(String)}. - * - * @deprecated As of release 0.6.0, replaced by the instance method - * {@link SharedAccessBlobPolicy#permissionsToString()}. - */ - @Deprecated - public static String permissionsToString(final EnumSet permissions) { - if (permissions == null) { - return Constants.EMPTY_STRING; - } - - // The service supports a fixed order => rwdl - final StringBuilder builder = new StringBuilder(); - - if (permissions.contains(SharedAccessBlobPermissions.READ)) { - builder.append("r"); - } - - if (permissions.contains(SharedAccessBlobPermissions.WRITE)) { - builder.append("w"); - } - - if (permissions.contains(SharedAccessBlobPermissions.DELETE)) { - builder.append("d"); - } - - if (permissions.contains(SharedAccessBlobPermissions.LIST)) { - builder.append("l"); - } - - return builder.toString(); - } - /** * The permissions for a shared access signature associated with this shared access policy. */ @@ -146,7 +58,30 @@ public void setPermissions(final EnumSet permission */ @Override public String permissionsToString() { - return SharedAccessBlobPolicy.permissionsToString(this.permissions); + if (this.permissions == null) { + return Constants.EMPTY_STRING; + } + + // The service supports a fixed order => rwdl + final StringBuilder builder = new StringBuilder(); + + if (this.permissions.contains(SharedAccessBlobPermissions.READ)) { + builder.append("r"); + } + + if (this.permissions.contains(SharedAccessBlobPermissions.WRITE)) { + builder.append("w"); + } + + if (this.permissions.contains(SharedAccessBlobPermissions.DELETE)) { + builder.append("d"); + } + + if (this.permissions.contains(SharedAccessBlobPermissions.LIST)) { + builder.append("l"); + } + + return builder.toString(); } /** @@ -165,6 +100,28 @@ public String permissionsToString() { */ @Override public void setPermissionsFromString(final String value) { - this.permissions = SharedAccessBlobPolicy.permissionsFromString(value); + final char[] chars = value.toCharArray(); + final EnumSet retSet = EnumSet.noneOf(SharedAccessBlobPermissions.class); + + for (final char c : chars) { + switch (c) { + case 'r': + retSet.add(SharedAccessBlobPermissions.READ); + break; + case 'w': + retSet.add(SharedAccessBlobPermissions.WRITE); + break; + case 'd': + retSet.add(SharedAccessBlobPermissions.DELETE); + break; + case 'l': + retSet.add(SharedAccessBlobPermissions.LIST); + break; + default: + throw new IllegalArgumentException("value"); + } + } + + this.permissions = retSet; } } diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/package.html b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/package.html new file mode 100644 index 0000000000000..7de3dd802e4db --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/package.html @@ -0,0 +1,5 @@ + + +This package contains the storage service blob classes. + + diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/Base64.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/Base64.java similarity index 99% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/Base64.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/Base64.java index dbd5683b21608..33957346bfddf 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/Base64.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/Base64.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; /** * RESERVED FOR INTERNAL USE. Provides Base64 encoding, decoding, and validation functionality. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/BaseRequest.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/BaseRequest.java similarity index 85% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/BaseRequest.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/BaseRequest.java index b7ac7e2196a33..7499424ce5c4a 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/BaseRequest.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/BaseRequest.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; import java.io.IOException; import java.net.HttpURLConnection; @@ -23,11 +23,12 @@ import java.util.HashMap; import java.util.Map.Entry; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.Credentials; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.StorageKey; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.Credentials; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.RequestOptions; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.StorageKey; /** * RESERVED FOR INTERNAL USE. The Base Request class for the protocol layer. @@ -90,9 +91,14 @@ public static void addMetadata(final HttpURLConnection request, final HashMap 0) { - modifiedSinceString = Utility.getGMTTime(new Date(conn.getIfModifiedSince())); - } - - appendCanonicalizedElement(canonicalizedString, modifiedSinceString); + appendCanonicalizedElement(canonicalizedString, + Utility.getStandardHeaderValue(conn, Constants.HeaderConstants.IF_MODIFIED_SINCE)); appendCanonicalizedElement(canonicalizedString, Utility.getStandardHeaderValue(conn, Constants.HeaderConstants.IF_MATCH)); appendCanonicalizedElement(canonicalizedString, @@ -445,5 +440,6 @@ private static ArrayList getHeaderValues(final Map> * the length of the content written to the outputstream in bytes, -1 if unknown * @return a canonicalized string. */ - protected abstract String canonicalize(HttpURLConnection conn, String accountName, Long contentLength) throws StorageException; + protected abstract String canonicalize(HttpURLConnection conn, String accountName, Long contentLength) + throws StorageException; } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/CanonicalizerFactory.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/CanonicalizerFactory.java similarity index 98% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/CanonicalizerFactory.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/CanonicalizerFactory.java index 905b1135ef42b..b5ebc068ed9a0 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/CanonicalizerFactory.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/CanonicalizerFactory.java @@ -15,7 +15,7 @@ /** * */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; import java.net.HttpURLConnection; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/ExecutionEngine.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/ExecutionEngine.java similarity index 81% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/ExecutionEngine.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/ExecutionEngine.java index bf2cb86155598..f55b860e5bf66 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/ExecutionEngine.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/ExecutionEngine.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; import java.io.IOException; import java.io.InputStream; @@ -28,23 +28,23 @@ import javax.xml.stream.XMLStreamException; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.LocationMode; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.RequestCompletedEvent; -import com.microsoft.windowsazure.storage.RequestResult; -import com.microsoft.windowsazure.storage.ResponseReceivedEvent; -import com.microsoft.windowsazure.storage.RetryContext; -import com.microsoft.windowsazure.storage.RetryInfo; -import com.microsoft.windowsazure.storage.RetryNoRetry; -import com.microsoft.windowsazure.storage.RetryPolicy; -import com.microsoft.windowsazure.storage.RetryPolicyFactory; -import com.microsoft.windowsazure.storage.RetryingEvent; -import com.microsoft.windowsazure.storage.SendingRequestEvent; -import com.microsoft.windowsazure.storage.StorageErrorCodeStrings; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.StorageLocation; -import com.microsoft.windowsazure.storage.table.TableServiceException; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.LocationMode; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.RequestCompletedEvent; +import com.microsoft.azure.storage.RequestResult; +import com.microsoft.azure.storage.ResponseReceivedEvent; +import com.microsoft.azure.storage.RetryContext; +import com.microsoft.azure.storage.RetryInfo; +import com.microsoft.azure.storage.RetryNoRetry; +import com.microsoft.azure.storage.RetryPolicy; +import com.microsoft.azure.storage.RetryPolicyFactory; +import com.microsoft.azure.storage.RetryingEvent; +import com.microsoft.azure.storage.SendingRequestEvent; +import com.microsoft.azure.storage.StorageErrorCodeStrings; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.StorageLocation; +import com.microsoft.azure.storage.table.TableServiceException; /** * RESERVED FOR INTERNAL USE. A class that handles execution of StorageOperations and enforces retry policies. @@ -73,7 +73,6 @@ public final class ExecutionEngine { * @throws StorageException * an exception representing any error which occurred during the operation. */ - @SuppressWarnings("deprecation") public static RESULT_TYPE executeWithRetry(final CLIENT_TYPE client, final PARENT_TYPE parentObject, final StorageRequest task, final RetryPolicyFactory policyFactory, final OperationContext opContext) throws StorageException { @@ -99,59 +98,8 @@ public static RESULT_TYPE executeWithRet while (true) { try { - // reset result flags - task.initialize(opContext); - - if (Utility.validateMaxExecutionTimeout(task.getRequestOptions().getOperationExpiryTimeInMs())) { - // maximum execution time would be exceeded by current time - TimeoutException timeoutException = new TimeoutException(SR.MAXIMUM_EXCUTION_TIMEOUT_EXCEPTION); - translatedException = new StorageException(StorageErrorCodeStrings.OPERATION_TIMED_OUT, - SR.MAXIMUM_EXCUTION_TIMEOUT_EXCEPTION, Constants.HeaderConstants.HTTP_UNUSED_306, null, - timeoutException); - throw translatedException; - } - - // Run the recovery action if this is a retry. Else, initialize the location mode for the task. - // For retries, it will be initialized in retry logic. - if (currentRetryCount > 0) { - task.recoveryAction(opContext); - Logger.info(opContext, LogConstants.RETRY); - } - else { - task.applyLocationModeToRequest(); - task.initializeLocation(); - Logger.info(opContext, LogConstants.STARTING); - } - - task.setRequestLocationMode(); - - // If the command only allows for a specific location, we should target - // that location no matter what the retry policy says. - task.validateLocation(); - - Logger.info(opContext, LogConstants.INIT_LOCATION, task.getCurrentLocation(), task.getLocationMode()); - - // 1. Build the request - request = task.buildRequest(client, parentObject, opContext); - task.setConnection(request); - opContext.setCurrentRequestObject(request); - - // 2. Add headers - task.setHeaders(request, parentObject, opContext); - - // Add any other custom headers that users have set on the opContext - if (opContext.getUserHeaders() != null) { - for (final Entry entry : opContext.getUserHeaders().entrySet()) { - request.setRequestProperty(entry.getKey(), entry.getValue()); - } - } - - // 3. Fire sending request event - ExecutionEngine.fireSendingRequestEvent(opContext, request, task.getResult()); - task.setIsSent(true); - - // 4. Sign the request - task.signRequest(request, client, opContext); + // 1-4: setup the request + request = setupStorageRequest(client, parentObject, task, currentRetryCount, opContext); Logger.info(opContext, LogConstants.START_REQUEST, request.getURL(), request.getRequestProperty(Constants.HeaderConstants.DATE)); @@ -254,7 +202,7 @@ public static RESULT_TYPE executeWithRet // Non Retryable if the inner exception is actually an TimeoutException, otherwise Retryable if (e.getCause() instanceof TimeoutException) { translatedException = new StorageException(StorageErrorCodeStrings.OPERATION_TIMED_OUT, - SR.MAXIMUM_EXCUTION_TIMEOUT_EXCEPTION, Constants.HeaderConstants.HTTP_UNUSED_306, null, + SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, Constants.HeaderConstants.HTTP_UNUSED_306, null, (Exception) e.getCause()); task.getResult().setException(translatedException); Logger.error(opContext, LogConstants.UNRETRYABLE_EXCEPTION, e.getCause().getClass().getName(), e @@ -357,9 +305,9 @@ public static RESULT_TYPE executeWithRet else if (Utility.validateMaxExecutionTimeout(task.getRequestOptions().getOperationExpiryTimeInMs(), retryInfo.getRetryInterval())) { // maximum execution time would be exceeded by current time plus retry interval delay - TimeoutException timeoutException = new TimeoutException(SR.MAXIMUM_EXCUTION_TIMEOUT_EXCEPTION); + TimeoutException timeoutException = new TimeoutException(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION); translatedException = new StorageException(StorageErrorCodeStrings.OPERATION_TIMED_OUT, - SR.MAXIMUM_EXCUTION_TIMEOUT_EXCEPTION, Constants.HeaderConstants.HTTP_UNUSED_306, null, + SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, Constants.HeaderConstants.HTTP_UNUSED_306, null, timeoutException); task.initialize(opContext); @@ -390,6 +338,76 @@ else if (Utility.validateMaxExecutionTimeout(task.getRequestOptions().getOperati } } + private static HttpURLConnection setupStorageRequest( + final CLIENT_TYPE client, final PARENT_TYPE parentObject, + final StorageRequest task, int currentRetryCount, + final OperationContext opContext) throws StorageException { + try { + + // reset result flags + task.initialize(opContext); + + if (Utility.validateMaxExecutionTimeout(task.getRequestOptions().getOperationExpiryTimeInMs())) { + // maximum execution time would be exceeded by current time + TimeoutException timeoutException = new TimeoutException(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION); + throw new StorageException(StorageErrorCodeStrings.OPERATION_TIMED_OUT, + SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, Constants.HeaderConstants.HTTP_UNUSED_306, null, + timeoutException); + } + + // Run the recovery action if this is a retry. Else, initialize the location mode for the task. + // For retries, it will be initialized in retry logic. + if (currentRetryCount > 0) { + task.recoveryAction(opContext); + Logger.info(opContext, LogConstants.RETRY); + } + else { + task.applyLocationModeToRequest(); + task.initializeLocation(); + Logger.info(opContext, LogConstants.STARTING); + } + + task.setRequestLocationMode(); + + // If the command only allows for a specific location, we should target + // that location no matter what the retry policy says. + task.validateLocation(); + + Logger.info(opContext, LogConstants.INIT_LOCATION, task.getCurrentLocation(), task.getLocationMode()); + + // 1. Build the request + HttpURLConnection request = task.buildRequest(client, parentObject, opContext); + + // 2. Add headers + task.setHeaders(request, parentObject, opContext); + + // Add any other custom headers that users have set on the opContext + if (opContext.getUserHeaders() != null) { + for (final Entry entry : opContext.getUserHeaders().entrySet()) { + request.setRequestProperty(entry.getKey(), entry.getValue()); + } + } + + // 3. Fire sending request event + ExecutionEngine.fireSendingRequestEvent(opContext, request, task.getResult()); + task.setIsSent(true); + + // 4. Sign the request + task.signRequest(request, client, opContext); + + // set the connection on the task + task.setConnection(request); + + return request; + } + catch (StorageException e) { + throw e; + } + catch (Exception e) { + throw new StorageException(null, e.getMessage(), Constants.HeaderConstants.HTTP_UNUSED_306, null, e); + } + } + private static StorageLocation getNextLocation(StorageLocation lastLocation, LocationMode locationMode) { switch (locationMode) { case PRIMARY_ONLY: diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/LazySegmentedIterable.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/LazySegmentedIterable.java similarity index 92% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/LazySegmentedIterable.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/LazySegmentedIterable.java index abfc5efef02e5..b948e08c95144 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/LazySegmentedIterable.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/LazySegmentedIterable.java @@ -12,13 +12,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; import java.util.Iterator; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.ResultSegment; -import com.microsoft.windowsazure.storage.RetryPolicyFactory; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.ResultSegment; +import com.microsoft.azure.storage.RetryPolicyFactory; /** * RESERVED FOR INTERNAL USE. Provides a lazy iterator which will retrieve the next segment of a result as the iterator diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/LazySegmentedIterator.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/LazySegmentedIterator.java similarity index 93% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/LazySegmentedIterator.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/LazySegmentedIterator.java index 2998407cfd397..98bdacf405dfb 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/LazySegmentedIterator.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/LazySegmentedIterator.java @@ -12,16 +12,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; import java.util.Iterator; import java.util.NoSuchElementException; -import com.microsoft.windowsazure.storage.DoesServiceRequest; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.ResultSegment; -import com.microsoft.windowsazure.storage.RetryPolicyFactory; -import com.microsoft.windowsazure.storage.StorageException; +import com.microsoft.azure.storage.DoesServiceRequest; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.ResultSegment; +import com.microsoft.azure.storage.RetryPolicyFactory; +import com.microsoft.azure.storage.StorageException; /** * RESERVED FOR INTERNAL USE. Provides a lazy iterator which will retrieve the next segment of a result as the iterator diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/ListResponse.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/ListResponse.java similarity index 96% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/ListResponse.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/ListResponse.java index 8cfd4e3e42316..3310a2f606654 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/ListResponse.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/ListResponse.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; import java.util.ArrayList; @@ -25,6 +25,9 @@ * @param */ public class ListResponse { + + public static final String ENUMERATION_RESULTS = "EnumerationResults"; + /** * Holds the ArrayList of results. */ diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/ListingContext.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/ListingContext.java similarity index 97% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/ListingContext.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/ListingContext.java index afc30dbbaa4a0..ccf7e061c2c3d 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/ListingContext.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/ListingContext.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; /** * RESERVED FOR INTERNAL USE. A class which holds the current context of a listing diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/LogConstants.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/LogConstants.java similarity index 98% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/LogConstants.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/LogConstants.java index e3e09b09202dc..911ba92f14376 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/LogConstants.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/LogConstants.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; /** * RESERVED FOR INTERNAL USE. Provides a standard set of log messages that could be produced by the client library. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/Logger.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/Logger.java similarity index 99% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/Logger.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/Logger.java index acf3815e257a9..5307f18a7def6 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/Logger.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/Logger.java @@ -12,11 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; import org.slf4j.LoggerFactory; -import com.microsoft.windowsazure.storage.OperationContext; +import com.microsoft.azure.storage.OperationContext; /** * RESERVED FOR INTERNAL USE. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/NetworkInputStream.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/NetworkInputStream.java similarity index 97% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/NetworkInputStream.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/NetworkInputStream.java index ee0b0504374d4..8e107e5b80559 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/NetworkInputStream.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/NetworkInputStream.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; import java.io.IOException; import java.io.InputStream; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/PathUtility.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/PathUtility.java similarity index 98% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/PathUtility.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/PathUtility.java index 20d505a5571a7..65ba13286f9fd 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/PathUtility.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/PathUtility.java @@ -12,17 +12,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; import java.net.URI; import java.net.URISyntaxException; import java.util.HashMap; import java.util.Map.Entry; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.StorageCredentials; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.StorageUri; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.StorageCredentials; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.StorageUri; /** * RESERVED FOR INTERNAL USE. A class to help modify paths diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/RequestLocationMode.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/RequestLocationMode.java similarity index 93% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/RequestLocationMode.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/RequestLocationMode.java index b400bd0523bef..7778fa3c8614e 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/RequestLocationMode.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/RequestLocationMode.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; /** * RESERVED FOR INTERNAL USE. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/SR.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/SR.java similarity index 94% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/SR.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/SR.java index 6f207bd214f0b..b2414efca038f 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/SR.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/SR.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; /** * RESERVED FOR INTERNAL USE. Provides a standard set of errors that could be thrown from the client library. @@ -83,7 +83,9 @@ public class SR { public static final String KEY_NULL = "Key invalid. Cannot be null."; public static final String LEASE_CONDITION_ON_SOURCE = "A lease condition cannot be specified on the source of a copy."; public static final String MARK_EXPIRED = "Stream mark expired."; - public static final String MAXIMUM_EXCUTION_TIMEOUT_EXCEPTION = "The client could not finish the operation within specified maximum execution timeout."; + public static final String MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION = "The client could not finish the operation within specified maximum execution timeout."; + public static final String METADATA_KEY_INVALID = "The key for one of the metadata key-value pairs is null, empty, or whitespace."; + public static final String METADATA_VALUE_INVALID = "The value for one of the metadata key-value pairs is null, empty, or whitespace."; public static final String MISSING_CREDENTIALS = "No credentials provided."; public static final String MISSING_MANDATORY_DATE_HEADER = "Canonicalization did not find a non-empty x-ms-date header in the request. Please use a request with a valid x-ms-date header in RFC 123 format."; public static final String MISSING_MANDATORY_PARAMETER_FOR_SAS = "Missing mandatory parameters for valid Shared Access Signature."; @@ -114,7 +116,9 @@ public class SR { public static final String SECONDARY_ONLY_COMMAND = "This operation can only be executed against the secondary storage location."; public static final String SNAPSHOT_LISTING_ERROR = "Listing snapshots is only supported in flat mode (no delimiter). Consider setting useFlatBlobListing to true."; public static final String SNAPSHOT_QUERY_OPTION_ALREADY_DEFINED = "Snapshot query parameter is already defined in the blob URI. Either pass in a snapshotTime parameter or use a full URL with a snapshot query parameter."; - public static final String STORAGE_CREDENTIALS_NULL = "StorageCredentials cannot be null for the queue service."; + public static final String STORAGE_QUEUE_CREDENTIALS_NULL = "StorageCredentials cannot be null for the Queue service."; + public static final String STORAGE_TABLE_CREDENTIALS_NULL = "StorageCredentials cannot be null for the Table service."; + public static final String STORAGE_CLIENT_OR_SAS_REQUIRED = "Either a SAS token or a service client must be specified."; public static final String STORAGE_URI_MISSING_LOCATION = "The URI for the target storage location is not specified. Please consider changing the request's location mode."; public static final String STORAGE_URI_MUST_MATCH = "Primary and secondary location URIs in a StorageUri must point to the same resource."; public static final String STOREAS_DIFFERENT_FOR_GETTER_AND_SETTER = "StoreAs Annotation found for both getter and setter for property %s with unequal values."; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/SegmentedStorageOperation.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/SegmentedStorageOperation.java similarity index 92% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/SegmentedStorageOperation.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/SegmentedStorageOperation.java index d64b057b69fea..6b76f3679ab4e 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/SegmentedStorageOperation.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/SegmentedStorageOperation.java @@ -12,10 +12,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; -import com.microsoft.windowsazure.storage.RequestOptions; -import com.microsoft.windowsazure.storage.ResultContinuation; +import com.microsoft.azure.storage.RequestOptions; +import com.microsoft.azure.storage.ResultContinuation; /** * RESERVED FOR INTERNAL USE. A base class which encapsulate the execution of a given segmented storage operation. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/SegmentedStorageRequest.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/SegmentedStorageRequest.java similarity index 90% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/SegmentedStorageRequest.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/SegmentedStorageRequest.java index 565266e41f746..d67efd6883bd9 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/SegmentedStorageRequest.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/SegmentedStorageRequest.java @@ -13,9 +13,9 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; -import com.microsoft.windowsazure.storage.ResultContinuation; +import com.microsoft.azure.storage.ResultContinuation; public class SegmentedStorageRequest { diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/SharedAccessSignatureHelper.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/SharedAccessSignatureHelper.java similarity index 76% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/SharedAccessSignatureHelper.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/SharedAccessSignatureHelper.java index 6b9971d214afe..3114820463041 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/SharedAccessSignatureHelper.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/SharedAccessSignatureHelper.java @@ -12,22 +12,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; import java.security.InvalidKeyException; import java.util.Date; import java.util.HashMap; import java.util.Map.Entry; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.ServiceClient; -import com.microsoft.windowsazure.storage.StorageCredentialsSharedAccessSignature; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.blob.SharedAccessBlobHeaders; -import com.microsoft.windowsazure.storage.blob.SharedAccessBlobPolicy; -import com.microsoft.windowsazure.storage.queue.SharedAccessQueuePolicy; -import com.microsoft.windowsazure.storage.table.SharedAccessTablePolicy; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.ServiceClient; +import com.microsoft.azure.storage.SharedAccessPolicy; +import com.microsoft.azure.storage.StorageCredentialsSharedAccessSignature; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.blob.SharedAccessBlobHeaders; +import com.microsoft.azure.storage.blob.SharedAccessBlobPolicy; +import com.microsoft.azure.storage.queue.SharedAccessQueuePolicy; +import com.microsoft.azure.storage.table.SharedAccessTablePolicy; /** * RESERVED FOR INTERNAL USE. Contains helper methods for implementing shared access signatures. @@ -192,6 +193,11 @@ public static StorageCredentialsSharedAccessSignature parseQuery(final HashMapUriQueryBuilder if the value is not null or empty. + * + * @param builder + * The builder to add to. + * @param name + * The name to add. + * @param val + * The value to add if not null or empty. + * @throws StorageException + */ + private static void addIfNotNullOrEmpty(UriQueryBuilder builder, String name, String val) throws StorageException { + if (!Utility.isNullOrEmpty(val)) { + builder.add(name, val); + } + } + /** * Get the complete query builder for creating the Shared Access Signature query. * @@ -322,11 +337,11 @@ else if (lowerKey.equals(Constants.QueryConstants.CONTENT_DISPOSITION)) { * The start time for a shared access signature URI. * @param expiryTime * The expiry time for a shared access signature URI. - * @param startPatitionKey + * @param startPartitionKey * The start partition key for a shared access signature URI. * @param startRowKey * The start row key for a shared access signature URI. - * @param endPatitionKey + * @param endPartitionKey * The end partition key for a shared access signature URI. * @param endRowKey * The end row key for a shared access signature URI. @@ -346,7 +361,7 @@ else if (lowerKey.equals(Constants.QueryConstants.CONTENT_DISPOSITION)) { * @throws StorageException */ private static UriQueryBuilder generateSharedAccessSignatureHelper(final SharedAccessPolicy policy, - final String startPatitionKey, final String startRowKey, final String endPatitionKey, + final String startPartitionKey, final String startRowKey, final String endPartitionKey, final String endRowKey, final String accessPolicyIdentifier, final String resourceType, final String tableName, final String signature, final String accountKeyName, final SharedAccessBlobHeaders headers) throws StorageException { @@ -366,73 +381,34 @@ private static UriQueryBuilder generateSharedAccessSignatureHelper(final SharedA builder.add(Constants.QueryConstants.SIGNED_VERSION, Constants.HeaderConstants.TARGET_STORAGE_VERSION); - if (!Utility.isNullOrEmpty(permissions)) { - builder.add(Constants.QueryConstants.SIGNED_PERMISSIONS, permissions); - } + addIfNotNullOrEmpty(builder, Constants.QueryConstants.SIGNED_PERMISSIONS, permissions); final String startString = Utility.getUTCTimeOrEmpty(startTime); - if (!Utility.isNullOrEmpty(startString)) { - builder.add(Constants.QueryConstants.SIGNED_START, startString); - } + addIfNotNullOrEmpty(builder, Constants.QueryConstants.SIGNED_START, startString); final String stopString = Utility.getUTCTimeOrEmpty(expiryTime); - if (!Utility.isNullOrEmpty(stopString)) { - builder.add(Constants.QueryConstants.SIGNED_EXPIRY, stopString); - } - - if (!Utility.isNullOrEmpty(startPatitionKey)) { - builder.add(Constants.QueryConstants.START_PARTITION_KEY, startPatitionKey); - } - - if (!Utility.isNullOrEmpty(startRowKey)) { - builder.add(Constants.QueryConstants.START_ROW_KEY, startRowKey); - } + addIfNotNullOrEmpty(builder, Constants.QueryConstants.SIGNED_EXPIRY, stopString); - if (!Utility.isNullOrEmpty(endPatitionKey)) { - builder.add(Constants.QueryConstants.END_PARTITION_KEY, endPatitionKey); - } - - if (!Utility.isNullOrEmpty(endRowKey)) { - builder.add(Constants.QueryConstants.END_ROW_KEY, endRowKey); - } - - if (!Utility.isNullOrEmpty(accessPolicyIdentifier)) { - builder.add(Constants.QueryConstants.SIGNED_IDENTIFIER, accessPolicyIdentifier); - } + addIfNotNullOrEmpty(builder, Constants.QueryConstants.START_PARTITION_KEY, startPartitionKey); + addIfNotNullOrEmpty(builder, Constants.QueryConstants.START_ROW_KEY, startRowKey); + addIfNotNullOrEmpty(builder, Constants.QueryConstants.END_PARTITION_KEY, endPartitionKey); + addIfNotNullOrEmpty(builder, Constants.QueryConstants.END_ROW_KEY, endRowKey); - if (!Utility.isNullOrEmpty(resourceType)) { - builder.add(Constants.QueryConstants.SIGNED_RESOURCE, resourceType); - } + addIfNotNullOrEmpty(builder, Constants.QueryConstants.SIGNED_IDENTIFIER, accessPolicyIdentifier); + addIfNotNullOrEmpty(builder, Constants.QueryConstants.SIGNED_RESOURCE, resourceType); - if (!Utility.isNullOrEmpty(tableName)) { - builder.add(Constants.QueryConstants.SAS_TABLE_NAME, tableName); - } + addIfNotNullOrEmpty(builder, Constants.QueryConstants.SAS_TABLE_NAME, tableName); if (headers != null) { - if (!Utility.isNullOrEmpty(headers.getCacheControl())) { - builder.add(Constants.QueryConstants.CACHE_CONTROL, headers.getCacheControl()); - } - if (!Utility.isNullOrEmpty(headers.getContentType())) { - builder.add(Constants.QueryConstants.CONTENT_TYPE, headers.getContentType()); - } - if (!Utility.isNullOrEmpty(headers.getContentEncoding())) { - builder.add(Constants.QueryConstants.CONTENT_ENCODING, headers.getContentEncoding()); - } - if (!Utility.isNullOrEmpty(headers.getContentLanguage())) { - builder.add(Constants.QueryConstants.CONTENT_LANGUAGE, headers.getContentLanguage()); - } - if (!Utility.isNullOrEmpty(headers.getContentDisposition())) { - builder.add(Constants.QueryConstants.CONTENT_DISPOSITION, headers.getContentDisposition()); - } + addIfNotNullOrEmpty(builder, Constants.QueryConstants.CACHE_CONTROL, headers.getCacheControl()); + addIfNotNullOrEmpty(builder, Constants.QueryConstants.CONTENT_TYPE, headers.getContentType()); + addIfNotNullOrEmpty(builder, Constants.QueryConstants.CONTENT_ENCODING, headers.getContentEncoding()); + addIfNotNullOrEmpty(builder, Constants.QueryConstants.CONTENT_LANGUAGE, headers.getContentLanguage()); + addIfNotNullOrEmpty(builder, Constants.QueryConstants.CONTENT_DISPOSITION, headers.getContentDisposition()); } - if (!Utility.isNullOrEmpty(signature)) { - builder.add(Constants.QueryConstants.SIGNATURE, signature); - } - - if (!Utility.isNullOrEmpty(accountKeyName)) { - builder.add(Constants.QueryConstants.SIGNED_KEY, accountKeyName); - } + addIfNotNullOrEmpty(builder, Constants.QueryConstants.SIGNATURE, signature); + addIfNotNullOrEmpty(builder, Constants.QueryConstants.SIGNED_KEY, accountKeyName); return builder; } @@ -503,7 +479,8 @@ private static String generateSharedAccessSignatureHashForBlob(final SharedAcces contentType == null ? Constants.EMPTY_STRING : contentType); stringToSign = Utility.safeDecode(stringToSign); - final String signature = client.getCredentials().computeHmac256(stringToSign, opContext); + final String signature = StorageCredentialsHelper.computeHmac256(client.getCredentials(), stringToSign, + opContext); // add logging return signature; @@ -533,7 +510,7 @@ private static String generateSharedAccessSignatureHashForBlob(final SharedAcces */ private static String generateSharedAccessSignatureHashForQueueAndTable(final SharedAccessPolicy policy, final String resourceName, final String accessPolicyIdentifier, final boolean useTableSas, - final String startPatitionKey, final String startRowKey, final String endPatitionKey, + final String startPartitionKey, final String startRowKey, final String endPartitionKey, final String endRowKey, final ServiceClient client, final OperationContext opContext) throws InvalidKeyException, StorageException { Utility.assertNotNullOrEmpty("resourceName", resourceName); @@ -556,14 +533,15 @@ private static String generateSharedAccessSignatureHashForQueueAndTable(final Sh if (useTableSas) { stringToSign = String.format("%s\n%s\n%s\n%s\n%s", stringToSign, - startPatitionKey == null ? Constants.EMPTY_STRING : startPatitionKey, + startPartitionKey == null ? Constants.EMPTY_STRING : startPartitionKey, startRowKey == null ? Constants.EMPTY_STRING : startRowKey, - endPatitionKey == null ? Constants.EMPTY_STRING : endPatitionKey, + endPartitionKey == null ? Constants.EMPTY_STRING : endPartitionKey, endRowKey == null ? Constants.EMPTY_STRING : endRowKey); } stringToSign = Utility.safeDecode(stringToSign); - final String signature = client.getCredentials().computeHmac256(stringToSign, opContext); + final String signature = StorageCredentialsHelper.computeHmac256(client.getCredentials(), stringToSign, + opContext); // add logging return signature; diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/core/StorageCredentialsHelper.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/StorageCredentialsHelper.java new file mode 100644 index 0000000000000..2ec3ec30fe31e --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/StorageCredentialsHelper.java @@ -0,0 +1,287 @@ +/** + * 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.core; + +import java.security.InvalidKeyException; + +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.StorageCredentials; +import com.microsoft.azure.storage.StorageCredentialsAccountAndKey; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.StorageKey; + +/** + * RESERVED FOR INTERNAL USE. A helper method for StorageCredentials. + */ +public class StorageCredentialsHelper { + + // + // RESERVED, for internal use only. Gets a value indicating whether a + // request can be signed under the Shared Key authentication scheme using + // the specified credentials. + // + // @return True if a request can be signed with these + // credentials; otherwise, false + // + /** Reserved. */ + public static boolean canCredentialsSignRequest(final StorageCredentials creds) { + if (creds.getClass().equals(StorageCredentialsAccountAndKey.class)) { + return true; + } + else { + return false; + } + } + + // + // RESERVED, for internal use only. Gets a value indicating whether a + // request can be signed under the Shared Key Lite authentication scheme + // using the specified credentials. + // + // @return true if a request can be signed with these + // credentials; otherwise, false + // + /** Reserved. */ + public static boolean canCredentialsSignRequestLite(final StorageCredentials creds) { + if (creds.getClass().equals(StorageCredentialsAccountAndKey.class)) { + return true; + } + else { + return false; + } + } + + /** + * Computes a signature for the specified string using the HMAC-SHA256 algorithm. + * + * @param value + * The UTF-8-encoded string to sign. + * + * @return A String that contains the HMAC-SHA256-encoded signature. + * + * @throws InvalidKeyException + * If the key is not a valid Base64-encoded string. + */ + public static String computeHmac256(final StorageCredentials creds, final String value) throws InvalidKeyException { + return computeHmac256(creds, value, null); + } + + /** + * Computes a signature for the specified string using the HMAC-SHA256 algorithm with the specified operation + * context. + * + * @param value + * The UTF-8-encoded string to sign. + * @param opContext + * An {@link OperationContext} object that 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. + * + * @return A String that contains the HMAC-SHA256-encoded signature. + * + * @throws InvalidKeyException + * If the key is not a valid Base64-encoded string. + */ + public static String computeHmac256(final StorageCredentials creds, final String value, + final OperationContext opContext) throws InvalidKeyException { + if (creds.getClass().equals(StorageCredentialsAccountAndKey.class)) { + return StorageKey.computeMacSha256(((StorageCredentialsAccountAndKey) creds).getCredentials().getKey(), + value); + } + else { + return null; + } + } + + /** + * Signs a request under the Shared Key authentication scheme. + * + * @param request + * An HttpURLConnection object that represents the request to sign. + * @param contentLength + * The length of the content written to the output stream. If unknown, specify -1. + * + * @throws InvalidKeyException + * If the given key is invalid. + * @throws StorageException + * If a storage service error occurred. + */ + public static void signBlobAndQueueRequest(final StorageCredentials creds, + final java.net.HttpURLConnection request, final long contentLength) throws InvalidKeyException, + StorageException { + signBlobAndQueueRequest(creds, request, contentLength, null); + } + + /** + * Signs a request using the specified operation context under the Shared Key authentication scheme. + * + * @param request + * An HttpURLConnection object that represents the request to sign. + * @param contentLength + * The length of the content written to the output stream. If unknown, specify -1. + * @param opContext + * An {@link OperationContext} object that 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 InvalidKeyException + * If the given key is invalid. + * @throws StorageException + * If a storage service error occurred. + */ + public static void signBlobAndQueueRequest(final StorageCredentials creds, + final java.net.HttpURLConnection request, final long contentLength, OperationContext opContext) + throws InvalidKeyException, StorageException { + if (creds.getClass().equals(StorageCredentialsAccountAndKey.class)) { + opContext = opContext == null ? new OperationContext() : opContext; + BaseRequest.signRequestForBlobAndQueue(request, ((StorageCredentialsAccountAndKey) creds).getCredentials(), + contentLength, opContext); + } + } + + /** + * Signs a request using the Shared Key Lite authentication scheme. + * + * @param request + * An HttpURLConnection object that represents the request to sign. + * @param contentLength + * The length of the content written to the output stream. If unknown, specify -1. + * + * @throws InvalidKeyException + * If the given key is invalid. + * @throws StorageException + * If an unspecified storage exception occurs. + */ + public static void signBlobAndQueueRequestLite(final StorageCredentials creds, + final java.net.HttpURLConnection request, final long contentLength) throws InvalidKeyException, + StorageException { + signBlobAndQueueRequestLite(creds, request, contentLength, null); + } + + /** + * Signs a request using the specified operation context under the Shared Key Lite authentication scheme. + * + * @param request + * An HttpURLConnection object that represents the request to sign. + * @param contentLength + * The length of the content written to the output stream. If unknown, specify -1. + * @param opContext + * An {@link OperationContext} object that 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 InvalidKeyException + * If the given key is invalid. + * @throws StorageException + * If a storage service error occurred. + */ + public static void signBlobAndQueueRequestLite(final StorageCredentials creds, + final java.net.HttpURLConnection request, final long contentLength, OperationContext opContext) + throws StorageException, InvalidKeyException { + if (creds.getClass().equals(StorageCredentialsAccountAndKey.class)) { + opContext = opContext == null ? new OperationContext() : opContext; + BaseRequest.signRequestForBlobAndQueueSharedKeyLite(request, + ((StorageCredentialsAccountAndKey) creds).getCredentials(), contentLength, opContext); + } + } + + /** + * Signs a request under the Shared Key authentication scheme. + * + * @param request + * An HttpURLConnection object that represents the request to sign. + * @param contentLength + * The length of the content written to the output stream. If unknown, specify -1. + * + * @throws InvalidKeyException + * If the given key is invalid. + * @throws StorageException + * If a storage service error occurred. + */ + public static void signTableRequest(final StorageCredentials creds, final java.net.HttpURLConnection request, + final long contentLength) throws InvalidKeyException, StorageException { + signTableRequest(creds, request, contentLength, null); + } + + /** + * Signs a request using the specified operation context under the Shared Key authentication scheme. + * + * @param request + * An HttpURLConnection object that represents the request to sign. + * @param contentLength + * The length of the content written to the output stream. If unknown, specify -1. + * @param opContext + * An {@link OperationContext} object that 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 InvalidKeyException + * If the given key is invalid. + * @throws StorageException + * If a storage service error occurred. + */ + public static void signTableRequest(final StorageCredentials creds, final java.net.HttpURLConnection request, + final long contentLength, OperationContext opContext) throws InvalidKeyException, StorageException { + if (creds.getClass().equals(StorageCredentialsAccountAndKey.class)) { + opContext = opContext == null ? new OperationContext() : opContext; + BaseRequest.signRequestForTableSharedKey(request, + ((StorageCredentialsAccountAndKey) creds).getCredentials(), contentLength, opContext); + } + } + + /** + * Signs a request using the Shared Key Lite authentication scheme. + * + * @param request + * An HttpURLConnection object that represents the request to sign. + * @param contentLength + * The length of the content written to the output stream. If unknown, specify -1. + * + * @throws InvalidKeyException + * If the given key is invalid. + * @throws StorageException + * If an unspecified storage exception occurs. + */ + public static void signTableRequestLite(final StorageCredentials creds, final java.net.HttpURLConnection request, + final long contentLength) throws InvalidKeyException, StorageException { + signTableRequestLite(creds, request, contentLength, null); + } + + /** + * Signs a request using the specified operation context under the Shared Key Lite authentication scheme. + * + * @param request + * An HttpURLConnection object that represents the request to sign. + * @param contentLength + * The length of the content written to the output stream. If unknown, specify -1. + * @param opContext + * An {@link OperationContext} object that 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 InvalidKeyException + * If the given key is invalid. + * @throws StorageException + * If a storage service error occurred. + */ + public static void signTableRequestLite(final StorageCredentials creds, final java.net.HttpURLConnection request, + final long contentLength, OperationContext opContext) throws StorageException, InvalidKeyException { + if (creds.getClass().equals(StorageCredentialsAccountAndKey.class)) { + opContext = opContext == null ? new OperationContext() : opContext; + BaseRequest.signRequestForTableSharedKeyLite(request, + ((StorageCredentialsAccountAndKey) creds).getCredentials(), contentLength, opContext); + } + } +} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/StorageOperation.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/StorageOperation.java similarity index 79% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/StorageOperation.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/StorageOperation.java index 7cca0354b3c67..ebf2534e2e8c4 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/StorageOperation.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/StorageOperation.java @@ -12,17 +12,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; import java.net.HttpURLConnection; -import java.security.InvalidKeyException; -import com.microsoft.windowsazure.storage.AuthenticationScheme; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.RequestOptions; -import com.microsoft.windowsazure.storage.RequestResult; -import com.microsoft.windowsazure.storage.ServiceClient; -import com.microsoft.windowsazure.storage.StorageException; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.RequestOptions; +import com.microsoft.azure.storage.RequestResult; +import com.microsoft.azure.storage.StorageException; /** * RESERVED FOR INTERNAL USE. A base class which encapsulate the execution of a given storage operation. @@ -158,26 +155,6 @@ protected final StorageException materializeException(final HttpURLConnection re return StorageException.translateException(request, null, opContext); } - public final void signRequest(ServiceClient client, HttpURLConnection request, long contentLength, - OperationContext context) throws InvalidKeyException, StorageException { - if (client.getAuthenticationScheme() == AuthenticationScheme.SHAREDKEYFULL) { - client.getCredentials().signBlobAndQueueRequest(request, contentLength, context); - } - else { - client.getCredentials().signBlobAndQueueRequestLite(request, contentLength, context); - } - } - - public final void signTableRequest(ServiceClient client, HttpURLConnection request, long contentLength, - OperationContext context) throws InvalidKeyException, StorageException { - if (client.getAuthenticationScheme() == AuthenticationScheme.SHAREDKEYFULL) { - client.getCredentials().signTableRequest(request, contentLength, context); - } - else { - client.getCredentials().signTableRequestLite(request, contentLength, context); - } - } - /** * @param exceptionReference * the exception to set diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/StorageRequest.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/StorageRequest.java similarity index 94% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/StorageRequest.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/StorageRequest.java index 2ec9071bea59f..b1a0a4d92f8d4 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/StorageRequest.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/StorageRequest.java @@ -13,23 +13,23 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.security.InvalidKeyException; -import com.microsoft.windowsazure.storage.AccessCondition; -import com.microsoft.windowsazure.storage.AuthenticationScheme; -import com.microsoft.windowsazure.storage.LocationMode; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.RequestOptions; -import com.microsoft.windowsazure.storage.RequestResult; -import com.microsoft.windowsazure.storage.ServiceClient; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.StorageLocation; -import com.microsoft.windowsazure.storage.StorageUri; +import com.microsoft.azure.storage.AccessCondition; +import com.microsoft.azure.storage.AuthenticationScheme; +import com.microsoft.azure.storage.LocationMode; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.RequestOptions; +import com.microsoft.azure.storage.RequestResult; +import com.microsoft.azure.storage.ServiceClient; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.StorageLocation; +import com.microsoft.azure.storage.StorageUri; /** * RESERVED FOR INTERNAL USE. A class which encapsulate the execution of a given storage operation. @@ -309,20 +309,21 @@ protected final StorageException materializeException(final HttpURLConnection re public static final void signBlobAndQueueRequest(HttpURLConnection request, ServiceClient client, long contentLength, OperationContext context) throws InvalidKeyException, StorageException { if (client.getAuthenticationScheme() == AuthenticationScheme.SHAREDKEYFULL) { - client.getCredentials().signBlobAndQueueRequest(request, contentLength, context); + StorageCredentialsHelper.signBlobAndQueueRequest(client.getCredentials(), request, contentLength, context); } else { - client.getCredentials().signBlobAndQueueRequestLite(request, contentLength, context); + StorageCredentialsHelper.signBlobAndQueueRequestLite(client.getCredentials(), request, contentLength, + context); } } public static final void signTableRequest(HttpURLConnection request, ServiceClient client, long contentLength, OperationContext context) throws InvalidKeyException, StorageException { if (client.getAuthenticationScheme() == AuthenticationScheme.SHAREDKEYFULL) { - client.getCredentials().signTableRequest(request, contentLength, context); + StorageCredentialsHelper.signTableRequest(client.getCredentials(), request, contentLength, context); } else { - client.getCredentials().signTableRequestLite(request, contentLength, context); + StorageCredentialsHelper.signTableRequestLite(client.getCredentials(), request, contentLength, context); } } @@ -618,6 +619,7 @@ public R postProcessResponse(HttpURLConnection connection, P parentObject, C cli * * @throws StorageException */ + @SuppressWarnings("unused") public void validateStreamWrite(StreamMd5AndLength descriptor) throws StorageException { // no-op } @@ -627,6 +629,7 @@ public void validateStreamWrite(StreamMd5AndLength descriptor) throws StorageExc * * @throws IOException */ + @SuppressWarnings("unused") public void recoveryAction(OperationContext context) throws IOException { // no-op } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/StreamMd5AndLength.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/StreamMd5AndLength.java similarity index 98% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/StreamMd5AndLength.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/StreamMd5AndLength.java index 9e88c3ceee493..a4b99f6dcb9df 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/StreamMd5AndLength.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/StreamMd5AndLength.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; import java.security.MessageDigest; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/TableFullCanonicalizer.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/TableFullCanonicalizer.java similarity index 92% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/TableFullCanonicalizer.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/TableFullCanonicalizer.java index 75f8a02363721..1fc25ca2747b9 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/TableFullCanonicalizer.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/TableFullCanonicalizer.java @@ -12,13 +12,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; import java.net.HttpURLConnection; import java.security.InvalidParameterException; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.StorageException; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.StorageException; /** * RESERVED FOR INTERNAL USE. Provides an implementation of the Canonicalizer class for requests against Table diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/TableLiteCanonicalizer.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/TableLiteCanonicalizer.java similarity index 93% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/TableLiteCanonicalizer.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/TableLiteCanonicalizer.java index 093188de77ea6..221523d3d8560 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/TableLiteCanonicalizer.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/TableLiteCanonicalizer.java @@ -15,13 +15,13 @@ /** * */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; import java.net.HttpURLConnection; import java.security.InvalidParameterException; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.StorageException; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.StorageException; /** * RESERVED FOR INTERNAL USE. Provides an implementation of the Canonicalizer class for requests against Table Service diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/UriQueryBuilder.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/UriQueryBuilder.java similarity index 97% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/UriQueryBuilder.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/UriQueryBuilder.java index df0d69e4a2b96..97528715911ed 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/UriQueryBuilder.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/UriQueryBuilder.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; import java.net.URI; import java.net.URISyntaxException; @@ -20,7 +20,7 @@ import java.util.HashMap; import java.util.Map.Entry; -import com.microsoft.windowsazure.storage.StorageException; +import com.microsoft.azure.storage.StorageException; /** * RESERVED FOR INTERNAL USE. A helper class to help modify the query string of a URI diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/Utility.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/Utility.java similarity index 88% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/Utility.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/core/Utility.java index 2e48f52d0bab5..a031fb167df7f 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/Utility.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/Utility.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.core; import java.io.IOException; import java.io.InputStream; @@ -29,25 +29,34 @@ import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.Arrays; import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.TimeZone; import java.util.concurrent.TimeoutException; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.RequestOptions; -import com.microsoft.windowsazure.storage.ResultContinuation; -import com.microsoft.windowsazure.storage.ResultContinuationType; -import com.microsoft.windowsazure.storage.StorageCredentials; -import com.microsoft.windowsazure.storage.StorageCredentialsAccountAndKey; -import com.microsoft.windowsazure.storage.StorageCredentialsAnonymous; -import com.microsoft.windowsazure.storage.StorageCredentialsSharedAccessSignature; -import com.microsoft.windowsazure.storage.StorageErrorCode; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.blob.CloudBlob; -import com.microsoft.windowsazure.storage.blob.CloudBlobClient; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.xml.sax.SAXException; + +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.RequestOptions; +import com.microsoft.azure.storage.ResultContinuation; +import com.microsoft.azure.storage.ResultContinuationType; +import com.microsoft.azure.storage.StorageCredentials; +import com.microsoft.azure.storage.StorageCredentialsAccountAndKey; +import com.microsoft.azure.storage.StorageCredentialsAnonymous; +import com.microsoft.azure.storage.StorageCredentialsSharedAccessSignature; +import com.microsoft.azure.storage.StorageErrorCode; +import com.microsoft.azure.storage.StorageErrorCodeStrings; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.blob.CloudBlob; +import com.microsoft.azure.storage.blob.CloudBlobClient; /** * RESERVED FOR INTERNAL USE. A class which provides utility methods. @@ -88,6 +97,17 @@ public final class Utility { */ public static final String ISO8061_LONG_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'"; + /** + * List of ports used for path style addressing. + */ + private static final List pathStylePorts = Arrays.asList(10000, 10001, 10002, 10003, 10004, 10100, 10101, + 10102, 10103, 10104, 11000, 11001, 11002, 11003, 11004, 11100, 11101, 11102, 11103, 11104); + + /** + * A factory to create SAXParser instances. + */ + private final static SAXParserFactory factory = SAXParserFactory.newInstance(); + /** * * Determines the size of an input stream, and optionally calculates the MD5 hash for the stream. @@ -337,42 +357,95 @@ public static boolean validateMaxExecutionTimeout(Long operationExpiryTimeInMs, return false; } + /** + * Returns a value representing the remaining time before the operation expires. 0 represents an infinite timeout. + * + * @param operationExpiryTimeInMs + * the time the request expires + * @return the remaining time before the operation expires, or 0 to represent an infinite timeout + * @throws StorageException + * wraps a TimeoutException if there is no more time remaining + */ + public static int getRemainingTimeout(Long operationExpiryTimeInMs) throws StorageException { + if (operationExpiryTimeInMs != null) { + long remainingTime = operationExpiryTimeInMs - new Date().getTime(); + if (remainingTime > Integer.MAX_VALUE) { + return Integer.MAX_VALUE; + } + else if (remainingTime > 0) { + return (int) remainingTime; + } + else { + TimeoutException timeoutException = new TimeoutException(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION); + StorageException translatedException = new StorageException( + StorageErrorCodeStrings.OPERATION_TIMED_OUT, SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, + Constants.HeaderConstants.HTTP_UNUSED_306, null, timeoutException); + throw translatedException; + } + } + else { + // represents an infinite timeout + return 0; + } + } + /** * Returns a value that indicates whether a specified URI is a path-style URI. * * @param baseURI * A java.net.URI value that represents the URI being checked. - * @param knownAccountName - * A String that represents the known account name to examine with baseURI, or - * null to examine baseURI on its own for being a path-style URI. - * * @return true if the specified URI is path-style; otherwise, false. */ - public static boolean determinePathStyleFromUri(final URI baseURI, final String knownAccountName) { + public static boolean determinePathStyleFromUri(final URI baseURI) { String path = baseURI.getPath(); - - if (knownAccountName == null) { - if (Utility.isNullOrEmpty(path) || path.equals("/") || baseURI.getPort() == -1) { - return false; - } - - return true; - } - - if (!Utility.isNullOrEmpty(path) && path.startsWith("/")) { + if (path != null && path.startsWith("/")) { path = path.substring(1); } - if (Utility.isNullOrEmpty(path) || baseURI.getHost().startsWith(knownAccountName)) { + // if the path is null or empty, this is not path-style + if (Utility.isNullOrEmpty(path)) { return false; } - else if (!Utility.isNullOrEmpty(path) && path.startsWith(knownAccountName)) { - return true; - } + // if this contains a port or has a host which is not DNS, this is path-style + return pathStylePorts.contains(baseURI.getPort()) || !isHostDnsName(baseURI); + } + + /** + * Returns a boolean indicating whether the host of the specified URI is DNS. + * + * @param uri + * The URI whose host to evaluate. + * @return true if the host is DNS; otherwise, false. + */ + private static boolean isHostDnsName(URI uri) { + String host = uri.getHost(); + for (int i = 0; i < host.length(); i++) { + char hostChar = host.charAt(i); + if (!Character.isDigit(hostChar) && !(hostChar == '.')) { + return true; + } + } return false; } + /** + * Reads character data for the Etag element from an XML stream reader. + * + * @param xmlr + * An XMLStreamReader object that represents the source XML stream reader. + * + * @return A String that represents the character data for the Etag element. + */ + public static String formatETag(final String etag) { + if (etag.startsWith("\"") && etag.endsWith("\"")) { + return etag; + } + else { + return String.format("\"%s\"", etag); + } + } + /** * Returns an unexpected storage exception. * @@ -441,6 +514,19 @@ public static String getGMTTime(final Date inDate) { return rfc1123Format.format(inDate); } + /** + * Returns a namespace aware SAXParser. + * + * @return A SAXParser instance which is namespace aware + * + * @throws ParserConfigurationException + * @throws SAXException + */ + public static SAXParser getSAXParser() throws ParserConfigurationException, SAXException { + factory.setNamespaceAware(true); + return factory.newSAXParser(); + } + /** * Returns the standard header value from the specified connection request, or an empty string if no header value * has been specified for the request. @@ -507,6 +593,19 @@ public static boolean isNullOrEmpty(final String value) { return value == null || value.length() == 0; } + /** + * Returns a value that indicates whether the specified string is null, empty, or whitespace. + * + * @param value + * A String being examined for null, empty, or whitespace. + * + * @return true if the specified value is null, empty, or whitespace; otherwise, + * false + */ + public static boolean isNullOrEmptyOrWhitespace(final String value) { + return value == null || value.trim().length() == 0; + } + /** * Parses a connection string and returns its values as a hash map of key/value pairs. * @@ -928,7 +1027,7 @@ public static StreamMd5AndLength writeToOutputStream(final InputStream sourceStr // if maximum execution time would be exceeded if (Utility.validateMaxExecutionTimeout(options.getOperationExpiryTimeInMs())) { // throw an exception - TimeoutException timeoutException = new TimeoutException(SR.MAXIMUM_EXCUTION_TIMEOUT_EXCEPTION); + TimeoutException timeoutException = new TimeoutException(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION); throw Utility.initIOException(timeoutException); } diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/core/package.html b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/package.html new file mode 100644 index 0000000000000..23199b6bb99d5 --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/core/package.html @@ -0,0 +1,5 @@ + + +FOR INTERNAL USE ONLY. This package contains the storage service core classes. + + diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/package.html b/microsoft-azure-storage/src/com/microsoft/azure/storage/package.html new file mode 100644 index 0000000000000..f0d5dfecff63c --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/package.html @@ -0,0 +1,5 @@ + + +This package contains the storage service base classes. + + diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/CloudQueue.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/CloudQueue.java similarity index 92% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/CloudQueue.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/queue/CloudQueue.java index 4784e61c1fa0e..0b0e9fb472041 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/CloudQueue.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/CloudQueue.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.queue; +package com.microsoft.azure.storage.queue; import java.io.ByteArrayInputStream; import java.io.StringWriter; @@ -28,28 +28,29 @@ import javax.xml.stream.XMLStreamException; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.DoesServiceRequest; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageCredentialsSharedAccessSignature; -import com.microsoft.windowsazure.storage.StorageErrorCode; -import com.microsoft.windowsazure.storage.StorageErrorCodeStrings; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.StorageUri; -import com.microsoft.windowsazure.storage.core.BaseResponse; -import com.microsoft.windowsazure.storage.core.ExecutionEngine; -import com.microsoft.windowsazure.storage.core.PathUtility; -import com.microsoft.windowsazure.storage.core.RequestLocationMode; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.SharedAccessPolicyDeserializer; -import com.microsoft.windowsazure.storage.core.SharedAccessPolicySerializer; -import com.microsoft.windowsazure.storage.core.SharedAccessSignatureHelper; -import com.microsoft.windowsazure.storage.core.StorageRequest; -import com.microsoft.windowsazure.storage.core.UriQueryBuilder; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.DoesServiceRequest; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.SharedAccessPolicyHandler; +import com.microsoft.azure.storage.SharedAccessPolicySerializer; +import com.microsoft.azure.storage.StorageCredentialsSharedAccessSignature; +import com.microsoft.azure.storage.StorageErrorCode; +import com.microsoft.azure.storage.StorageErrorCodeStrings; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.StorageUri; +import com.microsoft.azure.storage.core.BaseResponse; +import com.microsoft.azure.storage.core.ExecutionEngine; +import com.microsoft.azure.storage.core.PathUtility; +import com.microsoft.azure.storage.core.RequestLocationMode; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.SharedAccessSignatureHelper; +import com.microsoft.azure.storage.core.StorageCredentialsHelper; +import com.microsoft.azure.storage.core.StorageRequest; +import com.microsoft.azure.storage.core.UriQueryBuilder; +import com.microsoft.azure.storage.core.Utility; /** - * This class represents a queue in the Windows Azure Queue service. + * This class represents a queue in the Microsoft Azure Queue service. */ public final class CloudQueue { @@ -106,6 +107,38 @@ private static CloudQueueMessage getFirstOrNull(final IterableCloudQueue class using the specified queue URI. The queue URI must + * include a SAS token. + * + * @param uri + * A java.net.URI object that represents the absolute URI of the queue. + * + * @throws StorageException + * If a storage service error occurred. + * @throws URISyntaxException + * If the resource URI is invalid. + */ + public CloudQueue(final URI uri) throws URISyntaxException, StorageException { + this(new StorageUri(uri, null)); + } + + /** + * Creates an instance of the CloudQueue class using the specified queue URI. The queue URI must + * include a SAS token. + * + * @param uri + * A StorageUri object that represents the absolute URI of the queue. + * + * @throws StorageException + * If a storage service error occurred. + * @throws URISyntaxException + * If the resource URI is invalid. + */ + public CloudQueue(final StorageUri uri) throws URISyntaxException, StorageException { + this(uri, null /* client */); + } + /** * Creates an instance of the CloudQueue class using the specified name and client. * @@ -121,7 +154,7 @@ private static CloudQueueMessage getFirstOrNull(final IterableNaming Queues and Metadata + * @see Naming Queues and Metadata */ public CloudQueue(final String queueName, final CloudQueueClient client) throws URISyntaxException, StorageException { @@ -174,8 +207,7 @@ public CloudQueue(final StorageUri uri, final CloudQueueClient client) throws UR this.storageUri = uri; - boolean usePathStyleUris = client == null ? Utility.determinePathStyleFromUri(this.storageUri.getPrimaryUri(), - null) : client.isUsePathStyleUris(); + boolean usePathStyleUris = client == null ? Utility.determinePathStyleFromUri(this.storageUri.getPrimaryUri()) : client.isUsePathStyleUris(); this.name = PathUtility.getQueueNameFromUri(uri.getPrimaryUri(), usePathStyleUris); this.queueServiceClient = client; @@ -185,7 +217,7 @@ public CloudQueue(final StorageUri uri, final CloudQueueClient client) throws UR } /** - * Adds a message to the back of the queue with the default options. + * Adds a message to the back of the queue. * * @param message * A {@link CloudQueueMessage} object that specifies the message to add. @@ -269,9 +301,8 @@ public HttpURLConnection buildRequest(CloudQueueClient client, CloudQueue queue, this.setSendStream(new ByteArrayInputStream(messageBytes)); this.setLength((long) messageBytes.length); return QueueRequest.putMessage( - queue.getMessageRequestAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), initialVisibilityDelayInSeconds, timeToLiveInSeconds, - context); + queue.getMessageRequestAddress(context).getUri(this.getCurrentLocation()), options, + context, initialVisibilityDelayInSeconds, timeToLiveInSeconds); } @Override @@ -302,7 +333,7 @@ public Void preProcessResponse(CloudQueue parentObject, CloudQueueClient client, } /** - * Clears all messages from the queue, using the default request options. + * Clears all messages from the queue. * * @throws StorageException * If a storage service error occurred during the operation. @@ -340,8 +371,7 @@ public void clear(QueueRequestOptions options, OperationContext opContext) throw options.getRetryPolicyFactory(), opContext); } - private StorageRequest clearImpl(final QueueRequestOptions options) - throws StorageException { + private StorageRequest clearImpl(final QueueRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @@ -349,8 +379,7 @@ private StorageRequest clearImpl(final Queue public HttpURLConnection buildRequest(CloudQueueClient client, CloudQueue queue, OperationContext context) throws Exception { return QueueRequest.clearMessages( - queue.getMessageRequestAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), context); + queue.getMessageRequestAddress(context).getUri(this.getCurrentLocation()), options, context); } @Override @@ -374,7 +403,7 @@ public Void preProcessResponse(CloudQueue parentObject, CloudQueueClient client, } /** - * Creates the queue in the storage service with default request options. + * Creates the queue. * * @throws StorageException * If a storage service error occurred during the operation. @@ -385,7 +414,7 @@ public void create() throws StorageException { } /** - * Creates the queue in the storage service using the specified request options and operation context. + * Creates the queue, using the specified request options and operation context. * * @param options * A {@link QueueRequestOptions} object that specifies any additional options for the request. Specifying @@ -412,8 +441,7 @@ public void create(QueueRequestOptions options, OperationContext opContext) thro options.getRetryPolicyFactory(), opContext); } - private StorageRequest createImpl(final QueueRequestOptions options) - throws StorageException { + private StorageRequest createImpl(final QueueRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @@ -421,7 +449,7 @@ private StorageRequest createImpl(final Queu public HttpURLConnection buildRequest(CloudQueueClient client, CloudQueue queue, OperationContext context) throws Exception { return QueueRequest.create(queue.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), context); + options, context); } @Override @@ -452,7 +480,7 @@ public Void preProcessResponse(CloudQueue parentObject, CloudQueueClient client, } /** - * Creates the queue in the storage service using default request options if it does not already exist. + * Creates the queue if it does not already exist. * * @return A value of true if the queue is created in the storage service, otherwise false * . @@ -466,8 +494,7 @@ public boolean createIfNotExists() throws StorageException { } /** - * Creates the queue in the storage service with the specified request options and operation context if it does not - * already exist. + * Creates the queue if it does not already exist, using the specified request options and operation context. * * @param options * A {@link QueueRequestOptions} object that specifies any additional options for the request. Specifying @@ -510,7 +537,7 @@ public boolean createIfNotExists(QueueRequestOptions options, OperationContext o } /** - * Deletes the queue from the storage service. + * Deletes the queue. * * @throws StorageException * If a storage service error occurred during the operation. @@ -521,7 +548,7 @@ public void delete() throws StorageException { } /** - * Deletes the queue from the storage service, using the specified request options and operation context. + * Deletes the queue, using the specified request options and operation context. * * @param options * A {@link QueueRequestOptions} object that specifies any additional options for the request. Specifying @@ -548,8 +575,7 @@ public void delete(QueueRequestOptions options, OperationContext opContext) thro options.getRetryPolicyFactory(), opContext); } - private StorageRequest deleteImpl(final QueueRequestOptions options) - throws StorageException { + private StorageRequest deleteImpl(final QueueRequestOptions options) { final StorageRequest deleteRequest = new StorageRequest( options, this.getStorageUri()) { @@ -557,7 +583,7 @@ private StorageRequest deleteImpl(final Queu public HttpURLConnection buildRequest(CloudQueueClient client, CloudQueue queue, OperationContext context) throws Exception { return QueueRequest.delete(queue.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), context); + options, context); } @Override @@ -581,7 +607,7 @@ public Void preProcessResponse(CloudQueue parentObject, CloudQueueClient client, } /** - * Deletes the queue from the storage service if it exists. + * Deletes the queue if it exists. * * @return A value of true if the queue existed in the storage service and has been deleted, otherwise * false. @@ -595,8 +621,7 @@ public boolean deleteIfExists() throws StorageException { } /** - * Deletes the queue from the storage service using the specified request options and operation context, if it - * exists. + * Deletes the queue if it exists, using the specified request options and operation context. * * @param options * A {@link QueueRequestOptions} object that specifies any additional options for the request. Specifying @@ -691,7 +716,7 @@ public void deleteMessage(final CloudQueueMessage message, QueueRequestOptions o } private StorageRequest deleteMessageImpl(final CloudQueueMessage message, - final QueueRequestOptions options) throws StorageException { + final QueueRequestOptions options) { final String messageId = message.getId(); final String messagePopReceipt = message.getPopReceipt(); @@ -703,7 +728,7 @@ public HttpURLConnection buildRequest(CloudQueueClient client, CloudQueue queue, throws Exception { return QueueRequest.deleteMessage( queue.getIndividualMessageAddress(messageId, context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), messagePopReceipt, context); + options, context, messagePopReceipt); } @Override @@ -766,8 +791,7 @@ public void downloadAttributes(QueueRequestOptions options, OperationContext opC options.getRetryPolicyFactory(), opContext); } - private StorageRequest downloadAttributesImpl(final QueueRequestOptions options) - throws StorageException { + private StorageRequest downloadAttributesImpl(final QueueRequestOptions options) { final StorageRequest getRequest = new StorageRequest( options, this.getStorageUri()) { @@ -780,8 +804,7 @@ public void setRequestLocationMode() { public HttpURLConnection buildRequest(CloudQueueClient client, CloudQueue queue, OperationContext context) throws Exception { return QueueRequest.downloadAttributes( - queue.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), context); + queue.getTransformedAddress(context).getUri(this.getCurrentLocation()), options, context); } @Override @@ -808,7 +831,7 @@ public Void preProcessResponse(CloudQueue queue, CloudQueueClient client, Operat } /** - * Returns a value that indicates whether the queue exists in the storage service. + * Returns a value that indicates whether the queue exists. * * @return true if the queue exists in the storage service, otherwise false. * @@ -821,8 +844,8 @@ public boolean exists() throws StorageException { } /** - * Returns a value that indicates whether the queue exists in the storage service, using the specified request - * options and operation context. + * Returns a value that indicates whether the queue existse, using the specified request options and operation + * context. * * @param options * A {@link QueueRequestOptions} object that specifies any additional options for the request. Specifying @@ -858,7 +881,7 @@ private boolean exists(final boolean primaryOnly, QueueRequestOptions options, O } private StorageRequest existsImpl(final boolean primaryOnly, - final QueueRequestOptions options) throws StorageException { + final QueueRequestOptions options) { final StorageRequest getRequest = new StorageRequest( options, this.getStorageUri()) { @@ -872,8 +895,7 @@ public void setRequestLocationMode() { public HttpURLConnection buildRequest(CloudQueueClient client, CloudQueue queue, OperationContext context) throws Exception { return QueueRequest.downloadAttributes( - queue.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), context); + queue.getTransformedAddress(context).getUri(this.getCurrentLocation()), options, context); } @Override @@ -1096,7 +1118,7 @@ public Iterable peekMessages(final int numberOfMessages, Queu } private StorageRequest> peekMessagesImpl( - final int numberOfMessages, final QueueRequestOptions options) throws StorageException { + final int numberOfMessages, final QueueRequestOptions options) { final StorageRequest> getRequest = new StorageRequest>( options, this.getStorageUri()) { @@ -1109,8 +1131,8 @@ public void setRequestLocationMode() { public HttpURLConnection buildRequest(CloudQueueClient client, CloudQueue queue, OperationContext context) throws Exception { return QueueRequest.peekMessages( - queue.getMessageRequestAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), numberOfMessages, context); + queue.getMessageRequestAddress(context).getUri(this.getCurrentLocation()), options, context, + numberOfMessages); } @Override @@ -1127,7 +1149,7 @@ public ArrayList preProcessResponse(CloudQueue queue, CloudQu return null; } else { - return QueueDeserializer.readMessages(this.getConnection().getInputStream(), + return QueueMessageHandler.readMessages(this.getConnection().getInputStream(), queue.shouldEncodeMessage); } } @@ -1245,8 +1267,7 @@ public Iterable retrieveMessages(final int numberOfMessages, } private StorageRequest> retrieveMessagesImpl( - final int numberOfMessages, final int visibilityTimeoutInSeconds, final QueueRequestOptions options) - throws StorageException { + final int numberOfMessages, final int visibilityTimeoutInSeconds, final QueueRequestOptions options) { final StorageRequest> getRequest = new StorageRequest>( options, this.getStorageUri()) { @@ -1254,8 +1275,8 @@ private StorageRequest preProcessResponse(CloudQueue queue, CloudQu return null; } else { - return QueueDeserializer.readMessages(this.getConnection().getInputStream(), + return QueueMessageHandler.readMessages(this.getConnection().getInputStream(), queue.shouldEncodeMessage); } } @@ -1399,7 +1420,7 @@ public HttpURLConnection buildRequest(CloudQueueClient client, CloudQueue queue, return QueueRequest.updateMessage( queue.getIndividualMessageAddress(message.getId(), context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), message.getPopReceipt(), visibilityTimeoutInSeconds, context); + options, context, message.getPopReceipt(), visibilityTimeoutInSeconds); } @Override @@ -1434,7 +1455,7 @@ public Void preProcessResponse(CloudQueue queue, CloudQueueClient client, Operat } /** - * Uploads the metadata in the CloudQueue object to the queue, using the default request options. + * Uploads the metadata in the CloudQueue object to the queue. * * @throws StorageException * If a storage service error occurred during the operation. @@ -1475,8 +1496,7 @@ public void uploadMetadata(QueueRequestOptions options, OperationContext opConte } - private StorageRequest uploadMetadataImpl(final QueueRequestOptions options) - throws StorageException { + private StorageRequest uploadMetadataImpl(final QueueRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @@ -1485,7 +1505,7 @@ private StorageRequest uploadMetadataImpl(fi public HttpURLConnection buildRequest(CloudQueueClient client, CloudQueue queue, OperationContext context) throws Exception { return QueueRequest.setMetadata(queue.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), context); + options, context); } @Override @@ -1579,7 +1599,7 @@ public HttpURLConnection buildRequest(CloudQueueClient client, CloudQueue queue, this.setSendStream(new ByteArrayInputStream(aclBytes)); this.setLength((long) aclBytes.length); return QueueRequest.setAcl(queue.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), context); + options, context); } @Override @@ -1664,7 +1684,7 @@ public QueuePermissions downloadPermissions(QueueRequestOptions options, Operati } private StorageRequest downloadPermissionsImpl( - final QueueRequestOptions options) throws StorageException { + final QueueRequestOptions options) { final StorageRequest getRequest = new StorageRequest( options, this.getStorageUri()) { @@ -1678,7 +1698,7 @@ public void setRequestLocationMode() { public HttpURLConnection buildRequest(CloudQueueClient client, CloudQueue queue, OperationContext context) throws Exception { return QueueRequest.getAcl(queue.getTransformedAddress(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), context); + options, context); } @Override @@ -1702,8 +1722,8 @@ public QueuePermissions preProcessResponse(CloudQueue parentObject, CloudQueueCl public QueuePermissions postProcessResponse(HttpURLConnection connection, CloudQueue queue, CloudQueueClient client, OperationContext context, QueuePermissions queuePermissions) throws Exception { - HashMap accessIds = SharedAccessPolicyDeserializer - .getAccessIdentifiers(this.getConnection().getInputStream(), SharedAccessQueuePolicy.class); + HashMap accessIds = SharedAccessPolicyHandler.getAccessIdentifiers( + this.getConnection().getInputStream(), SharedAccessQueuePolicy.class); for (final String key : accessIds.keySet()) { queuePermissions.getSharedAccessPolicies().put(key, accessIds.get(key)); @@ -1734,7 +1754,7 @@ public QueuePermissions postProcessResponse(HttpURLConnection connection, CloudQ public String generateSharedAccessSignature(final SharedAccessQueuePolicy policy, final String groupPolicyIdentifier) throws InvalidKeyException, StorageException { - if (!this.queueServiceClient.getCredentials().canCredentialsSignRequest()) { + if (!StorageCredentialsHelper.canCredentialsSignRequest(this.queueServiceClient.getCredentials())) { final String errorMessage = SR.CANNOT_CREATE_SAS_WITHOUT_ACCOUNT_KEY; throw new IllegalArgumentException(errorMessage); } @@ -1781,19 +1801,7 @@ private String getSharedAccessCanonicalName() { */ private final StorageUri getTransformedAddress(final OperationContext opContext) throws URISyntaxException, StorageException { - if (this.queueServiceClient.getCredentials().doCredentialsNeedTransformUri()) { - if (this.getStorageUri().isAbsolute()) { - return this.queueServiceClient.getCredentials().transformUri(this.getStorageUri(), opContext); - } - else { - final StorageException ex = Utility.generateNewUnexpectedStorageException(null); - ex.getExtendedErrorInformation().setErrorMessage("Queue Object relative URIs not supported."); - throw ex; - } - } - else { - return this.getStorageUri(); - } + return this.queueServiceClient.getCredentials().transformUri(this.getStorageUri(), opContext); } /** @@ -1828,6 +1836,9 @@ private void parseQueryAndVerify(final StorageUri completeUri, final CloudQueueC .parseQuery(queryParameters); if (sasCreds == null) { + if (existingClient == null) { + throw new IllegalArgumentException(SR.STORAGE_CLIENT_OR_SAS_REQUIRED); + } return; } @@ -1840,9 +1851,8 @@ private void parseQueryAndVerify(final StorageUri completeUri, final CloudQueueC } if (existingClient != null && !sameCredentials) { - this.queueServiceClient.setRetryPolicyFactory(existingClient.getRetryPolicyFactory()); - this.queueServiceClient.setTimeoutInMs(existingClient.getTimeoutInMs()); - this.queueServiceClient.setLocationMode(existingClient.getLocationMode()); + this.queueServiceClient.setDefaultRequestOptions(new QueueRequestOptions(existingClient + .getDefaultRequestOptions())); } } } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/CloudQueueClient.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/CloudQueueClient.java similarity index 74% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/CloudQueueClient.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/queue/CloudQueueClient.java index 058f12265cbc9..0cea554088fcd 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/CloudQueueClient.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/CloudQueueClient.java @@ -13,66 +13,79 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.queue; +package com.microsoft.azure.storage.queue; import java.net.HttpURLConnection; import java.net.URI; import java.net.URISyntaxException; -import com.microsoft.windowsazure.storage.DoesServiceRequest; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.ResultContinuation; -import com.microsoft.windowsazure.storage.ResultContinuationType; -import com.microsoft.windowsazure.storage.ResultSegment; -import com.microsoft.windowsazure.storage.ServiceClient; -import com.microsoft.windowsazure.storage.ServiceProperties; -import com.microsoft.windowsazure.storage.ServiceStats; -import com.microsoft.windowsazure.storage.StorageCredentials; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.StorageUri; -import com.microsoft.windowsazure.storage.core.ExecutionEngine; -import com.microsoft.windowsazure.storage.core.LazySegmentedIterable; -import com.microsoft.windowsazure.storage.core.ListResponse; -import com.microsoft.windowsazure.storage.core.ListingContext; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.SegmentedStorageRequest; -import com.microsoft.windowsazure.storage.core.StorageRequest; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.DoesServiceRequest; +import com.microsoft.azure.storage.LocationMode; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.ResultContinuation; +import com.microsoft.azure.storage.ResultContinuationType; +import com.microsoft.azure.storage.ResultSegment; +import com.microsoft.azure.storage.RetryExponentialRetry; +import com.microsoft.azure.storage.ServiceClient; +import com.microsoft.azure.storage.ServiceProperties; +import com.microsoft.azure.storage.ServiceStats; +import com.microsoft.azure.storage.StorageCredentials; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.StorageUri; +import com.microsoft.azure.storage.blob.BlobRequestOptions; +import com.microsoft.azure.storage.blob.CloudBlobClient; +import com.microsoft.azure.storage.core.ExecutionEngine; +import com.microsoft.azure.storage.core.LazySegmentedIterable; +import com.microsoft.azure.storage.core.ListResponse; +import com.microsoft.azure.storage.core.ListingContext; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.SegmentedStorageRequest; +import com.microsoft.azure.storage.core.StorageRequest; +import com.microsoft.azure.storage.core.Utility; /** - * Provides a service client for accessing the Windows Azure Queue service. + * Provides a service client for accessing the Microsoft Azure Queue service. */ public final class CloudQueueClient extends ServiceClient { /** - * Initializes a new instance of the CloudQueueClient class - * using the specified Queue service endpoint and account credentials. + * Holds the default request option values associated with this Service Client. + */ + private QueueRequestOptions defaultRequestOptions; + + /** + * Initializes a new instance of the CloudQueueClient class using the specified Queue service endpoint + * and account credentials. * * @param baseUri - * The Queue service endpoint to use to create the client + * A java.net.URI object that represents the Queue service endpoint used to create the + * client. * @param credentials - * The account credentials. + * A {@link StorageCredentials} object that represents the account credentials. */ public CloudQueueClient(final URI baseUri, final StorageCredentials credentials) { this(new StorageUri(baseUri, null), credentials); } /** - * Initializes a new instance of the CloudQueueClient class - * using the specified Queue service endpoint and account credentials. + * Initializes a new instance of the CloudQueueClient class using the specified Queue service endpoint + * and account credentials. * * @param baseUri - * The Queue service endpoint to use to create the client + * A {@link StorageUri} object that represents the Queue service endpoint used to create the + * client. * @param credentials - * The account credentials. + * A {@link StorageCredentials} object that represents the account credentials. */ public CloudQueueClient(final StorageUri baseUri, final StorageCredentials credentials) { super(baseUri, credentials); - this.setTimeoutInMs(QueueConstants.DEFAULT_QUEUE_CLIENT_TIMEOUT_IN_MS); - if (credentials == null) { - throw new IllegalArgumentException(SR.STORAGE_CREDENTIALS_NULL); + throw new IllegalArgumentException(SR.STORAGE_QUEUE_CREDENTIALS_NULL); } + + this.defaultRequestOptions = new QueueRequestOptions(); + this.defaultRequestOptions.setLocationMode(LocationMode.PRIMARY_ONLY); + this.defaultRequestOptions.setRetryPolicyFactory(new RetryExponentialRetry()); } /** @@ -88,7 +101,7 @@ public CloudQueueClient(final StorageUri baseUri, final StorageCredentials crede * If the resource URI constructed based on the queueName is invalid. * @throws StorageException * If a storage service error occurred. - * @see Naming Queues and Metadata + * @see Naming Queues and Metadata */ public CloudQueue getQueueReference(final String queueName) throws URISyntaxException, StorageException { return new CloudQueue(queueName, this); @@ -99,11 +112,9 @@ public CloudQueue getQueueReference(final String queueName) throws URISyntaxExce * * @return An iterable collection of {@link CloudQueue} objects retrieved lazily that * represent the queues in this client. - * @throws StorageException - * If a storage service error occurred during the operation. */ @DoesServiceRequest - public Iterable listQueues() throws StorageException { + public Iterable listQueues() { return this.listQueues(null, QueueListingDetails.NONE, null, null); } @@ -117,11 +128,9 @@ public Iterable listQueues() throws StorageException { * @return An iterable collection of {@link CloudQueue} objects retrieved lazily that * represent the queues in this client whose names begin with the * specified prefix. - * @throws StorageException - * If a storage service error occurred during the operation. */ @DoesServiceRequest - public Iterable listQueues(final String prefix) throws StorageException { + public Iterable listQueues(final String prefix) { return this.listQueues(prefix, QueueListingDetails.NONE, null, null); } @@ -148,12 +157,10 @@ public Iterable listQueues(final String prefix) throws StorageExcept * * @return An iterable collection of {@link CloudQueue} objects retrieved lazily that * represents the specified queues for this client. - * @throws StorageException - * If a storage service error occurred during the operation. */ @DoesServiceRequest public Iterable listQueues(final String prefix, final QueueListingDetails detailsIncluded, - QueueRequestOptions options, OperationContext opContext) throws StorageException { + QueueRequestOptions options, OperationContext opContext) { if (opContext == null) { opContext = new OperationContext(); } @@ -257,7 +264,7 @@ public ResultSegment listQueuesSegmented(final String prefix, private StorageRequest> listQueuesSegmentedImpl( final String prefix, final QueueListingDetails detailsIncluded, final int maxResults, - final QueueRequestOptions options, final SegmentedStorageRequest segmentedRequest) throws StorageException { + final QueueRequestOptions options, final SegmentedStorageRequest segmentedRequest) { Utility.assertContinuationType(segmentedRequest.getToken(), ResultContinuationType.QUEUE); final ListingContext listingContext = new ListingContext(prefix, maxResults); @@ -274,8 +281,8 @@ public HttpURLConnection buildRequest(CloudQueueClient client, Void parentObject throws Exception { listingContext.setMarker(segmentedRequest.getToken() != null ? segmentedRequest.getToken() .getNextMarker() : null); - return QueueRequest.list(client.getStorageUri().getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), listingContext, detailsIncluded, context); + return QueueRequest.list(client.getStorageUri().getUri(this.getCurrentLocation()), options, context, + listingContext, detailsIncluded); } @Override @@ -298,7 +305,7 @@ public ResultSegment preProcessResponse(Void parentObject, CloudQueu public ResultSegment postProcessResponse(HttpURLConnection connection, Void queue, CloudQueueClient client, OperationContext context, ResultSegment storageObject) throws Exception { - final ListResponse response = QueueDeserializer.getQueues(connection.getInputStream(), + final ListResponse response = QueueListHandler.getQueues(connection.getInputStream(), client); ResultContinuation newToken = null; @@ -323,10 +330,11 @@ public ResultSegment postProcessResponse(HttpURLConnection connectio } /** - * Queries the service to get the service statistics + * Queries the service for the {@link ServiceStats}. * - * @return ServiceStats for the given storage service + * @return {@link ServiceStats} for the given storage service * @throws StorageException + * If a storage service error occurred. */ @DoesServiceRequest public ServiceStats getServiceStats() throws StorageException { @@ -334,7 +342,7 @@ public ServiceStats getServiceStats() throws StorageException { } /** - * Queries the service to get the service statistics + * Queries the service for the {@link ServiceStats}. * * @param options * A {@link QueueRequestOptions} object that specifies any additional options for the request. Specifying @@ -344,8 +352,9 @@ public ServiceStats getServiceStats() throws StorageException { * An {@link OperationContext} object that 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. - * @return ServiceStats for the given storage service + * @return {@link ServiceStats} for the given storage service * @throws StorageException + * If a storage service error occurred. */ @DoesServiceRequest public ServiceStats getServiceStats(QueueRequestOptions options, OperationContext opContext) @@ -358,14 +367,14 @@ public ServiceStats getServiceStats(QueueRequestOptions options, OperationContex options = QueueRequestOptions.applyDefaults(options, this); return ExecutionEngine.executeWithRetry(this, null, this.getServiceStatsImpl(options, false), - this.getRetryPolicyFactory(), opContext); + options.getRetryPolicyFactory(), opContext); } /** - * Retrieves the current ServiceProperties for the given storage service. This includes Metrics and Logging - * Configurations. + * Retrieves the current {@link ServiceProperties} for the given storage service. This includes Logging, + * HourMetrics, MinuteMetrics and CORS configurations. * - * @return the ServiceProperties object representing the current configuration of the service. + * @return the {@link ServiceProperties} object representing the current configuration of the service. * @throws StorageException * If a storage service error occurred. */ @@ -375,8 +384,8 @@ public final ServiceProperties downloadServiceProperties() throws StorageExcepti } /** - * Retrieves the current ServiceProperties for the given storage service. This includes Metrics and Logging - * Configurations. + * Retrieves the current {@link ServiceProperties} for the given storage service. This includes Logging, + * HourMetrics, MinuteMetrics and CORS configurations. * * @param options * A {@link QueueRequestOptions} object that specifies any additional options for the request. Specifying @@ -386,7 +395,7 @@ public final ServiceProperties downloadServiceProperties() throws StorageExcepti * An {@link OperationContext} object that 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. - * @return the ServiceProperties object representing the current configuration of the service. + * @return the {@link ServiceProperties} object representing the current configuration of the service. * @throws StorageException * If a storage service error occurred. */ @@ -405,15 +414,13 @@ public final ServiceProperties downloadServiceProperties(QueueRequestOptions opt } /** - * Uploads a new configuration of service properties to the storage service, - * using the default request options. This includes Metrics and Logging - * Configuration. + * Uploads a new {@link ServiceProperties} configuration to the given storage service. This includes Logging, + * HourMetrics, MinuteMetrics and CORS configurations. * * @param properties * The {@link ServiceProperties} to upload. - * * @throws StorageException - * If a storage service error occurred during the operation. + * If a storage service error occurred. */ @DoesServiceRequest public void uploadServiceProperties(final ServiceProperties properties) throws StorageException { @@ -421,25 +428,21 @@ public void uploadServiceProperties(final ServiceProperties properties) throws S } /** - * Uploads a new configuration of service properties to the storage service, - * using the specified request options and operation context. This includes - * Metrics and Logging Configuration. + * Uploads a new {@link ServiceProperties} configuration to the given storage service. This includes Logging, + * HourMetrics, MinuteMetrics and CORS configurations. * * @param properties * The {@link ServiceProperties} to upload. * @param options - * A {@link QueueRequestOptions} object that specifies any additional - * options for the request. Specifying null will use - * the default request options from the associated service client - * ({@link CloudQueueClient}). + * 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 that 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. - * + * An {@link OperationContext} object that 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 during the operation. + * If a storage service error occurred. */ @DoesServiceRequest public void uploadServiceProperties(final ServiceProperties properties, QueueRequestOptions options, @@ -461,4 +464,35 @@ public void uploadServiceProperties(final ServiceProperties properties, QueueReq this.uploadServicePropertiesImpl(properties, options, opContext, false), options.getRetryPolicyFactory(), opContext); } + + /** + * @return the usePathStyleUris + */ + @Override + protected boolean isUsePathStyleUris() { + return super.isUsePathStyleUris(); + } + + /** + * Gets the {@link QueueRequestOptions} that is used for requests associated with this CloudQueueClient + * + * @return + * The {@link QueueRequestOptions} object containing the values used by this CloudQueueClient + */ + @Override + public QueueRequestOptions getDefaultRequestOptions() { + return this.defaultRequestOptions; + } + + /** + * Sets the {@link QueueRequestOptions} that is used for any queue accessed with this CloudQueueClient + * object. + * + * @param defaultRequestOptions + * The QueueRequestOptions to use. + */ + public void setDefaultRequestOptions(QueueRequestOptions defaultRequestOptions) { + Utility.assertNotNull("defaultRequestOptions", defaultRequestOptions); + this.defaultRequestOptions = defaultRequestOptions; + } } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/CloudQueueMessage.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/CloudQueueMessage.java similarity index 92% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/CloudQueueMessage.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/queue/CloudQueueMessage.java index 93b8eb5ccc6d6..73c19fe15fef0 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/CloudQueueMessage.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/CloudQueueMessage.java @@ -12,19 +12,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.queue; +package com.microsoft.azure.storage.queue; import java.io.UnsupportedEncodingException; import java.util.Date; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.core.Base64; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.core.Base64; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; /** - * Represents a message in the Windows Azure Queue service. + * Represents a message in the Microsoft Azure Queue service. */ public class CloudQueueMessage { @@ -77,8 +77,8 @@ protected CloudQueueMessage() { } /** - * Initializes a new instance of the CloudQueueMessage class with an array - * of byte containing the message. + * Initializes a new instance of the CloudQueueMessage class with an array of byte containing the + * message. * * @param content * The array of byte that contains the message. @@ -88,8 +88,7 @@ public CloudQueueMessage(final byte[] content) { } /** - * Initializes a new instance of the CloudQueueMessage class with a string - * containing the message. + * Initializes a new instance of the CloudQueueMessage class with a string containing the message. * * @param content * The String that contains the message. @@ -261,10 +260,9 @@ protected final void setDequeueCount(int dequeueCount) { * Sets the expiration time for the message. * * @param expirationTime - * The java.util.Date representing the expiration - * time to set on the message. + * The java.util.Date representing the expiration time to set on the message. */ - public final void setExpirationTime(final Date expirationTime) { + protected final void setExpirationTime(final Date expirationTime) { this.expirationTime = expirationTime; } @@ -329,7 +327,7 @@ protected final void setMessageType(final QueueMessageType messageType) { * The java.util.Date representing the time to set * for the message to be visible. */ - public final void setNextVisibleTime(final Date nextVisibleTime) { + protected final void setNextVisibleTime(final Date nextVisibleTime) { this.nextVisibleTime = nextVisibleTime; } @@ -339,7 +337,7 @@ public final void setNextVisibleTime(final Date nextVisibleTime) { * @param popReceipt * A String containing the message's pop receipt. */ - public final void setPopReceipt(final String popReceipt) { + protected final void setPopReceipt(final String popReceipt) { this.popReceipt = popReceipt; } } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/MessageUpdateFields.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/MessageUpdateFields.java similarity index 95% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/MessageUpdateFields.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/queue/MessageUpdateFields.java index 4f417860f89f0..d7d8ada427cbc 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/MessageUpdateFields.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/MessageUpdateFields.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.queue; +package com.microsoft.azure.storage.queue; /** * Flags for the values to set when updating messages. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueConstants.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueConstants.java similarity index 90% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueConstants.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueConstants.java index 890115b7eff01..86ab7ed43ce2a 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueConstants.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueConstants.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.queue; +package com.microsoft.azure.storage.queue; /** * RESERVED FOR INTERNAL USE. Holds the Constants used for the Queue Service. @@ -22,14 +22,9 @@ final class QueueConstants { /** * The header that specifies the approximate message count of a queue. */ - public static final String APPROXIMATE_MESSAGES_COUNT = com.microsoft.windowsazure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + public static final String APPROXIMATE_MESSAGES_COUNT = com.microsoft.azure.storage.Constants.PREFIX_FOR_STORAGE_HEADER + "approximate-messages-count"; - /** - * Default client side timeout, in milliseconds, for queue service. - */ - public static final int DEFAULT_QUEUE_CLIENT_TIMEOUT_IN_MS = 30 * 1000; - /** * Default visibility time out for the retrieve message operation. */ @@ -53,7 +48,7 @@ final class QueueConstants { /** * The maximum message size in bytes. */ - public static final long MAX_MESSAGE_SIZE = 64 * com.microsoft.windowsazure.storage.Constants.KB; + public static final long MAX_MESSAGE_SIZE = 64 * com.microsoft.azure.storage.Constants.KB; /** * The maximum number of messages that can be peeked or retrieved at a time. diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueListHandler.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueListHandler.java new file mode 100644 index 0000000000000..3bed02f389dd7 --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueListHandler.java @@ -0,0 +1,152 @@ +/** + * 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.queue; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.Stack; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.core.ListResponse; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; + +/** + * RESERVED FOR INTERNAL USE. A class used to deserialize a list of queues. + */ +final class QueueListHandler extends DefaultHandler { + + private final ListResponse response = new ListResponse(); + + private final Stack elementStack = new Stack(); + private StringBuilder bld = new StringBuilder(); + + private final CloudQueueClient serviceClient; + + private String queueName; + private HashMap metadata; + + private QueueListHandler(CloudQueueClient serviceClient) { + this.serviceClient = serviceClient; + } + + /** + * Parses the input stream containing the response body of the list queues request result and populates the class + * data. + * + * @param stream + * The InputStream object to deserialize from. + * @param serviceClient + * A {@link CloudQueueClient} object associated with the storage + * service. + * + * @throws IOException + * @throws SAXException + * @throws ParserConfigurationException + */ + public static ListResponse getQueues(final InputStream stream, final CloudQueueClient serviceClient) + throws SAXException, IOException, ParserConfigurationException { + SAXParser saxParser = Utility.getSAXParser(); + QueueListHandler handler = new QueueListHandler(serviceClient); + saxParser.parse(stream, handler); + + return handler.response; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + this.elementStack.push(localName); + + if (QueueConstants.QUEUE_ELEMENT.equals(localName)) { + this.queueName = Constants.EMPTY_STRING; + this.metadata = new HashMap(); + } + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + String currentNode = this.elementStack.pop(); + + // if the node popped from the stack and the localName don't match, the xml document is improperly formatted + if (!localName.equals(currentNode)) { + throw new SAXException(SR.INVALID_RESPONSE_RECEIVED); + } + + String parentNode = null; + if (!this.elementStack.isEmpty()) { + parentNode = this.elementStack.peek(); + } + + String value = this.bld.toString(); + if (value.isEmpty()) { + value = null; + } + + if (QueueConstants.QUEUE_ELEMENT.equals(currentNode)) { + CloudQueue queue; + try { + queue = this.serviceClient.getQueueReference(this.queueName); + queue.setMetadata(this.metadata); + + this.response.getResults().add(queue); + } + catch (URISyntaxException e) { + throw new SAXException(e); + } + catch (StorageException e) { + throw new SAXException(e); + } + } + else if (ListResponse.ENUMERATION_RESULTS.equals(parentNode)) { + if (Constants.PREFIX_ELEMENT.equals(currentNode)) { + this.response.setPrefix(value); + } + else if (Constants.MARKER_ELEMENT.equals(currentNode)) { + this.response.setMarker(value); + } + else if (Constants.NEXT_MARKER_ELEMENT.equals(currentNode)) { + this.response.setNextMarker(value); + } + else if (Constants.MAX_RESULTS_ELEMENT.equals(currentNode)) { + this.response.setMaxResults(Integer.parseInt(value)); + } + } + else if (Constants.METADATA_ELEMENT.equals(parentNode)) { + this.metadata.put(currentNode, value); + } + else if (QueueConstants.QUEUE_ELEMENT.equals(parentNode)) { + if (Constants.NAME_ELEMENT.equals(currentNode)) { + this.queueName = value; + } + } + + this.bld = new StringBuilder(); + } + + @Override + public void characters(char ch[], int start, int length) throws SAXException { + this.bld.append(ch, start, length); + } +} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueListingDetails.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueListingDetails.java similarity index 96% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueListingDetails.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueListingDetails.java index 143fa602ddf09..a430c5993b0f5 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueListingDetails.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueListingDetails.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.queue; +package com.microsoft.azure.storage.queue; /** * Specifies which details to include when listing the queues in this storage diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueMessageHandler.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueMessageHandler.java new file mode 100644 index 0000000000000..397c3e0f016f4 --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueMessageHandler.java @@ -0,0 +1,148 @@ +/** + * 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.queue; + +import java.io.IOException; +import java.io.InputStream; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Stack; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; + +/** + * RESERVED FOR INTERNAL USE. A class used to deserialize a list of queue messages. + */ +final class QueueMessageHandler extends DefaultHandler { + + private final Stack elementStack = new Stack(); + private StringBuilder bld = new StringBuilder(); + + private final ArrayList messages = new ArrayList(); + + private final boolean shouldEncodeMessage; + + private CloudQueueMessage message = new CloudQueueMessage(); + + private QueueMessageHandler(final boolean shouldEncodeMessage) { + this.shouldEncodeMessage = shouldEncodeMessage; + } + + /** + * Populates CloudQueueMessage objects from the XMLStreamReader; the reader must be at the Start element of + * QueuesElement. + * + * @param stream + * The InputStream object to deserialize from. + * @param shouldEncodeMessage + * A flag indicating whether messages should be base-64 encoded. + * + * @return An ArrayList of {@link CloudQueueMessage} from the + * stream. + * + * @throws IOException + * @throws SAXException + * @throws ParserConfigurationException + */ + public static ArrayList readMessages(final InputStream stream, final boolean shouldEncodeMessage) + throws SAXException, IOException, ParserConfigurationException { + SAXParser saxParser = Utility.getSAXParser(); + QueueMessageHandler handler = new QueueMessageHandler(shouldEncodeMessage); + saxParser.parse(stream, handler); + + return handler.messages; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + this.elementStack.push(localName); + + if (QueueConstants.QUEUE_MESSAGE_ELEMENT.equals(localName)) { + this.message = new CloudQueueMessage(); + this.message.setMessageType(this.shouldEncodeMessage ? QueueMessageType.BASE_64_ENCODED + : QueueMessageType.RAW_STRING); + } + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + String currentNode = this.elementStack.pop(); + + // if the node popped from the stack and the localName don't match, the xml document is improperly formatted + if (!localName.equals(currentNode)) { + throw new SAXException(SR.INVALID_RESPONSE_RECEIVED); + } + + String value = this.bld.toString(); + if (value.isEmpty()) { + value = null; + } + + if (QueueConstants.QUEUE_MESSAGE_ELEMENT.equals(localName)) { + this.messages.add(this.message); + } + else if (QueueConstants.MESSAGE_ID_ELEMENT.equals(currentNode)) { + this.message.setMessageId(value); + } + else if (QueueConstants.INSERTION_TIME_ELEMENT.equals(currentNode)) { + try { + this.message.setInsertionTime(Utility.parseRFC1123DateFromStringInGMT(value)); + } + catch (ParseException e) { + throw new SAXException(e); + } + } + else if (QueueConstants.EXPIRATION_TIME_ELEMENT.equals(currentNode)) { + try { + this.message.setExpirationTime(Utility.parseRFC1123DateFromStringInGMT(value)); + } + catch (ParseException e) { + throw new SAXException(e); + } + } + else if (QueueConstants.POP_RECEIPT_ELEMENT.equals(currentNode)) { + this.message.setPopReceipt(value); + } + else if (QueueConstants.TIME_NEXT_VISIBLE_ELEMENT.equals(currentNode)) { + try { + this.message.setNextVisibleTime(Utility.parseRFC1123DateFromStringInGMT(value)); + } + catch (ParseException e) { + throw new SAXException(e); + } + } + else if (QueueConstants.DEQUEUE_COUNT_ELEMENT.equals(currentNode)) { + this.message.setDequeueCount(Integer.parseInt(value)); + } + else if (QueueConstants.MESSAGE_TEXT_ELEMENT.equals(currentNode)) { + this.message.messageContent = value; + } + + this.bld = new StringBuilder(); + } + + @Override + public void characters(char ch[], int start, int length) throws SAXException { + this.bld.append(ch, start, length); + } +} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueMessageSerializer.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueMessageSerializer.java similarity index 93% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueMessageSerializer.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueMessageSerializer.java index 2c2f2dffe2f37..cb054ec92873a 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueMessageSerializer.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueMessageSerializer.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.queue; +package com.microsoft.azure.storage.queue; import java.io.StringWriter; import java.io.UnsupportedEncodingException; @@ -21,8 +21,8 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.core.Utility; /** * RESERVED FOR INTERNAL USE. A class used to serialize message requests to a byte array. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueMessageType.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueMessageType.java similarity index 94% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueMessageType.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueMessageType.java index 9e4d8a29c3cb9..6f8b2f6b8dd65 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueMessageType.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueMessageType.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.queue; +package com.microsoft.azure.storage.queue; /** * Reserved for internal use. Specifies queue message type. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueuePermissions.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueuePermissions.java similarity index 86% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueuePermissions.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueuePermissions.java index ac5222948ab1c..f57b02b9ae75e 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueuePermissions.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueuePermissions.java @@ -13,14 +13,13 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.queue; +package com.microsoft.azure.storage.queue; -import com.microsoft.windowsazure.storage.core.Permissions; +import com.microsoft.azure.storage.Permissions; /** * Represents the permissions for a container. */ - public final class QueuePermissions extends Permissions { } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueRequest.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueRequest.java similarity index 73% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueRequest.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueRequest.java index 6a1886ff3c6db..622c16845abfb 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueRequest.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueRequest.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.queue; +package com.microsoft.azure.storage.queue; import java.io.IOException; import java.net.HttpURLConnection; @@ -21,13 +21,13 @@ import java.net.URISyntaxException; import java.util.HashMap; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.core.BaseRequest; -import com.microsoft.windowsazure.storage.core.ListingContext; -import com.microsoft.windowsazure.storage.core.UriQueryBuilder; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.core.BaseRequest; +import com.microsoft.azure.storage.core.ListingContext; +import com.microsoft.azure.storage.core.UriQueryBuilder; +import com.microsoft.azure.storage.core.Utility; /** * RESERVED FOR INTERNAL USE. Provides a set of methods for constructing web @@ -35,6 +35,8 @@ */ final class QueueRequest { + private static final String METADATA = "metadata"; + private static final String POP_RECEIPT = "popreceipt"; private static final String PEEK_ONLY = "peekonly"; @@ -73,11 +75,10 @@ public static void addMetadata(final HttpURLConnection request, final HashMapURI object that specifies the absolute URI to * the queue. - * @param timeout - * The server response timeout interval in milliseconds. If the - * operation does not complete within the specified timeout - * interval, a timeout error is returned by the server. If the - * timeout value is 0, the maximum timeout of 30 seconds is used. + * @param queueOptions + * A {@link QueueRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudQueueClient}. * @param opContext * An {@link OperationContext} object that represents the context * for the current operation. This object is used to track @@ -93,10 +94,10 @@ public static void addMetadata(final HttpURLConnection request, final HashMapURI object that specifies the absolute URI to * the queue. - * @param timeout - * The server response timeout interval in milliseconds. If the - * operation does not complete within the specified timeout - * interval, a timeout error is returned by the server. If the - * timeout value is 0, the maximum timeout of 30 seconds is used. + * @param queueOptions + * A {@link QueueRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudQueueClient}. * @param opContext * An {@link OperationContext} object that represents the context * for the current operation. This object is used to track @@ -130,9 +130,9 @@ public static HttpURLConnection clearMessages(final URI uri, final int timeout, * @throws StorageException * If a storage service error occurred during the operation. */ - public static HttpURLConnection create(final URI uri, final int timeout, final OperationContext opContext) - throws IOException, URISyntaxException, StorageException { - return BaseRequest.create(uri, timeout, null, opContext); + public static HttpURLConnection create(final URI uri, final QueueRequestOptions queueOptions, + final OperationContext opContext) throws IOException, URISyntaxException, StorageException { + return BaseRequest.create(uri, queueOptions, null, opContext); } /** @@ -142,11 +142,10 @@ public static HttpURLConnection create(final URI uri, final int timeout, final O * @param uri * A URI object that specifies the absolute URI to * the queue. - * @param timeout - * The server response timeout interval in milliseconds. If the - * operation does not complete within the specified timeout - * interval, a timeout error is returned by the server. If the - * timeout value is 0, the maximum timeout of 30 seconds is used. + * @param queueOptions + * A {@link QueueRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudQueueClient}. * @param opContext * An {@link OperationContext} object that represents the context * for the current operation. This object is used to track @@ -162,9 +161,9 @@ public static HttpURLConnection create(final URI uri, final int timeout, final O * @throws StorageException * If a storage service error occurred during the operation. */ - public static HttpURLConnection delete(final URI uri, final int timeout, final OperationContext opContext) - throws IOException, URISyntaxException, StorageException { - return BaseRequest.delete(uri, timeout, null, opContext); + public static HttpURLConnection delete(final URI uri, final QueueRequestOptions queueOptions, + final OperationContext opContext) throws IOException, URISyntaxException, StorageException { + return BaseRequest.delete(uri, queueOptions, null, opContext); } /** @@ -174,21 +173,19 @@ public static HttpURLConnection delete(final URI uri, final int timeout, final O * @param uri * A URI object that specifies the absolute URI to * the queue. - * @param timeout - * The server response timeout interval in milliseconds. If the - * operation does not complete within the specified timeout - * interval, a timeout error is returned by the server. If the - * timeout value is 0, the maximum timeout of 30 seconds is used. - * @param popReceipt - * A String that contains the pop receipt value - * returned from an earlier call to {@link CloudQueueMessage#getPopReceipt} for the message to - * delete. + * @param queueOptions + * A {@link QueueRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudQueueClient}. * @param opContext * An {@link OperationContext} object that 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. - * + * @param popReceipt + * A String that contains the pop receipt value + * returned from an earlier call to {@link CloudQueueMessage#getPopReceipt} for the message to + * delete. * @return An HttpURLConnection configured for the specified * operation. * @@ -198,13 +195,14 @@ public static HttpURLConnection delete(final URI uri, final int timeout, final O * @throws StorageException * If a storage service error occurred during the operation. */ - public static HttpURLConnection deleteMessage(final URI uri, final int timeout, final String popReceipt, - final OperationContext opContext) throws URISyntaxException, IOException, StorageException { + public static HttpURLConnection deleteMessage(final URI uri, final QueueRequestOptions queueOptions, + final OperationContext opContext, final String popReceipt) throws URISyntaxException, IOException, + StorageException { final UriQueryBuilder builder = new UriQueryBuilder(); builder.add(POP_RECEIPT, popReceipt); - final HttpURLConnection request = BaseRequest.createURLConnection(uri, timeout, builder, opContext); + final HttpURLConnection request = BaseRequest.createURLConnection(uri, queueOptions, builder, opContext); request.setRequestMethod(Constants.HTTP_DELETE); @@ -219,11 +217,10 @@ public static HttpURLConnection deleteMessage(final URI uri, final int timeout, * @param uri * A URI object that specifies the absolute URI to * the queue. - * @param timeout - * The server response timeout interval in milliseconds. If the - * operation does not complete within the specified timeout - * interval, a timeout error is returned by the server. If the - * timeout value is 0, the maximum timeout of 30 seconds is used. + * @param queueOptions + * A {@link QueueRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudQueueClient}. * @param opContext * An {@link OperationContext} object that represents the context * for the current operation. This object is used to track @@ -239,9 +236,16 @@ public static HttpURLConnection deleteMessage(final URI uri, final int timeout, * @throws StorageException * If a storage service error occurred during the operation. */ - public static HttpURLConnection downloadAttributes(final URI uri, final int timeout, + public static HttpURLConnection downloadAttributes(final URI uri, final QueueRequestOptions queueOptions, final OperationContext opContext) throws IOException, URISyntaxException, StorageException { - return BaseRequest.getMetadata(uri, timeout, null, opContext); + UriQueryBuilder builder = new UriQueryBuilder(); + + builder.add(Constants.QueryConstants.COMPONENT, METADATA); + final HttpURLConnection retConnection = BaseRequest.createURLConnection(uri, queueOptions, builder, opContext); + + retConnection.setRequestMethod(Constants.HTTP_HEAD); + + return retConnection; } /** @@ -251,23 +255,21 @@ public static HttpURLConnection downloadAttributes(final URI uri, final int time * @param uri * A URI object that specifies the absolute URI to * the storage account. - * @param timeout - * The server response timeout interval in milliseconds. If the - * operation does not complete within the specified timeout - * interval, a timeout error is returned by the server. If the - * timeout value is 0, the maximum timeout of 30 seconds is used. + * @param queueOptions + * A {@link QueueRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudQueueClient}. + * @param opContext + * An {@link OperationContext} object that 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. * @param listingContext * A {@link ListingContext} object that specifies parameters for * the listing operation, if any. May be null. * @param detailsIncluded * A {@link QueueListingDetails} object that specifies additional * details to return with the listing, if any. May be null. - * @param opContext - * An {@link OperationContext} object that 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. - * * @return An HttpURLConnection configured for the specified * operation. * @@ -277,9 +279,9 @@ public static HttpURLConnection downloadAttributes(final URI uri, final int time * @throws StorageException * If a storage service error occurred during the operation. */ - public static HttpURLConnection list(final URI uri, final int timeout, final ListingContext listingContext, - final QueueListingDetails detailsIncluded, final OperationContext opContext) throws URISyntaxException, - IOException, StorageException { + public static HttpURLConnection list(final URI uri, final QueueRequestOptions queueOptions, + final OperationContext opContext, final ListingContext listingContext, + final QueueListingDetails detailsIncluded) throws URISyntaxException, IOException, StorageException { final UriQueryBuilder builder = new UriQueryBuilder(); builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.LIST); @@ -302,7 +304,7 @@ public static HttpURLConnection list(final URI uri, final int timeout, final Lis builder.add(Constants.QueryConstants.INCLUDE, Constants.QueryConstants.METADATA); } - final HttpURLConnection request = BaseRequest.createURLConnection(uri, timeout, builder, opContext); + final HttpURLConnection request = BaseRequest.createURLConnection(uri, queueOptions, builder, opContext); request.setRequestMethod(Constants.HTTP_GET); @@ -317,20 +319,18 @@ public static HttpURLConnection list(final URI uri, final int timeout, final Lis * @param uri * A URI object that specifies the absolute URI to * the queue. - * @param timeout - * The server response timeout interval in milliseconds. If the - * operation does not complete within the specified timeout - * interval, a timeout error is returned by the server. If the - * timeout value is 0, the maximum timeout of 30 seconds is used. - * @param numberOfMessages - * A nonzero value that specifies the number of messages to - * retrieve from the queue, up to a maximum of 32. + * @param queueOptions + * A {@link QueueRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudQueueClient}. * @param opContext * An {@link OperationContext} object that 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. - * + * @param numberOfMessages + * A nonzero value that specifies the number of messages to + * retrieve from the queue, up to a maximum of 32. * @return An HttpURLConnection configured for the specified * operation. * @@ -340,8 +340,9 @@ public static HttpURLConnection list(final URI uri, final int timeout, final Lis * @throws StorageException * If a storage service error occurred during the operation. */ - public static HttpURLConnection peekMessages(final URI uri, final int timeout, final int numberOfMessages, - final OperationContext opContext) throws URISyntaxException, IOException, StorageException { + public static HttpURLConnection peekMessages(final URI uri, final QueueRequestOptions queueOptions, + final OperationContext opContext, final int numberOfMessages) throws URISyntaxException, IOException, + StorageException { final UriQueryBuilder builder = new UriQueryBuilder(); builder.add(PEEK_ONLY, "true"); @@ -350,7 +351,7 @@ public static HttpURLConnection peekMessages(final URI uri, final int timeout, f builder.add(NUMBER_OF_MESSAGES, Integer.toString(numberOfMessages)); } - final HttpURLConnection request = BaseRequest.createURLConnection(uri, timeout, builder, opContext); + final HttpURLConnection request = BaseRequest.createURLConnection(uri, queueOptions, builder, opContext); request.setRequestMethod(Constants.HTTP_GET); @@ -365,11 +366,15 @@ public static HttpURLConnection peekMessages(final URI uri, final int timeout, f * @param uri * A URI object that specifies the absolute URI to * the queue. - * @param timeout - * The server response timeout interval in milliseconds. If the - * operation does not complete within the specified timeout - * interval, a timeout error is returned by the server. If the - * timeout value is 0, the maximum timeout of 30 seconds is used. + * @param queueOptions + * A {@link QueueRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudQueueClient}. + * @param opContext + * An {@link OperationContext} object that 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. * @param visibilityTimeoutInSeconds * Specifies the length of time for the message to be invisible * in seconds, starting when it is added to the queue. A value of @@ -381,12 +386,6 @@ public static HttpURLConnection peekMessages(final URI uri, final int timeout, f * Specifies the time-to-live interval for the message, in * seconds. The maximum time-to-live allowed is 7 days. If this * parameter is 0, the default time-to-live of 7 days is used. - * @param opContext - * An {@link OperationContext} object that 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. - * * @return An HttpURLConnection configured for the specified * operation. * @@ -396,9 +395,9 @@ public static HttpURLConnection peekMessages(final URI uri, final int timeout, f * @throws StorageException * If a storage service error occurred during the operation. */ - public static HttpURLConnection putMessage(final URI uri, final int timeout, final int visibilityTimeoutInSeconds, - final int timeToLiveInSeconds, final OperationContext opContext) throws IOException, URISyntaxException, - StorageException { + public static HttpURLConnection putMessage(final URI uri, final QueueRequestOptions queueOptions, + final OperationContext opContext, final int visibilityTimeoutInSeconds, final int timeToLiveInSeconds) + throws IOException, URISyntaxException, StorageException { final UriQueryBuilder builder = new UriQueryBuilder(); @@ -410,7 +409,7 @@ public static HttpURLConnection putMessage(final URI uri, final int timeout, fin builder.add(MESSAGE_TTL, Integer.toString(timeToLiveInSeconds)); } - final HttpURLConnection request = BaseRequest.createURLConnection(uri, timeout, builder, opContext); + final HttpURLConnection request = BaseRequest.createURLConnection(uri, queueOptions, builder, opContext); request.setDoOutput(true); request.setRequestMethod(Constants.HTTP_POST); @@ -425,11 +424,15 @@ public static HttpURLConnection putMessage(final URI uri, final int timeout, fin * @param uri * A URI object that specifies the absolute URI to * the queue. - * @param timeout - * The server response timeout interval in milliseconds. If the - * operation does not complete within the specified timeout - * interval, a timeout error is returned by the server. If the - * timeout value is 0, the maximum timeout of 30 seconds is used. + * @param queueOptions + * A {@link QueueRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudQueueClient}. + * @param opContext + * An {@link OperationContext} object that 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. * @param numberOfMessages * A nonzero value that specifies the number of messages to * retrieve from the queue, up to a maximum of 32. @@ -441,12 +444,6 @@ public static HttpURLConnection putMessage(final URI uri, final int timeout, fin * visibility timeout of a message can be set to a value later * than the expiry time, which will prevent the message from * being retrieved again whether it is processed or not. - * @param opContext - * An {@link OperationContext} object that 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. - * * @return An HttpURLConnection configured for the specified * operation. * @@ -456,9 +453,9 @@ public static HttpURLConnection putMessage(final URI uri, final int timeout, fin * @throws StorageException * If a storage service error occurred during the operation. */ - public static HttpURLConnection retrieveMessages(final URI uri, final int timeout, final int numberOfMessages, - final int visibilityTimeoutInSeconds, final OperationContext opContext) throws URISyntaxException, - IOException, StorageException { + public static HttpURLConnection retrieveMessages(final URI uri, final QueueRequestOptions queueOptions, + final OperationContext opContext, final int numberOfMessages, final int visibilityTimeoutInSeconds) + throws URISyntaxException, IOException, StorageException { final UriQueryBuilder builder = new UriQueryBuilder(); @@ -468,7 +465,7 @@ public static HttpURLConnection retrieveMessages(final URI uri, final int timeou builder.add(VISIBILITY_TIMEOUT, Integer.toString(visibilityTimeoutInSeconds)); - final HttpURLConnection request = BaseRequest.createURLConnection(uri, timeout, builder, opContext); + final HttpURLConnection request = BaseRequest.createURLConnection(uri, queueOptions, builder, opContext); request.setRequestMethod("GET"); @@ -485,11 +482,10 @@ public static HttpURLConnection retrieveMessages(final URI uri, final int timeou * @param uri * A URI object that specifies the absolute URI to * the queue. - * @param timeout - * The server response timeout interval in milliseconds. If the - * operation does not complete within the specified timeout - * interval, a timeout error is returned by the server. If the - * timeout value is 0, the maximum timeout of 30 seconds is used. + * @param queueOptions + * A {@link QueueRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudQueueClient}. * @param opContext * An {@link OperationContext} object that represents the context * for the current operation. This object is used to track @@ -505,9 +501,9 @@ public static HttpURLConnection retrieveMessages(final URI uri, final int timeou * @throws StorageException * If a storage service error occurred during the operation. */ - public static HttpURLConnection setMetadata(final URI uri, final int timeout, final OperationContext opContext) - throws IOException, URISyntaxException, StorageException { - return BaseRequest.setMetadata(uri, timeout, null, opContext); + public static HttpURLConnection setMetadata(final URI uri, final QueueRequestOptions queueOptions, + final OperationContext opContext) throws IOException, URISyntaxException, StorageException { + return BaseRequest.setMetadata(uri, queueOptions, null, opContext); } /** @@ -520,11 +516,15 @@ public static HttpURLConnection setMetadata(final URI uri, final int timeout, fi * @param uri * A URI object that specifies the absolute URI to * the queue. - * @param timeout - * The server response timeout interval in milliseconds. If the - * operation does not complete within the specified timeout - * interval, a timeout error is returned by the server. If the - * timeout value is 0, the maximum timeout of 30 seconds is used. + * @param queueOptions + * A {@link QueueRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudQueueClient}. + * @param opContext + * An {@link OperationContext} object that 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. * @param popReceipt * A String that contains the pop receipt value * returned from an earlier call to {@link CloudQueueMessage#getPopReceipt} for the message to @@ -538,12 +538,6 @@ public static HttpURLConnection setMetadata(final URI uri, final int timeout, fi * value later than the expiry time, which will prevent the * message from being retrieved again whether it is processed or * not. - * @param opContext - * An {@link OperationContext} object that 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. - * * @return An HttpURLConnection configured for the specified * operation. * @@ -553,9 +547,9 @@ public static HttpURLConnection setMetadata(final URI uri, final int timeout, fi * @throws StorageException * If a storage service error occurred during the operation. */ - public static HttpURLConnection updateMessage(final URI uri, final int timeout, final String popReceipt, - final int visibilityTimeoutInSeconds, final OperationContext opContext) throws URISyntaxException, - IOException, StorageException { + public static HttpURLConnection updateMessage(final URI uri, final QueueRequestOptions queueOptions, + final OperationContext opContext, final String popReceipt, final int visibilityTimeoutInSeconds) + throws URISyntaxException, IOException, StorageException { final UriQueryBuilder builder = new UriQueryBuilder(); @@ -563,7 +557,7 @@ public static HttpURLConnection updateMessage(final URI uri, final int timeout, builder.add(VISIBILITY_TIMEOUT, Integer.toString(visibilityTimeoutInSeconds)); - final HttpURLConnection request = BaseRequest.createURLConnection(uri, timeout, builder, opContext); + final HttpURLConnection request = BaseRequest.createURLConnection(uri, queueOptions, builder, opContext); request.setDoOutput(true); request.setRequestMethod(Constants.HTTP_PUT); @@ -572,23 +566,27 @@ public static HttpURLConnection updateMessage(final URI uri, final int timeout, } /** - * Sets the ACL for the queue. , Sign with length of aclBytes. + * Sets the ACL for the queue. Sign with length of aclBytes. * * @param uri * The absolute URI to the queue. - * @param timeout - * The server timeout interval. - * @param publicAccess - * The type of public access to allow for the queue. + * @param queueOptions + * A {@link QueueRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudQueueClient}. + * @param opContext + * An {@link OperationContext} object that 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. * @return a HttpURLConnection configured for the operation. * @throws StorageException * */ - public static HttpURLConnection setAcl(final URI uri, final int timeout, final OperationContext opContext) - throws IOException, URISyntaxException, StorageException { + public static HttpURLConnection setAcl(final URI uri, final QueueRequestOptions queueOptions, + final OperationContext opContext) throws IOException, URISyntaxException, StorageException { final UriQueryBuilder builder = new UriQueryBuilder(); builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.ACL); - final HttpURLConnection request = BaseRequest.createURLConnection(uri, timeout, builder, opContext); + final HttpURLConnection request = BaseRequest.createURLConnection(uri, queueOptions, builder, opContext); request.setDoOutput(true); request.setRequestMethod(Constants.HTTP_PUT); @@ -601,17 +599,23 @@ public static HttpURLConnection setAcl(final URI uri, final int timeout, final O * * @param uri * The absolute URI to the container. - * @param timeout - * The server timeout interval. + * @param queueOptions + * A {@link QueueRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudQueueClient}. + * @param opContext + * An {@link OperationContext} object that 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. * @return a HttpURLConnection configured for the operation. * @throws StorageException */ - public static HttpURLConnection getAcl(final URI uri, final int timeout, final OperationContext opContext) - throws IOException, URISyntaxException, StorageException { + public static HttpURLConnection getAcl(final URI uri, final QueueRequestOptions queueOptions, + final OperationContext opContext) throws IOException, URISyntaxException, StorageException { final UriQueryBuilder builder = new UriQueryBuilder(); builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.ACL); - final HttpURLConnection request = BaseRequest.createURLConnection(uri, timeout, builder, opContext); + final HttpURLConnection request = BaseRequest.createURLConnection(uri, queueOptions, builder, opContext); request.setRequestMethod(Constants.HTTP_GET); diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueRequestOptions.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueRequestOptions.java similarity index 85% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueRequestOptions.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueRequestOptions.java index c1b625f14817f..8abdcdab32384 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueRequestOptions.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueRequestOptions.java @@ -13,10 +13,10 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.queue; +package com.microsoft.azure.storage.queue; -import com.microsoft.windowsazure.storage.RequestOptions; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.RequestOptions; +import com.microsoft.azure.storage.core.Utility; /** * Represents a set of options that may be specified on a queue request. @@ -53,15 +53,14 @@ public QueueRequestOptions(final QueueRequestOptions other) { */ protected static final QueueRequestOptions applyDefaults(QueueRequestOptions options, final CloudQueueClient client) { QueueRequestOptions modifiedOptions = new QueueRequestOptions(options); + RequestOptions.populateRequestOptions(modifiedOptions, client.getDefaultRequestOptions(), false); return QueueRequestOptions.applyDefaultsInternal(modifiedOptions, client); } - protected static final QueueRequestOptions applyDefaultsInternal(QueueRequestOptions modifiedOptions, + private static final QueueRequestOptions applyDefaultsInternal(QueueRequestOptions modifiedOptions, CloudQueueClient client) { Utility.assertNotNull("modifiedOptions", modifiedOptions); - RequestOptions.applyBaseDefaultsInternal(modifiedOptions, client); - + RequestOptions.applyBaseDefaultsInternal(modifiedOptions); return modifiedOptions; } - } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueResponse.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueResponse.java similarity index 92% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueResponse.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueResponse.java index 679e095149f87..05993ef748831 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueResponse.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/QueueResponse.java @@ -13,11 +13,11 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.queue; +package com.microsoft.azure.storage.queue; import java.net.HttpURLConnection; -import com.microsoft.windowsazure.storage.core.BaseResponse; +import com.microsoft.azure.storage.core.BaseResponse; /** * RESERVED FOR INTERNAL USE. A class for parsing various responses from the queue service. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/SharedAccessQueuePermissions.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/SharedAccessQueuePermissions.java similarity index 98% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/SharedAccessQueuePermissions.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/queue/SharedAccessQueuePermissions.java index 5d33b5a9c060a..9204b99395f0d 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/SharedAccessQueuePermissions.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/SharedAccessQueuePermissions.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.queue; +package com.microsoft.azure.storage.queue; import java.util.EnumSet; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/SharedAccessQueuePolicy.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/SharedAccessQueuePolicy.java similarity index 61% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/SharedAccessQueuePolicy.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/queue/SharedAccessQueuePolicy.java index 211381d9ba9ce..908cfa1190f1c 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/SharedAccessQueuePolicy.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/SharedAccessQueuePolicy.java @@ -12,106 +12,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.queue; +package com.microsoft.azure.storage.queue; import java.util.EnumSet; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.core.SharedAccessPolicy; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.SharedAccessPolicy; /** * Represents a shared access policy, which specifies the start time, expiry time, and permissions for a shared access * signature. */ public final class SharedAccessQueuePolicy extends SharedAccessPolicy { - - /** - * Assigns shared access permissions using the specified permissions string. - * - * @param value - * A String that represents the shared access permissions. The string must contain one or - * more of the following values. Note that they must be lower case, and the order that they are specified - * must be in the order of "raup". - *
    - *
  • d: Read access.
  • - *
  • l: Add access.
  • - *
  • r: Update access.
  • - *
  • w: ProcessMessages access.
  • - *
- * - * @return A java.util.EnumSet object that contains {@link SharedAccessQueuePermissions} values that - * represents the set of shared access permissions. - * - * @deprecated As of release 0.6.0, replaced by the instance method - * {@link SharedAccessQueuePolicy#setPermissionsFromString(String)}. - */ - @Deprecated - public static EnumSet permissionsFromString(final String value) { - final char[] chars = value.toCharArray(); - final EnumSet retSet = EnumSet.noneOf(SharedAccessQueuePermissions.class); - - for (final char c : chars) { - switch (c) { - case 'r': - retSet.add(SharedAccessQueuePermissions.READ); - break; - case 'a': - retSet.add(SharedAccessQueuePermissions.ADD); - break; - case 'u': - retSet.add(SharedAccessQueuePermissions.UPDATE); - break; - case 'p': - retSet.add(SharedAccessQueuePermissions.PROCESSMESSAGES); - break; - default: - throw new IllegalArgumentException("value"); - } - } - - return retSet; - } - - /** - * Converts the permissions specified for the shared access policy to a string. - * - * @param permissions - * A {@link SharedAccessQueuePermissions} object that represents the shared access permissions. - * - * @return A String that represents the shared access permissions in the "raup" format, which is - * described at {@link SharedAccessQueuePolicy#permissionsFromString(String)}. - * - * @deprecated As of release 0.6.0, replaced by the instance method - * {@link SharedAccessQueuePolicy#permissionsToString()}. - */ - @Deprecated - public static String permissionsToString(final EnumSet permissions) { - if (permissions == null) { - return Constants.EMPTY_STRING; - } - - // The service supports a fixed order => rwdl - final StringBuilder builder = new StringBuilder(); - - if (permissions.contains(SharedAccessQueuePermissions.READ)) { - builder.append("r"); - } - - if (permissions.contains(SharedAccessQueuePermissions.ADD)) { - builder.append("a"); - } - - if (permissions.contains(SharedAccessQueuePermissions.UPDATE)) { - builder.append("u"); - } - - if (permissions.contains(SharedAccessQueuePermissions.PROCESSMESSAGES)) { - builder.append("p"); - } - - return builder.toString(); - } - /** * The permissions for a shared access signature associated with this shared access policy. */ @@ -146,7 +58,30 @@ public void setPermissions(final EnumSet permissio */ @Override public String permissionsToString() { - return SharedAccessQueuePolicy.permissionsToString(this.permissions); + if (this.permissions == null) { + return Constants.EMPTY_STRING; + } + + // The service supports a fixed order => raup + final StringBuilder builder = new StringBuilder(); + + if (this.permissions.contains(SharedAccessQueuePermissions.READ)) { + builder.append("r"); + } + + if (this.permissions.contains(SharedAccessQueuePermissions.ADD)) { + builder.append("a"); + } + + if (this.permissions.contains(SharedAccessQueuePermissions.UPDATE)) { + builder.append("u"); + } + + if (this.permissions.contains(SharedAccessQueuePermissions.PROCESSMESSAGES)) { + builder.append("p"); + } + + return builder.toString(); } /** @@ -165,6 +100,28 @@ public String permissionsToString() { */ @Override public void setPermissionsFromString(final String value) { - this.permissions = SharedAccessQueuePolicy.permissionsFromString(value); + final char[] chars = value.toCharArray(); + final EnumSet retSet = EnumSet.noneOf(SharedAccessQueuePermissions.class); + + for (final char c : chars) { + switch (c) { + case 'r': + retSet.add(SharedAccessQueuePermissions.READ); + break; + case 'a': + retSet.add(SharedAccessQueuePermissions.ADD); + break; + case 'u': + retSet.add(SharedAccessQueuePermissions.UPDATE); + break; + case 'p': + retSet.add(SharedAccessQueuePermissions.PROCESSMESSAGES); + break; + default: + throw new IllegalArgumentException("value"); + } + } + + this.permissions = retSet; } } diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/package.html b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/package.html new file mode 100644 index 0000000000000..69856c491d3ae --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/queue/package.html @@ -0,0 +1,5 @@ + + +This package contains the storage service queue classes. + + diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/CloudTable.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/CloudTable.java similarity index 87% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/CloudTable.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/CloudTable.java index d4ea5e3f4a34c..64381f677ddee 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/CloudTable.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/CloudTable.java @@ -12,10 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.io.ByteArrayInputStream; -import java.io.IOException; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; @@ -28,31 +27,32 @@ import javax.xml.stream.XMLStreamException; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.DoesServiceRequest; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.ResultContinuation; -import com.microsoft.windowsazure.storage.ResultSegment; -import com.microsoft.windowsazure.storage.StorageCredentials; -import com.microsoft.windowsazure.storage.StorageCredentialsAccountAndKey; -import com.microsoft.windowsazure.storage.StorageCredentialsSharedAccessSignature; -import com.microsoft.windowsazure.storage.StorageErrorCode; -import com.microsoft.windowsazure.storage.StorageErrorCodeStrings; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.StorageUri; -import com.microsoft.windowsazure.storage.core.ExecutionEngine; -import com.microsoft.windowsazure.storage.core.PathUtility; -import com.microsoft.windowsazure.storage.core.RequestLocationMode; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.SharedAccessPolicyDeserializer; -import com.microsoft.windowsazure.storage.core.SharedAccessPolicySerializer; -import com.microsoft.windowsazure.storage.core.SharedAccessSignatureHelper; -import com.microsoft.windowsazure.storage.core.StorageRequest; -import com.microsoft.windowsazure.storage.core.UriQueryBuilder; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.DoesServiceRequest; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.ResultContinuation; +import com.microsoft.azure.storage.ResultSegment; +import com.microsoft.azure.storage.SharedAccessPolicyHandler; +import com.microsoft.azure.storage.SharedAccessPolicySerializer; +import com.microsoft.azure.storage.StorageCredentials; +import com.microsoft.azure.storage.StorageCredentialsAccountAndKey; +import com.microsoft.azure.storage.StorageCredentialsSharedAccessSignature; +import com.microsoft.azure.storage.StorageErrorCode; +import com.microsoft.azure.storage.StorageErrorCodeStrings; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.StorageUri; +import com.microsoft.azure.storage.core.ExecutionEngine; +import com.microsoft.azure.storage.core.PathUtility; +import com.microsoft.azure.storage.core.RequestLocationMode; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.SharedAccessSignatureHelper; +import com.microsoft.azure.storage.core.StorageCredentialsHelper; +import com.microsoft.azure.storage.core.StorageRequest; +import com.microsoft.azure.storage.core.UriQueryBuilder; +import com.microsoft.azure.storage.core.Utility; /** - * Represents a table in the Windows Azure Table service. + * Represents a table in the Microsoft Azure Table service. */ public final class CloudTable { /** @@ -106,6 +106,38 @@ public URI getUri() { return this.storageUri.getPrimaryUri(); } + /** + * Creates an instance of the CloudTable class using the specified table URI. The table URI must + * include a SAS token. + * + * @param uri + * A java.net.URI object that represents the absolute URI of the table. + * + * @throws StorageException + * If a storage service error occurred. + * @throws URISyntaxException + * If the resource URI is invalid. + */ + public CloudTable(final URI uri) throws URISyntaxException, StorageException { + this(new StorageUri(uri, null)); + } + + /** + * Creates an instance of the CloudTable class using the specified table URI. The table URI must + * include a SAS token. + * + * @param uri + * A StorageUri object that represents the absolute URI of the table. + * + * @throws StorageException + * If a storage service error occurred. + * @throws URISyntaxException + * If the resource URI is invalid. + */ + public CloudTable(final StorageUri uri) throws URISyntaxException, StorageException { + this(uri, null /* client*/); + } + /** * Creates an instance of the CloudTable class using the specified name and client. * @@ -122,8 +154,8 @@ public URI getUri() { * If the resource URI constructed based on the tableName is invalid. * @throws StorageException * If a storage service error occurred. - * @see Understanding the Table Service - * Data Model + * @see Understanding the Table Service Data + * Model */ public CloudTable(final String tableName, final CloudTableClient client) throws URISyntaxException, StorageException { @@ -175,8 +207,7 @@ public CloudTable(final StorageUri uri, final CloudTableClient client) throws UR this.storageUri = uri; - boolean usePathStyleUris = client == null ? Utility.determinePathStyleFromUri(this.storageUri.getPrimaryUri(), - null) : client.isUsePathStyleUris(); + boolean usePathStyleUris = client == null ? Utility.determinePathStyleFromUri(this.storageUri.getPrimaryUri()) : client.isUsePathStyleUris(); this.name = PathUtility.getTableNameFromUri(uri.getPrimaryUri(), usePathStyleUris); this.tableServiceClient = client; @@ -187,9 +218,9 @@ public CloudTable(final StorageUri uri, final CloudTableClient client) throws UR /** * Creates the table in the storage service with default request options. *

- * This method invokes the Create - * Table REST API to create the specified table, using the Table service endpoint and storage account - * credentials of this instance. + * This method invokes the Create Table + * REST API to create the specified table, using the Table service endpoint and storage account credentials of this + * instance. * * @throws StorageException * If a storage service error occurred during the operation. @@ -203,9 +234,9 @@ public void create() throws StorageException { * Creates the table in the storage service, using the specified {@link TableRequestOptions} and * {@link OperationContext}. *

- * This method invokes the Create - * Table REST API to create the specified table, using the Table service endpoint and storage account - * credentials of this instance. + * This method invokes the Create Table + * REST API to create the specified table, using the Table service endpoint and storage account credentials of this + * instance. * * Use the {@link TableRequestOptions} to override execution options such as the timeout or retry policy for the * operation. @@ -222,7 +253,6 @@ public void create() throws StorageException { * If an error occurs accessing the storage service, or because the table cannot be * created, or already exists. */ - @SuppressWarnings("deprecation") @DoesServiceRequest public void create(TableRequestOptions options, OperationContext opContext) throws StorageException { if (opContext == null) { @@ -237,7 +267,7 @@ public void create(TableRequestOptions options, OperationContext opContext) thro final DynamicTableEntity tableEntry = new DynamicTableEntity(); tableEntry.getProperties().put(TableConstants.TABLE_NAME, new EntityProperty(this.name)); - this.tableServiceClient.execute(TableConstants.TABLES_SERVICE_TABLES_NAME, TableOperation.insert(tableEntry), + TableOperation.insert(tableEntry).execute(this.tableServiceClient, TableConstants.TABLES_SERVICE_TABLES_NAME, options, opContext); } @@ -324,7 +354,6 @@ public void delete() throws StorageException { * @throws StorageException * If a storage service error occurred during the operation. */ - @SuppressWarnings("deprecation") @DoesServiceRequest public void delete(TableRequestOptions options, OperationContext opContext) throws StorageException { if (opContext == null) { @@ -338,19 +367,8 @@ public void delete(TableRequestOptions options, OperationContext opContext) thro final DynamicTableEntity tableEntry = new DynamicTableEntity(); tableEntry.getProperties().put(TableConstants.TABLE_NAME, new EntityProperty(this.name)); - final TableOperation delOp = new TableOperation(tableEntry, TableOperationType.DELETE); - - final TableResult result = this.tableServiceClient.execute(TableConstants.TABLES_SERVICE_TABLES_NAME, delOp, - options, opContext); - - if (result.getHttpStatusCode() == HttpURLConnection.HTTP_NO_CONTENT) { - return; - } - else { - throw new StorageException(StorageErrorCodeStrings.OUT_OF_RANGE_INPUT, SR.UNEXPECTED_STATUS_CODE_RECEIVED, - result.getHttpStatusCode(), null /* extendedErrorInfo */, null /* innerException */); - } - + TableOperation deleteOp = new TableOperation(tableEntry, TableOperationType.DELETE); + deleteOp.execute(this.tableServiceClient, TableConstants.TABLES_SERVICE_TABLES_NAME, options, opContext); } /** @@ -415,7 +433,7 @@ public boolean deleteIfExists(TableRequestOptions options, OperationContext opCo * individual table operations, with the requirement that each operation entity must have same partition key. Only * one retrieve operation is allowed per batch. Note that the total payload of a batch operation is limited to 4MB. *

- * This method invokes an Entity Group + * This method invokes an Entity Group * Transaction on the REST API to execute the specified batch operation on the table as an atomic unit, using * the Table service endpoint and storage account credentials of this instance. * @@ -440,7 +458,7 @@ public ArrayList execute(final TableBatchOperation batch) throws St * table operations, with the requirement that each operation entity must have same partition key. Only one retrieve * operation is allowed per batch. Note that the total payload of a batch operation is limited to 4MB. *

- * This method invokes an Entity Group + * This method invokes an Entity Group * Transaction on the REST API to execute the specified batch operation on the table as an atomic unit, using * the Table service endpoint and storage account credentials of this instance. * @@ -480,9 +498,9 @@ public ArrayList execute(final TableBatchOperation batch, TableRequ /** * Executes the operation on a table. *

- * This method will invoke the Table - * Service REST API to execute the specified operation on the table, using the Table service endpoint and - * storage account credentials of this instance. + * This method will invoke the Table Service + * REST API to execute the specified operation on the table, using the Table service endpoint and storage + * account credentials of this instance. * * @param operation * The {@link TableOperation} object representing the operation to execute on the table. @@ -501,9 +519,9 @@ public TableResult execute(final TableOperation operation) throws StorageExcepti /** * Executes the operation on a table, using the specified {@link TableRequestOptions} and {@link OperationContext}. *

- * This method will invoke the Table - * Service REST API to execute the specified operation on the table, using the Table service endpoint and - * storage account credentials of this instance. + * This method will invoke the Table Service + * REST API to execute the specified operation on the table, using the Table service endpoint and storage + * account credentials of this instance. * * Use the {@link TableRequestOptions} to override execution options such as the timeout or retry policy for the * operation. @@ -534,9 +552,9 @@ public TableResult execute(final TableOperation operation, final TableRequestOpt /** * Executes a query, applying the specified {@link EntityResolver} to the result. *

- * This method will invoke a Query - * Entities operation on the Table - * Service REST API to query the table, using the Table service endpoint and storage account credentials of this + * This method will invoke a Query + * Entities operation on the Table Service + * REST API to query the table, using the Table service endpoint and storage account credentials of this * instance. * * @param query @@ -548,10 +566,9 @@ public TableResult execute(final TableOperation operation, final TableRequestOpt * @return * A collection implementing the Iterable interface containing the projection into type * R of the results of executing the query. - * @throws StorageException */ @DoesServiceRequest - public Iterable execute(final TableQuery query, final EntityResolver resolver) throws StorageException { + public Iterable execute(final TableQuery query, final EntityResolver resolver) { return this.execute(query, resolver, null /* options */, null /* opContext */); } @@ -559,9 +576,9 @@ public Iterable execute(final TableQuery query, final EntityResolver - * This method will invoke a Query - * Entities operation on the Table - * Service REST API to query the table, using the Table service endpoint and storage account credentials of this + * This method will invoke a Query + * Entities operation on the Table Service + * REST API to query the table, using the Table service endpoint and storage account credentials of this * instance. * * Use the {@link TableRequestOptions} to override execution options such as the timeout or retry policy for the @@ -583,12 +600,11 @@ public Iterable execute(final TableQuery query, final EntityResolverIterable interface containing the projection into type * R of the results of executing the query. - * @throws StorageException */ @DoesServiceRequest - @SuppressWarnings({ "unchecked", "deprecation" }) + @SuppressWarnings({ "unchecked" }) public Iterable execute(final TableQuery query, final EntityResolver resolver, - final TableRequestOptions options, final OperationContext opContext) throws StorageException { + final TableRequestOptions options, final OperationContext opContext) { Utility.assertNotNull("query", query); Utility.assertNotNull(SR.QUERY_REQUIRES_VALID_CLASSTYPE_OR_RESOLVER, resolver); query.setSourceTableName(this.getName()); @@ -598,9 +614,9 @@ public Iterable execute(final TableQuery query, final EntityResolver - * This method will invoke a Query - * Entities operation on the Table - * Service REST API to query the table, using the Table service endpoint and storage account credentials of this + * This method will invoke a Query + * Entities operation on the Table Service + * REST API to query the table, using the Table service endpoint and storage account credentials of this * instance. * * @param query @@ -610,19 +626,18 @@ public Iterable execute(final TableQuery query, final EntityResolverIterable interface specialized for type T of the results of * executing the query. - * @throws StorageException */ @DoesServiceRequest - public Iterable execute(final TableQuery query) throws StorageException { + public Iterable execute(final TableQuery query) { return this.execute(query, null /* options */, null /* opContext */); } /** * Executes a query, using the specified {@link TableRequestOptions} and {@link OperationContext}. *

- * This method will invoke a Query - * Entities operation on the Table - * Service REST API to query the table, using the Table service endpoint and storage account credentials of this + * This method will invoke a Query + * Entities operation on the Table Service + * REST API to query the table, using the Table service endpoint and storage account credentials of this * instance. * * Use the {@link TableRequestOptions} to override execution options such as the timeout or retry policy for the @@ -642,13 +657,13 @@ public Iterable execute(final TableQuery query) th * @return * A collection implementing the Iterable interface specialized for type T of the results of * executing the query. - * @throws StorageException */ - @SuppressWarnings({ "unchecked", "deprecation" }) + @SuppressWarnings({ "unchecked" }) @DoesServiceRequest public Iterable execute(final TableQuery query, final TableRequestOptions options, - final OperationContext opContext) throws StorageException { + final OperationContext opContext) { Utility.assertNotNull("query", query); + Utility.assertNotNull(SR.QUERY_REQUIRES_VALID_CLASSTYPE_OR_RESOLVER, query.getClazzType()); query.setSourceTableName(this.getName()); return (Iterable) this.getServiceClient().generateIteratorForQuery(query, null, options, opContext); } @@ -659,9 +674,9 @@ public Iterable execute(final TableQuery query, fi * Executing a query with executeSegmented allows the query to be resumed after returning partial * results, using information returned by the server in the {@link ResultSegment} object. *

- * This method will invoke a Query - * Entities operation on the Table - * Service REST API to query the table, using the Table service endpoint and storage account credentials of this + * This method will invoke a Query + * Entities operation on the Table Service + * REST API to query the table, using the Table service endpoint and storage account credentials of this * instance. * * @param query @@ -679,16 +694,12 @@ public Iterable execute(final TableQuery query, fi * A {@link ResultSegment} containing the projection into type R of the results of executing * the query. * - * @throws IOException - * if an IO error occurred during the operation. - * @throws URISyntaxException - * if the URI generated for the query is invalid. * @throws StorageException * if a storage service error occurred during the operation. */ @DoesServiceRequest public ResultSegment executeSegmented(final TableQuery query, final EntityResolver resolver, - final ResultContinuation continuationToken) throws IOException, URISyntaxException, StorageException { + final ResultContinuation continuationToken) throws StorageException { return this.executeSegmented(query, resolver, continuationToken, null /* options */, null /* opContext */); } @@ -699,9 +710,9 @@ public ResultSegment executeSegmented(final TableQuery query, final En * Executing a query with executeSegmented allows the query to be resumed after returning partial * results, using information returned by the server in the {@link ResultSegment} object. *

- * This method will invoke a Query - * Entities operation on the Table - * Service REST API to query the table, using the Table service endpoint and storage account credentials of this + * This method will invoke a Query + * Entities operation on the Table Service + * REST API to query the table, using the Table service endpoint and storage account credentials of this * instance. * * Use the {@link TableRequestOptions} to override execution options such as the timeout or retry policy for the @@ -729,18 +740,14 @@ public ResultSegment executeSegmented(final TableQuery query, final En * A {@link ResultSegment} containing the projection into type R of the results of executing * the query. * - * @throws IOException - * if an IO error occurred during the operation. - * @throws URISyntaxException - * if the URI generated for the query is invalid. * @throws StorageException * if a storage service error occurred during the operation. */ @DoesServiceRequest - @SuppressWarnings({ "unchecked", "deprecation" }) + @SuppressWarnings({ "unchecked" }) public ResultSegment executeSegmented(final TableQuery query, final EntityResolver resolver, final ResultContinuation continuationToken, final TableRequestOptions options, - final OperationContext opContext) throws IOException, URISyntaxException, StorageException { + final OperationContext opContext) throws StorageException { Utility.assertNotNull(SR.QUERY_REQUIRES_VALID_CLASSTYPE_OR_RESOLVER, resolver); query.setSourceTableName(this.getName()); return (ResultSegment) this.getServiceClient().executeQuerySegmentedImpl(query, resolver, continuationToken, @@ -752,9 +759,9 @@ public ResultSegment executeSegmented(final TableQuery query, final En * Executing a query with executeSegmented allows the query to be resumed after returning partial * results, using information returned by the server in the {@link ResultSegment} object. *

- * This method will invoke a Query - * Entities operation on the Table - * Service REST API to query the table, using the Table service endpoint and storage account credentials of this + * This method will invoke a Query + * Entities operation on the Table Service + * REST API to query the table, using the Table service endpoint and storage account credentials of this * instance. * * @param query @@ -769,16 +776,12 @@ public ResultSegment executeSegmented(final TableQuery query, final En * @return * A {@link ResultSegment} specialized for type T of the results of executing the query. * - * @throws IOException - * if an IO error occurred during the operation. - * @throws URISyntaxException - * if the URI generated for the query is invalid. * @throws StorageException * if a storage service error occurred during the operation. */ @DoesServiceRequest public ResultSegment executeSegmented(final TableQuery query, - final ResultContinuation continuationToken) throws IOException, URISyntaxException, StorageException { + final ResultContinuation continuationToken) throws StorageException { return this.executeSegmented(query, continuationToken, null /* options */, null /* opContext */); } @@ -788,9 +791,9 @@ public ResultSegment executeSegmented(final TableQuer * Executing a query with executeSegmented allows the query to be resumed after returning partial * results, using information returned by the server in the {@link ResultSegment} object. *

- * This method will invoke a Query - * Entities operation on the Table - * Service REST API to query the table, using the Table service endpoint and storage account credentials of this + * This method will invoke a Query + * Entities operation on the Table Service + * REST API to query the table, using the Table service endpoint and storage account credentials of this * instance. * * Use the {@link TableRequestOptions} to override execution options such as the timeout or retry policy for the @@ -815,18 +818,14 @@ public ResultSegment executeSegmented(final TableQuer * @return * A {@link ResultSegment} specialized for type T of the results of executing the query. * - * @throws IOException - * if an IO error occurred during the operation. - * @throws URISyntaxException - * if the URI generated for the query is invalid. * @throws StorageException * if a storage service error occurred during the operation. */ @DoesServiceRequest - @SuppressWarnings({ "unchecked", "deprecation" }) + @SuppressWarnings({ "unchecked" }) public ResultSegment executeSegmented(final TableQuery query, final ResultContinuation continuationToken, final TableRequestOptions options, - final OperationContext opContext) throws IOException, URISyntaxException, StorageException { + final OperationContext opContext) throws StorageException { Utility.assertNotNull("query", query); query.setSourceTableName(this.getName()); return (ResultSegment) this.getServiceClient().executeQuerySegmentedImpl(query, null, continuationToken, @@ -887,7 +886,6 @@ public boolean exists(TableRequestOptions options, OperationContext opContext) t * @throws StorageException * If a storage service error occurred during the operation. */ - @SuppressWarnings("deprecation") @DoesServiceRequest private boolean exists(final boolean primaryOnly, TableRequestOptions options, OperationContext opContext) throws StorageException { @@ -903,8 +901,9 @@ private boolean exists(final boolean primaryOnly, TableRequestOptions options, O QueryTableOperation operation = (QueryTableOperation) TableOperation.retrieve(this.name /* Used As PK */, null/* Row Key */, DynamicTableEntity.class); operation.setPrimaryOnlyRetrieve(primaryOnly); - final TableResult result = this.tableServiceClient.execute(TableConstants.TABLES_SERVICE_TABLES_NAME, - operation, options, opContext); + + final TableResult result = operation.execute(this.tableServiceClient, + TableConstants.TABLES_SERVICE_TABLES_NAME, options, opContext); if (result.getHttpStatusCode() == HttpURLConnection.HTTP_OK) { return true; @@ -1066,7 +1065,7 @@ public TablePermissions downloadPermissions(TableRequestOptions options, Operati } private StorageRequest downloadPermissionsImpl( - final TableRequestOptions options) throws StorageException { + final TableRequestOptions options) { final StorageRequest getRequest = new StorageRequest( options, this.getStorageUri()) { @@ -1100,8 +1099,8 @@ public TablePermissions preProcessResponse(CloudTable parentObject, CloudTableCl @Override public TablePermissions postProcessResponse(HttpURLConnection connection, CloudTable table, CloudTableClient client, OperationContext context, TablePermissions permissions) throws Exception { - HashMap accessIds = SharedAccessPolicyDeserializer - .getAccessIdentifiers(this.getConnection().getInputStream(), SharedAccessTablePolicy.class); + HashMap accessIds = SharedAccessPolicyHandler.getAccessIdentifiers( + this.getConnection().getInputStream(), SharedAccessTablePolicy.class); for (final String key : accessIds.keySet()) { permissions.getSharedAccessPolicies().put(key, accessIds.get(key)); } @@ -1133,7 +1132,7 @@ public String generateSharedAccessSignature(final SharedAccessTablePolicy policy final String accessPolicyIdentifier, final String startPartitionKey, final String startRowKey, final String endPartitionKey, final String endRowKey) throws InvalidKeyException, StorageException { - if (!this.tableServiceClient.getCredentials().canCredentialsSignRequest()) { + if (!StorageCredentialsHelper.canCredentialsSignRequest(this.tableServiceClient.getCredentials())) { throw new IllegalArgumentException(SR.CANNOT_CREATE_SAS_WITHOUT_ACCOUNT_KEY); } @@ -1201,6 +1200,9 @@ private void parseQueryAndVerify(final StorageUri completeUri, final CloudTableC .parseQuery(queryParameters); if (sasCreds == null) { + if (existingClient == null) { + throw new IllegalArgumentException(SR.STORAGE_CLIENT_OR_SAS_REQUIRED); + } return; } @@ -1213,10 +1215,8 @@ private void parseQueryAndVerify(final StorageUri completeUri, final CloudTableC } if (existingClient != null && !sameCredentials) { - this.tableServiceClient.setRetryPolicyFactory(existingClient.getRetryPolicyFactory()); - this.tableServiceClient.setTimeoutInMs(existingClient.getTimeoutInMs()); - this.tableServiceClient.setLocationMode(existingClient.getLocationMode()); - this.tableServiceClient.setTablePayloadFormat(existingClient.getTablePayloadFormat()); + this.tableServiceClient.setDefaultRequestOptions(new TableRequestOptions(existingClient + .getDefaultRequestOptions())); } } } diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/table/CloudTableClient.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/CloudTableClient.java new file mode 100644 index 0000000000000..c49ddd3e0e5e5 --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/CloudTableClient.java @@ -0,0 +1,756 @@ +/** + * 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.table; + +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Date; +import java.util.HashMap; + +import com.microsoft.azure.storage.DoesServiceRequest; +import com.microsoft.azure.storage.LocationMode; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.ResultContinuation; +import com.microsoft.azure.storage.ResultContinuationType; +import com.microsoft.azure.storage.ResultSegment; +import com.microsoft.azure.storage.RetryExponentialRetry; +import com.microsoft.azure.storage.ServiceClient; +import com.microsoft.azure.storage.ServiceProperties; +import com.microsoft.azure.storage.ServiceStats; +import com.microsoft.azure.storage.StorageCredentials; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.StorageUri; +import com.microsoft.azure.storage.blob.BlobRequestOptions; +import com.microsoft.azure.storage.blob.CloudBlobClient; +import com.microsoft.azure.storage.core.ExecutionEngine; +import com.microsoft.azure.storage.core.LazySegmentedIterable; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.SegmentedStorageRequest; +import com.microsoft.azure.storage.core.StorageRequest; +import com.microsoft.azure.storage.core.Utility; + +/** + * Provides a service client for accessing the Microsoft Azure Table service. + *

+ * The {@link CloudTableClient} class encapsulates the base URI for the Table service endpoint and the credentials for + * accessing the storage account, and provides methods to create, delete, list, and query tables, as well as methods to + * execute operations and queries on table entities. These methods invoke Storage Service REST API operations to make + * the requests and obtain the results that are returned. + *

+ * A Table service endpoint is the base URI for Table service resources, including the DNS name of the storage account: + *
+ *     http://myaccount.table.core.windows.net
+ * For more information, see the MSDN topic Addressing Table Service Resources. + *

+ * The credentials can be a combination of the storage account name and a key, or a shared access signature. For more + * information, see the MSDN topic Authenticating + * Access to Your Storage Account. + * + */ +public final class CloudTableClient extends ServiceClient { + /** + * Holds the default request option values associated with this Service Client. + */ + private TableRequestOptions defaultRequestOptions; + + /** + * Reserved for internal use. An {@link EntityResolver} that projects table entity data as a String + * containing the table name. + */ + private final EntityResolver tableNameResolver = new EntityResolver() { + @Override + public String resolve(String partitionKey, String rowKey, Date timeStamp, + HashMap properties, String etag) { + return properties.get(TableConstants.TABLE_NAME).getValueAsString(); + } + }; + + /** + * Initializes an instance of the CloudTableClient class using a Table service endpoint and + * storage account credentials. + * + * @param baseUri + * A java.net.URI object that represents the Table service endpoint used to initialize the + * client. + * @param credentials + * A {@link StorageCredentials} object that represents the storage account credentials for access. + */ + public CloudTableClient(final URI baseUri, StorageCredentials credentials) { + this(new StorageUri(baseUri), credentials); + } + + /** + * Initializes an instance of the CloudTableClientclass using a Table service endpoint and + * storage account credentials. + * + * @param baseUri + * A {@link StorageUri} object that represents the Table service endpoint used to initialize the + * client. + * @param credentials + * A {@link StorageCredentials} object that represents the storage account credentials for access. + */ + public CloudTableClient(final StorageUri baseUri, StorageCredentials credentials) { + super(baseUri, credentials); + if (credentials == null) { + throw new IllegalArgumentException(SR.STORAGE_TABLE_CREDENTIALS_NULL); + } + + this.defaultRequestOptions = new TableRequestOptions(); + this.defaultRequestOptions.setLocationMode(LocationMode.PRIMARY_ONLY); + this.defaultRequestOptions.setRetryPolicyFactory(new RetryExponentialRetry()); + this.defaultRequestOptions.setTablePayloadFormat(TablePayloadFormat.Json); + } + + /** + * Gets a {@link CloudTable} object with the specified name. + * + * @param tableName + * The name of the table, which must adhere to table naming rules. The table name + * should not include any path separator characters (/). + * Table names are case insensitive, must be unique within an account and must be between 3-63 characters + * long. Table names must start with an cannot begin with a numeric character and may only contain + * alphanumeric characters. Some table names are reserved, including "table". + * @return A reference to a {@link CloudTable} object. + * @throws URISyntaxException + * If the resource URI constructed based on the tableName is invalid. + * @throws StorageException + * If a storage service error occurred. + * @see Understanding the Table Service Data + * Model + */ + public CloudTable getTableReference(final String tableName) throws URISyntaxException, StorageException { + Utility.assertNotNullOrEmpty("tableName", tableName); + return new CloudTable(tableName, this); + } + + /** + * Lists the table names in the storage account. + *

+ * This method invokes the Query Tables + * REST API to list the table names, using the Table service endpoint and storage account credentials of this + * instance. + * + * @return + * An Iterable collection of the table names in the storage account retrieved lazily. + */ + @DoesServiceRequest + public Iterable listTables() { + return this.listTables(null); + } + + /** + * Lists the table names in the storage account that match the specified prefix. + *

+ * This method invokes the Query Tables + * REST API to list the table names that match the prefix, using the Table service endpoint and storage account + * credentials of this instance. + * + * @param prefix + * A String containing the prefix to match on table names to return. + * + * @return + * An Iterable collection of the table names in the storage account retrieved lazily that match + * the specified + * prefix. + */ + @DoesServiceRequest + public Iterable listTables(final String prefix) { + return this.listTables(prefix, null /* options */, null /* opContext */); + } + + /** + * Lists the table names in the storage account that match the specified prefix, using the specified + * {@link TableRequestOptions} and {@link OperationContext}. + *

+ * This method invokes the Query Tables + * REST API to list the table names that match the prefix, using the Table service endpoint and storage account + * credentials of this instance. + * + * Use the {@link TableRequestOptions} to override execution options such as the timeout or retry policy for the + * operation. + * + * @param prefix + * A String containing the prefix to match on table names to return. + * @param options + * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudTableClient}. + * @param opContext + * An {@link OperationContext} object for tracking the current operation. Specify null to + * safely ignore operation context. + * + * @return + * An Iterable collection of the table names in the storage account retrieved lazily that match + * the specified + * prefix. + */ + @SuppressWarnings("unchecked") + @DoesServiceRequest + public Iterable listTables(final String prefix, final TableRequestOptions options, + final OperationContext opContext) { + return (Iterable) this.generateIteratorForQuery(this.generateListTablesQuery(prefix), + this.tableNameResolver, options, opContext); + } + + /** + * Lists the table names in the storage account in segmented mode. This method allows listing of tables to be + * resumed after returning a partial set of results, using information returned by the server in the + * {@link ResultSegment} object. + *

+ * This method invokes the Query Tables + * REST API to list the table names, using the Table service endpoint and storage account credentials of this + * instance. + * + * @return + * A {@link ResultSegment} of String objects containing table names in the storage account. + * + * @throws StorageException + * if a storage service error occurred during the operation. + */ + @DoesServiceRequest + public ResultSegment listTablesSegmented() throws StorageException { + return this.listTablesSegmented(null); + } + + /** + * Lists the table names in the storage account that match the specified prefix in segmented mode. This method + * allows listing of tables to be resumed after returning a partial set of results, using information returned by + * the server in the {@link ResultSegment} object. + *

+ * This method invokes the Query Tables + * REST API to list the table names that match the prefix, using the Table service endpoint and storage account + * credentials of this instance. + * + * @param prefix + * A String containing the prefix to match on table names to return. + * + * @return + * A {@link ResultSegment} of String objects containing table names matching the prefix in the + * storage account. + * + * @throws StorageException + * if a storage service error occurred during the operation. + */ + @DoesServiceRequest + public ResultSegment listTablesSegmented(final String prefix) throws StorageException { + return this.listTablesSegmented(prefix, null /* maxResults */, null /* continuationToken */, + null /* options */, null /* opContext */); + } + + /** + * Lists up to the specified maximum of the table names in the storage account that match the specified prefix in a + * resumable mode with the specified {@link ResultContinuation} continuation token, using the specified + * {@link TableRequestOptions} and {@link OperationContext}. This method allows listing of tables to be resumed + * after returning a page of results, using information returned by the server in the {@link ResultSegment} object. + *

+ * This method invokes the Query Tables + * REST API to list the table names that match the prefix, using the Table service endpoint and storage account + * credentials of this instance. + * + * Use the {@link TableRequestOptions} to override execution options such as the timeout or retry policy for the + * operation. + * + * @param prefix + * A String containing the prefix to match on table names to return. + * @param maxResults + * The maximum number of table names to return in the {@link ResultSegment}. If this parameter is null, + * the query will list up to the maximum 1,000 results. + * @param continuationToken + * A {@link ResultContinuation} object representing a continuation token from the server when the + * operation returns a partial result. Specify null on the initial call. Call the + * {@link ResultSegment#getContinuationToken()} method on the result to obtain the + * {@link ResultContinuation} object to use in the next call to resume the query. + * @param options + * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudTableClient}. + * @param opContext + * An {@link OperationContext} object for tracking the current operation. Specify null to + * safely ignore operation context. + * + * @return + * A {@link ResultSegment} of String objects containing table names in the storage account. + * + * @throws StorageException + * if a storage service error occurred during the operation. + */ + @SuppressWarnings("unchecked") + @DoesServiceRequest + public ResultSegment listTablesSegmented(final String prefix, final Integer maxResults, + final ResultContinuation continuationToken, final TableRequestOptions options, + final OperationContext opContext) throws StorageException { + return (ResultSegment) this.executeQuerySegmentedImpl( + this.generateListTablesQuery(prefix).take(maxResults), this.tableNameResolver, continuationToken, + options, opContext); + } + + /** + * Reserved for internal use. Generates a query to list table names with the given prefix. + * + * @param prefix + * A String containing the prefix to match on table names to return. + * @return + * A {@link TableQuery} instance for listing table names with the specified prefix. + */ + private TableQuery generateListTablesQuery(final String prefix) { + TableQuery listQuery = TableQuery. from(TableServiceEntity.class); + listQuery.setSourceTableName(TableConstants.TABLES_SERVICE_TABLES_NAME); + + if (!Utility.isNullOrEmpty(prefix)) { + // Append Max char to end '{' is 1 + 'z' in AsciiTable > uppperBound = prefix + '{' + final String prefixFilter = String.format("(%s ge '%s') and (%s lt '%s{')", TableConstants.TABLE_NAME, + prefix, TableConstants.TABLE_NAME, prefix); + + listQuery = listQuery.where(prefixFilter); + } + + return listQuery; + } + + /** + * Reserved for internal use. Executes a segmented query operation using the specified retry and timeout policies. + * + * @param queryToExecute + * The {@link TableQuery} to execute. + * @param resolver + * An {@link EntityResolver} instance which creates a projection of the table query result entities into + * the specified type R. Pass null to return the results as the table entity + * type. + * @param continuationToken + * The {@link ResultContinuation} to pass with the operation to resume a query, if any. Pass + * null for an initial query. + * @param options + * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudTableClient}. + * @param opContext + * An {@link OperationContext} object for tracking the current operation. Specify null to + * safely ignore operation context. + * @return + * A {@link ResultSegment} containing a collection of the query results specialized for the + * {@link TableEntity} or {@link EntityResolver} type returned by the query. + * @throws StorageException + * if a Storage service error occurs. + */ + protected ResultSegment executeQuerySegmentedImpl(final TableQuery queryToExecute, + final EntityResolver resolver, final ResultContinuation continuationToken, TableRequestOptions options, + OperationContext opContext) throws StorageException { + if (opContext == null) { + opContext = new OperationContext(); + } + + opContext.initialize(); + options = TableRequestOptions.applyDefaults(options, this); + + Utility.assertContinuationType(continuationToken, ResultContinuationType.TABLE); + + SegmentedStorageRequest segmentedRequest = new SegmentedStorageRequest(); + segmentedRequest.setToken(continuationToken); + + return ExecutionEngine.executeWithRetry(this, queryToExecute, + this.executeQuerySegmentedWithResolverCoreImpl(queryToExecute, resolver, options, segmentedRequest), + options.getRetryPolicyFactory(), opContext); + } + + private StorageRequest, ResultSegment> executeQuerySegmentedCoreImpl( + final TableQuery queryToExecute, final EntityResolver resolver, final TableRequestOptions options, + final SegmentedStorageRequest segmentedRequest) { + + if (resolver == null) { + Utility.assertNotNull(SR.QUERY_REQUIRES_VALID_CLASSTYPE_OR_RESOLVER, queryToExecute.getClazzType()); + } + + final StorageRequest, ResultSegment> getRequest = new StorageRequest, ResultSegment>( + options, this.getStorageUri()) { + + @Override + public void setRequestLocationMode() { + this.setRequestLocationMode(Utility.getListingLocationMode(segmentedRequest.getToken())); + } + + @Override + public HttpURLConnection buildRequest(CloudTableClient client, TableQuery queryRef, + OperationContext context) throws Exception { + return TableRequest.query(client.getTransformedEndPoint(context).getUri(this.getCurrentLocation()), + options, queryToExecute.generateQueryBuilder(), context, queryToExecute.getSourceTableName(), + null/* identity */, segmentedRequest.getToken()); + } + + @Override + public void signRequest(HttpURLConnection connection, CloudTableClient client, OperationContext context) + throws Exception { + StorageRequest.signTableRequest(connection, client, -1L, context); + } + + @Override + public ResultSegment preProcessResponse(TableQuery queryRef, CloudTableClient client, + OperationContext context) throws Exception { + if (this.getResult().getStatusCode() != HttpURLConnection.HTTP_OK) { + throw TableServiceException.generateTableServiceException(true, this.getResult(), null, this + .getConnection().getErrorStream(), options.getTablePayloadFormat()); + } + + return null; + } + + @SuppressWarnings("unchecked") + @Override + public ResultSegment postProcessResponse(HttpURLConnection connection, TableQuery queryRef, + CloudTableClient client, OperationContext context, ResultSegment storageObject) throws Exception { + ODataPayload clazzResponse = null; + + InputStream inStream = connection.getInputStream(); + + clazzResponse = (ODataPayload) TableDeserializer.parseQueryResponse(inStream, options, + queryToExecute.getClazzType(), null, context); + + final ResultContinuation nextToken = TableResponse.getTableContinuationFromResponse(connection); + if (nextToken != null) { + nextToken.setTargetLocation(this.getResult().getTargetLocation()); + } + + // Note, setting the token on the SegmentedStorageRequest is + // key, this is how the iterator will share the token across executions + segmentedRequest.setToken(nextToken); + + return new ResultSegment(clazzResponse.results, + queryToExecute.getTakeCount() == null ? clazzResponse.results.size() + : queryToExecute.getTakeCount(), nextToken); + } + }; + + return getRequest; + } + + private StorageRequest, ResultSegment> executeQuerySegmentedWithResolverCoreImpl( + final TableQuery queryToExecute, final EntityResolver resolver, final TableRequestOptions options, + final SegmentedStorageRequest segmentedRequest) { + + if (resolver == null) { + Utility.assertNotNull(SR.QUERY_REQUIRES_VALID_CLASSTYPE_OR_RESOLVER, queryToExecute.getClazzType()); + } + + final StorageRequest, ResultSegment> getRequest = new StorageRequest, ResultSegment>( + options, this.getStorageUri()) { + + @Override + public void setRequestLocationMode() { + this.setRequestLocationMode(Utility.getListingLocationMode(segmentedRequest.getToken())); + } + + @Override + public HttpURLConnection buildRequest(CloudTableClient client, TableQuery queryRef, + OperationContext context) throws Exception { + return TableRequest.query(client.getTransformedEndPoint(context).getUri(this.getCurrentLocation()), + options, queryToExecute.generateQueryBuilder(), context, queryToExecute.getSourceTableName(), + null/* identity */, segmentedRequest.getToken()); + } + + @Override + public void signRequest(HttpURLConnection connection, CloudTableClient client, OperationContext context) + throws Exception { + StorageRequest.signTableRequest(connection, client, -1L, context); + } + + @Override + public ResultSegment preProcessResponse(TableQuery queryRef, CloudTableClient client, + OperationContext context) throws Exception { + if (this.getResult().getStatusCode() != HttpURLConnection.HTTP_OK) { + throw TableServiceException.generateTableServiceException(true, this.getResult(), null, this + .getConnection().getErrorStream(), options.getTablePayloadFormat()); + } + + return null; + } + + @SuppressWarnings("unchecked") + @Override + public ResultSegment postProcessResponse(HttpURLConnection connection, TableQuery queryRef, + CloudTableClient client, OperationContext context, ResultSegment storageObject) throws Exception { + ODataPayload resolvedResponse = null; + + InputStream inStream = connection.getInputStream(); + + resolvedResponse = (ODataPayload) TableDeserializer.parseQueryResponse(inStream, options, + queryToExecute.getClazzType(), resolver, context); + + final ResultContinuation nextToken = TableResponse.getTableContinuationFromResponse(connection); + if (nextToken != null) { + nextToken.setTargetLocation(this.getResult().getTargetLocation()); + } + + // Note, setting the token on the SegmentedStorageRequest is + // key, this is how the iterator will share the token across executions + segmentedRequest.setToken(nextToken); + + return new ResultSegment(resolvedResponse.results, + queryToExecute.getTakeCount() == null ? resolvedResponse.results.size() + : queryToExecute.getTakeCount(), nextToken); + + } + }; + + return getRequest; + } + + protected final StorageUri getTransformedEndPoint(final OperationContext opContext) throws URISyntaxException, + StorageException { + return this.getCredentials().transformUri(this.getStorageUri(), opContext); + } + + /** + * Reserved for internal use. Generates an iterator for a segmented query operation. + * + * @param queryRef + * The {@link TableQuery} to execute. + * @param resolver + * An {@link EntityResolver} instance which creates a projection of the table query result entities into + * the specified type R. Pass null to return the results as the table entity + * type. + * @param options + * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudTableClient}. + * @param opContext + * An {@link OperationContext} object for tracking the current operation. Specify null to + * safely ignore operation context. + * @return + * An instance of Iterable specialized for the {@link TableEntity} or {@link EntityResolver} + * type returned by the query. + */ + protected Iterable generateIteratorForQuery(final TableQuery queryRef, + final EntityResolver resolver, TableRequestOptions options, OperationContext opContext) { + + if (opContext == null) { + opContext = new OperationContext(); + } + + opContext.initialize(); + options = TableRequestOptions.applyDefaults(options, this); + + SegmentedStorageRequest segmentedRequest = new SegmentedStorageRequest(); + + if (resolver == null) { + return new LazySegmentedIterable, T>(this.executeQuerySegmentedCoreImpl( + queryRef, resolver, options, segmentedRequest), this, queryRef, options.getRetryPolicyFactory(), + opContext); + } + else { + return new LazySegmentedIterable, R>( + this.executeQuerySegmentedWithResolverCoreImpl(queryRef, resolver, options, segmentedRequest), + this, queryRef, options.getRetryPolicyFactory(), opContext); + } + } + + /** + * Queries the service for the {@link ServiceStats}. + * + * @return {@link ServiceStats} for the given storage service + * @throws StorageException + * If a storage service error occurred. + */ + @DoesServiceRequest + public ServiceStats getServiceStats() throws StorageException { + return this.getServiceStats(null /* options */, null /* opContext */); + } + + /** + * Queries the given storage service for the {@link ServiceStats}. + * + * @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 that 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. + * @return {@link ServiceStats} for the given storage service + * @throws StorageException + * If a storage service error occurred. + */ + @DoesServiceRequest + public ServiceStats getServiceStats(TableRequestOptions options, OperationContext opContext) + throws StorageException { + if (opContext == null) { + opContext = new OperationContext(); + } + + opContext.initialize(); + options = TableRequestOptions.applyDefaults(options, this); + + return ExecutionEngine.executeWithRetry(this, null, this.getServiceStatsImpl(options, true), + options.getRetryPolicyFactory(), opContext); + } + + /** + * Retrieves the current {@link ServiceProperties} for the given storage service. This includes Logging, + * HourMetrics, MinuteMetrics and CORS configurations. + * + * @return the {@link ServiceProperties} object representing the current configuration of the service. + * @throws StorageException + * If a storage service error occurred. + */ + @DoesServiceRequest + public final ServiceProperties downloadServiceProperties() throws StorageException { + return this.downloadServiceProperties(null /* options */, null /* opContext */); + } + + /** + * Retrieves the current {@link ServiceProperties} for the given storage service. This includes Logging, + * HourMetrics, MinuteMetrics and CORS configurations. + * + * @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 that 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. + * + * @return the {@link ServiceProperties} object representing the current configuration of the service. + * @throws StorageException + * If a storage service error occurred. + */ + @DoesServiceRequest + public final ServiceProperties downloadServiceProperties(TableRequestOptions options, OperationContext opContext) + throws StorageException { + if (opContext == null) { + opContext = new OperationContext(); + } + + opContext.initialize(); + options = TableRequestOptions.applyDefaults(options, this); + + return ExecutionEngine.executeWithRetry(this, null, this.downloadServicePropertiesImpl(options, true), + options.getRetryPolicyFactory(), opContext); + } + + /** + * Uploads a new {@link ServiceProperties} configuration to the given storage service. This includes Logging, + * HourMetrics, MinuteMetrics and CORS configurations. + * + * @param properties + * The {@link ServiceProperties} to upload. + * @throws StorageException + * If a storage service error occurred. + */ + @DoesServiceRequest + public void uploadServiceProperties(final ServiceProperties properties) throws StorageException { + this.uploadServiceProperties(properties, null /* options */, null /* opContext */); + } + + /** + * Uploads a new {@link ServiceProperties} configuration to the given storage service. This includes Logging, + * HourMetrics, MinuteMetrics and CORS configurations. + * + * @param properties + * The {@link ServiceProperties} to upload. + * @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 that 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 uploadServiceProperties(final ServiceProperties properties, TableRequestOptions options, + OperationContext opContext) throws StorageException { + if (!Utility.isNullOrEmpty(properties.getDefaultServiceVersion())) { + throw new IllegalArgumentException(SR.DEFAULT_SERVICE_VERSION_ONLY_SET_FOR_BLOB_SERVICE); + } + + if (opContext == null) { + opContext = new OperationContext(); + } + + opContext.initialize(); + options = TableRequestOptions.applyDefaults(options, this); + + Utility.assertNotNull("properties", properties); + + ExecutionEngine.executeWithRetry(this, null, + this.uploadServicePropertiesImpl(properties, options, opContext, true), + options.getRetryPolicyFactory(), opContext); + } + + /** + * Gets the {@link TablePayloadFormat} that is used for any table accessed with this CloudTableClient + * object. Default is {@link TablePayloadFormat#Json} + * + * @return + * The {@link TablePayloadFormat} used by this CloudTableClient + * + * @deprecated use {@link #getDefaultRequestOptions().getTablePayloadFormat()} instead. + */ + @Deprecated + public TablePayloadFormat getTablePayloadFormat() { + return this.defaultRequestOptions.getTablePayloadFormat(); + } + + /** + * Sets the {@link TablePayloadFormat} that is used for any table accessed with this CloudTableClient + * object. + * + * @param payloadFormat + * The TablePayloadFormat to use. + * + * @deprecated use {@link #getDefaultRequestOptions().setTablePayloadFormat()} instead. + */ + @Deprecated + public void setTablePayloadFormat(TablePayloadFormat payloadFormat) { + this.defaultRequestOptions.setTablePayloadFormat(payloadFormat); + } + + /** + * Gets the {@link TableRequestOptions} that is used for requests associated with this CloudTableClient + * + * @return + * The {@link TableRequestOptions} object containing the values used by this CloudTableClient + */ + @Override + public TableRequestOptions getDefaultRequestOptions() { + return this.defaultRequestOptions; + } + + /** + * Sets the {@link TableRequestOptions} that is used for any table accessed with this CloudTableClient + * object. + * + * @param defaultRequestOptions + * The TableRequestOptions to use. + */ + public void setDefaultRequestOptions(TableRequestOptions defaultRequestOptions) { + Utility.assertNotNull("defaultRequestOptions", defaultRequestOptions); + this.defaultRequestOptions = defaultRequestOptions; + } + + /** + * @return the usePathStyleUris + */ + @Override + protected boolean isUsePathStyleUris() { + return super.isUsePathStyleUris(); + } +} \ No newline at end of file diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/DeserializationHelper.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/DeserializationHelper.java similarity index 61% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/DeserializationHelper.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/DeserializationHelper.java index 0c611b123dc6d..74630f8b56e30 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/DeserializationHelper.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/DeserializationHelper.java @@ -12,73 +12,72 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.core; +package com.microsoft.azure.storage.table; import java.io.InputStream; import java.io.Reader; -import java.util.HashMap; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; -import com.microsoft.windowsazure.storage.Constants; +import com.microsoft.azure.storage.Constants; /** * RESERVED FOR INTERNAL USE. An internal helper class used to parse objects from responses. */ -public final class DeserializationHelper { +final class DeserializationHelper { + // see use below for more explanation + private final static String ENTITY_EXPANSION_EXCEPTION_MESSAGE = "(.|\n)*Message: JAXP00010001: The parser has encountered more than \"\\d+\" entity expansions in this document; this is the limit imposed by the JDK\\."; - private final static XMLInputFactory xmlif = XMLInputFactory.newInstance(); + private static XMLInputFactory xmlif; static { + setupXMLInputFactory(); + } + + /** + * Sets this class's XMLInputFactory instance to a new factory instance and sets the appropriate + * properties on it. This is not synchronized so multiple threads executing this will cause multiple factories to be + * created, but this is okay as it does not matter for the reader which factory creates it as they are functionally + * identical. + */ + public static void setupXMLInputFactory() { + final XMLInputFactory xmlif = XMLInputFactory.newInstance(); xmlif.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, Boolean.TRUE); xmlif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); // set the IS_COALESCING property to true , if application desires to // get whole text data as one event. xmlif.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE); + DeserializationHelper.xmlif = xmlif; } /** - * Reads Metadata from the XMLStreamReader. - * - * @param xmlr - * the XMLStreamReader object - * @return the metadata as a hashmap. - * @throws XMLStreamException - * if there is a parsing exception + * Tests whether the provided exception is an entity expansion exception. + * + * Some versions of Java cause an exception to be incorrectly thrown when more XMLStreamReaders have been + * created by a single factory than the entity expansion limit property (default 64000). The default form of this + * exception is: "ParseError at [row,col]:[1,1]\n + * Message: JAXP00010001: The parser has encountered more than + * \"64000\" entity expansions in this document; this is the limit imposed by the JDK." + * + * @param e + * the XMLStreamException to test + * @return + * true if entity expansion exception, false otherwise */ - public static HashMap parseMetadateFromXML(final XMLStreamReader xmlr) throws XMLStreamException { - final HashMap retVals = new HashMap(); - xmlr.require(XMLStreamConstants.START_ELEMENT, null, Constants.METADATA_ELEMENT); - - int eventType = xmlr.getEventType(); - - while (xmlr.hasNext()) { - eventType = xmlr.next(); - final String name = xmlr.getName().toString(); - - if (eventType == XMLStreamConstants.END_ELEMENT && Constants.METADATA_ELEMENT.equals(name)) { - break; - } - else if (Constants.INVALID_METADATA_NAME.equals(name)) { - // no op , skip - } - else if (eventType == XMLStreamConstants.START_ELEMENT) { - final String tValue = DeserializationHelper.readElementFromXMLReader(xmlr, name); - if (!Utility.isNullOrEmpty(tValue)) { - retVals.put(name, tValue); - } - } - } - - return retVals; + public static boolean isEntityExpansionLimitException(XMLStreamException e) { + return e.getMessage() != null && e.getMessage().matches(ENTITY_EXPANSION_EXCEPTION_MESSAGE); } /** * Creates an XML stream reader from the specified input stream. * + * Some versions of Java cause an exception to be incorrectly thrown when more XMLStreamReaders have been + * created by a single factory than the entity expansion limit property (default 64000). This model catches + * that exception, creates a new factory with the appropriate settings, and then retries the reader creation. + * * @param reader * An InputStreamReader object that represents the input reader to use as the source. * @@ -87,14 +86,32 @@ else if (eventType == XMLStreamConstants.START_ELEMENT) { * * @throws XMLStreamException * If the XML stream reader could not be created. + * @see https://bugs.openjdk.java.net/browse/JDK-8028111 */ public static XMLStreamReader createXMLStreamReaderFromReader(final Reader reader) throws XMLStreamException { - return xmlif.createXMLStreamReader(reader); + while (true) { + try { + return xmlif.createXMLStreamReader(reader); + } + catch (XMLStreamException e) { + if (isEntityExpansionLimitException(e)) { + setupXMLInputFactory(); + } + else { + throw e; + } + } + } } /** * Creates an XML stream reader from the specified input stream. * + * Some versions of Java cause an exception to be incorrectly thrown when more XMLStreamReaders have been + * created by a single factory than the entity expansion limit property (default 64000). This model catches + * that exception, creates a new factory with the appropriate settings, and then retries the reader creation. + * * @param streamRef * An InputStream object that represents the input stream to use as the source. * @@ -103,10 +120,25 @@ public static XMLStreamReader createXMLStreamReaderFromReader(final Reader reade * * @throws XMLStreamException * If the XML stream reader could not be created. + * + * @see https://bugs.openjdk.java.net/browse/JDK-8028111 */ public static XMLStreamReader createXMLStreamReaderFromStream(final InputStream streamRef) throws XMLStreamException { - return xmlif.createXMLStreamReader(streamRef, Constants.UTF8_CHARSET); + while (true) { + try { + return xmlif.createXMLStreamReader(streamRef, Constants.UTF8_CHARSET); + } + catch (XMLStreamException e) { + if (isEntityExpansionLimitException(e)) { + setupXMLInputFactory(); + } + else { + throw e; + } + } + } } /** @@ -175,27 +207,6 @@ public static String readElementFromXMLReader(final XMLStreamReader xmlr, final } } - /** - * Reads character data for the Etag element from an XML stream reader. - * - * @param xmlr - * An XMLStreamReader object that represents the source XML stream reader. - * - * @return A String that represents the character data for the Etag element. - * - * @throws XMLStreamException - * If an XML stream failure occurs. - */ - public static String readETagFromXMLReader(final XMLStreamReader xmlr) throws XMLStreamException { - String etag = readElementFromXMLReader(xmlr, Constants.ETAG_ELEMENT, true); - if (etag.startsWith("\"") && etag.endsWith("\"")) { - return etag; - } - else { - return String.format("\"%s\"", etag); - } - } - /** * Private Default Ctor */ diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/DynamicTableEntity.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/DynamicTableEntity.java similarity index 97% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/DynamicTableEntity.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/DynamicTableEntity.java index 39d9fe8e5c3ae..9e17d4f8f6c40 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/DynamicTableEntity.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/DynamicTableEntity.java @@ -13,13 +13,13 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.util.Date; import java.util.HashMap; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageException; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.StorageException; /** * A {@link TableEntity} type which allows callers direct access to the property map of the entity. This class extends diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/EdmType.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/EdmType.java similarity index 93% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/EdmType.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/EdmType.java index 014f360c857c9..26ba5d047d8ac 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/EdmType.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/EdmType.java @@ -13,14 +13,14 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.util.Collections; import java.util.EnumSet; import java.util.Set; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.core.SR; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.core.SR; /** * A enumeration used to represent the primitive types of the Entity Data Model (EDM) in the Open Data Protocol (OData). @@ -134,16 +134,17 @@ protected final boolean mustAnnotateType() { /** * Parses an EDM data type name and return the matching {@link EdmType} enumeration value. A null or * empty value parameter is matched as {@link EdmType#STRING}. Note that only the subset of EDM data types - * supported in Windows Azure Table storage is parsed, consisting of {@link #BINARY}, {@link #BOOLEAN}, + * supported in Microsoft Azure Table storage is parsed, consisting of {@link #BINARY}, {@link #BOOLEAN}, * {@link #BYTE} , {@link #DATE_TIME}, {@link #DOUBLE}, {@link #GUID}, {@link #INT32}, {@link #INT64}, and - * {@link #STRING}. Any other type will cause an {@link IllegalArgumentException} to be thrown. + * {@link #STRING}. Any + * other type will cause an {@link IllegalArgumentException} to be thrown. * * @param value * A String containing the name of an EDM data type. * @return * The {@link EdmType} enumeration value matching the specified EDM data type. * @throws IllegalArgumentException - * if an EDM data type not supported in Windows Azure Table storage is passed as an argument. + * if an EDM data type not supported in Microsoft Azure Table storage is passed as an argument. * */ public static EdmType parse(final String value) { diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/EntityProperty.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/EntityProperty.java similarity index 98% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/EntityProperty.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/EntityProperty.java index e3e04722abc5f..ecb21bc058de2 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/EntityProperty.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/EntityProperty.java @@ -13,16 +13,16 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.text.ParseException; import java.util.Date; import java.util.UUID; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.core.Base64; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.core.Base64; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; /** * A class which represents a single typed property value in a table entity. An {@link EntityProperty} stores the data @@ -184,10 +184,8 @@ else if (type.equals(Date.class)) { * The String representation of the value to construct. * @param edmType * The {@link EdmType} data type of the value to construct. - * @throws ParseException - * if the String representation of the value cannot be interpreted as the data type. */ - protected EntityProperty(final String value, final EdmType edmType) throws ParseException { + protected EntityProperty(final String value, final EdmType edmType) { this.edmType = edmType; this.value = value; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/EntityResolver.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/EntityResolver.java similarity index 96% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/EntityResolver.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/EntityResolver.java index 00a2b2700cbb9..db3f000a63a42 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/EntityResolver.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/EntityResolver.java @@ -13,12 +13,12 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.util.Date; import java.util.HashMap; -import com.microsoft.windowsazure.storage.StorageException; +import com.microsoft.azure.storage.StorageException; /** * An interface to perform client side projection on a retrieved entity. An {@link EntityResolver} instance must diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/Ignore.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/Ignore.java similarity index 96% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/Ignore.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/Ignore.java index be95182c5c045..fb0bbee606209 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/Ignore.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/Ignore.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/MimeHeader.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/MimeHeader.java similarity index 76% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/MimeHeader.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/MimeHeader.java index 30a6b8c6d928a..d28bf964a1139 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/MimeHeader.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/MimeHeader.java @@ -12,14 +12,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; /** * Reserved for internal use. A class that represents a given MIME Header. */ -class MimeHeader { - protected String boundary; - protected String contentType; - protected String contentTransferEncoding; - protected String subBoundary; +final class MimeHeader { + String boundary; + String contentType; + String contentTransferEncoding; + String subBoundary; } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/MimeHelper.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/MimeHelper.java similarity index 94% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/MimeHelper.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/MimeHelper.java index ccfae8427fda9..4b609a86f0a2f 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/MimeHelper.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/MimeHelper.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.io.BufferedReader; import java.io.IOException; @@ -28,20 +28,19 @@ import javax.xml.stream.XMLStreamException; -import com.fasterxml.jackson.core.JsonParseException; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageErrorCodeStrings; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.core.PathUtility; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.UriQueryBuilder; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.StorageErrorCodeStrings; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.core.PathUtility; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.UriQueryBuilder; +import com.microsoft.azure.storage.core.Utility; /** * Reserved for internal use. A class used to read and write MIME requests and responses. */ -class MimeHelper { +final class MimeHelper { /** * Reserved for internal use. Reads the response stream from a batch operation into an ArrayList of * {@link MimePart} objects. @@ -61,12 +60,9 @@ class MimeHelper { * if a storage service error occurs. * @throws IOException * if an error occurs while accessing the stream with Json. - * @throws JsonParseException - * if an error occurs while parsing the stream. */ - protected static ArrayList readBatchResponseStream(final InputStream inStream, - final String expectedBundaryName, final OperationContext opContext, TablePayloadFormat format) - throws IOException, StorageException, XMLStreamException { + static ArrayList readBatchResponseStream(final InputStream inStream, final String expectedBundaryName, + final OperationContext opContext, TablePayloadFormat format) throws IOException, StorageException { final ArrayList result = new ArrayList(); final InputStreamReader streamReader = new InputStreamReader(inStream, Constants.UTF8_CHARSET); final BufferedReader reader = new BufferedReader(streamReader); @@ -106,7 +102,7 @@ protected static ArrayList readBatchResponseStream(final InputStream i /** * Reserved for internal use. Writes the batch operation to the output stream using batch request syntax. * Batch request syntax is described in the MSDN topic Performing Entity Group + * href="http://msdn.microsoft.com/en-us/library/azure/dd894038.aspx">Performing Entity Group * Transactions. * * @param outStream @@ -132,7 +128,7 @@ protected static ArrayList readBatchResponseStream(final InputStream i * @throws XMLStreamException * if an error occurs accessing the stream. */ - protected static void writeBatchToStream(final OutputStream outStream, final TableRequestOptions options, + static void writeBatchToStream(final OutputStream outStream, final TableRequestOptions options, final String tableName, final URI baseUri, final TableBatchOperation batch, final String batchID, final String changeSet, final OperationContext opContext) throws IOException, URISyntaxException, StorageException, XMLStreamException { @@ -470,6 +466,7 @@ private static String writeStringForOperation(final TableOperation operation, Ta return outWriter.toString(); } + @SuppressWarnings("deprecation") private static String generateAcceptHeaderValue(TablePayloadFormat payloadFormat) { if (payloadFormat == TablePayloadFormat.AtomPub) { return TableConstants.HeaderConstants.ATOM_ACCEPT_TYPE; @@ -485,6 +482,7 @@ else if (payloadFormat == TablePayloadFormat.Json) { } } + @SuppressWarnings("deprecation") private static String generateContentTypeHeaderValue(TablePayloadFormat payloadFormat) { if (payloadFormat == TablePayloadFormat.AtomPub) { return TableConstants.HeaderConstants.ATOM_CONTENT_TYPE; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/MimePart.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/MimePart.java similarity index 81% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/MimePart.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/MimePart.java index 0d0e20df77556..07d6ae8d37841 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/MimePart.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/MimePart.java @@ -13,26 +13,26 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.net.URI; import java.util.HashMap; import java.util.Map; -import com.microsoft.windowsazure.storage.core.SR; +import com.microsoft.azure.storage.core.SR; /** * Reserved for internal use. A class that represents a given MIME Part. */ -class MimePart { - protected int httpStatusCode = -1; - protected String httpStatusMessage; - protected HashMap headers = new HashMap(); - protected String payload; - protected TableOperationType op; - protected URI requestIdentity; +final class MimePart { + int httpStatusCode = -1; + String httpStatusMessage; + HashMap headers = new HashMap(); + String payload; + TableOperationType op; + URI requestIdentity; - protected String toRequestString() { + String toRequestString() { StringBuilder builder = new StringBuilder(); // append mime part header @@ -53,7 +53,7 @@ protected String toRequestString() { return builder.toString(); } - protected static void appendHeader(StringBuilder builder) { + static void appendHeader(StringBuilder builder) { builder.append("Content-Type: application/http\r\n"); builder.append("Content-Transfer-Encoding: binary\r\n\r\n"); } @@ -66,7 +66,7 @@ protected static void appendHeader(StringBuilder builder) { * @return * A String containing the HTTP verb to use with the operation. */ - protected static String getHttpVerbForOperation(final TableOperationType operationType) { + static String getHttpVerbForOperation(final TableOperationType operationType) { if (operationType == TableOperationType.INSERT) { return "POST"; } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/ODataConstants.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/ODataConstants.java similarity index 98% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/ODataConstants.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/ODataConstants.java index 787ee1d7dcbb8..17e710baef5e6 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/ODataConstants.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/ODataConstants.java @@ -13,12 +13,12 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; /** * Reserved for internal use. A class that holds relevant constants for interacting with OData feeds. */ -class ODataConstants { +final class ODataConstants { /** * The String representation of the Atom namespace. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/ODataPayload.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/ODataPayload.java similarity index 85% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/ODataPayload.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/ODataPayload.java index 26d50636f6698..f7c779a0f35b7 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/ODataPayload.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/ODataPayload.java @@ -13,29 +13,29 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.util.ArrayList; /** * Reserved for internal use. A class that represents an OData payload and resulting entities. */ -class ODataPayload { +final class ODataPayload { /** * A collection of table entities. */ - protected ArrayList results; + ArrayList results; /** * A collection of {@link TableResults} which include additional information about the entities returned by an * operation. */ - protected ArrayList tableResults; + ArrayList tableResults; /** * Constructs an {@link ODataPayload} instance with new empty entity and {@link TableResult} collections. */ - protected ODataPayload() { + ODataPayload() { this.results = new ArrayList(); this.tableResults = new ArrayList(); } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/ODataUtilities.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/ODataUtilities.java similarity index 97% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/ODataUtilities.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/ODataUtilities.java index 93edf3259e401..e5a3e36055f9c 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/ODataUtilities.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/ODataUtilities.java @@ -13,19 +13,19 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.io.IOException; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; -import com.microsoft.windowsazure.storage.core.SR; +import com.microsoft.azure.storage.core.SR; /*** * RESERVED FOR INTERNAL USE. A class to hold utility methods for parsing OData payloads */ -public final class ODataUtilities { +final class ODataUtilities { /*** * Reserved for internal use. Asserts that the current name of the parser equals the expected value * diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/PropertyPair.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/PropertyPair.java similarity index 98% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/PropertyPair.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/PropertyPair.java index 7f0ad965b4f2b..58573c766de77 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/PropertyPair.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/PropertyPair.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -21,14 +21,14 @@ import java.util.HashMap; import java.util.Map.Entry; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.Utility; /** * Reserved for internal use. A class used internally during the reflection process to determine which properties should * be serialized. */ -class PropertyPair { +final class PropertyPair { /** * Reserved for internal use. A static factory method to generate a map of property names to {@link PropertyPair} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/QueryTableOperation.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/QueryTableOperation.java similarity index 89% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/QueryTableOperation.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/QueryTableOperation.java index 5c091ebb08ea8..e213094d0d797 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/QueryTableOperation.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/QueryTableOperation.java @@ -13,23 +13,22 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; -import java.text.ParseException; import javax.xml.stream.XMLStreamException; import com.fasterxml.jackson.core.JsonParseException; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.core.ExecutionEngine; -import com.microsoft.windowsazure.storage.core.RequestLocationMode; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.StorageRequest; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.core.ExecutionEngine; +import com.microsoft.azure.storage.core.RequestLocationMode; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.StorageRequest; +import com.microsoft.azure.storage.core.Utility; /** * A class that extends {@link TableOperation} to implement a query to retrieve a single table entity. To execute a @@ -129,8 +128,6 @@ protected Class getClazzType() { * * @throws XMLStreamException * if an error occurs accessing the {@link InputStream} with AtomPub. - * @throws ParseException - * if an error occurs in parsing the response. * @throws InstantiationException * if an error occurs in object construction. * @throws IllegalAccessException @@ -145,10 +142,9 @@ protected Class getClazzType() { @Override protected TableResult parseResponse(final InputStream inStream, final int httpStatusCode, String etagFromHeader, final OperationContext opContext, final TableRequestOptions options) throws XMLStreamException, - ParseException, InstantiationException, IllegalAccessException, StorageException, JsonParseException, - IOException { - TableResult res = TableDeserializer.parseSingleOpResponse(inStream, options, httpStatusCode, this.getClazzType(), - this.getResolver(), opContext); + InstantiationException, IllegalAccessException, StorageException, JsonParseException, IOException { + TableResult res = TableDeserializer.parseSingleOpResponse(inStream, options, httpStatusCode, + this.getClazzType(), this.getResolver(), opContext); res.setEtag(etagFromHeader); return res; } @@ -185,8 +181,7 @@ protected TableResult performRetrieve(final CloudTableClient client, final Strin } private StorageRequest retrieveImpl( - final CloudTableClient client, final String tableName, final TableRequestOptions options) - throws StorageException { + final CloudTableClient client, final String tableName, final TableRequestOptions options) { final boolean isTableEntry = TableConstants.TABLES_SERVICE_TABLES_NAME.equals(tableName); if (this.getClazzType() != null) { Utility.checkNullaryCtor(this.getClazzType()); @@ -207,10 +202,10 @@ public void setRequestLocationMode() { @Override public HttpURLConnection buildRequest(CloudTableClient client, QueryTableOperation operation, OperationContext context) throws Exception { - return TableRequest.query(client.getTransformedEndPoint(context).getUri(this.getCurrentLocation()), - tableName, generateRequestIdentity(isTableEntry, operation.getPartitionKey(), false), - options.getTimeoutIntervalInMs(), null/* Query Builder */, null/* Continuation Token */, - options, context); + return TableRequest + .query(client.getTransformedEndPoint(context).getUri(this.getCurrentLocation()), options, + null/* Query Builder */, context, tableName, + generateRequestIdentity(isTableEntry, operation.getPartitionKey(), false), null/* Continuation Token */); } @Override diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/SharedAccessTablePermissions.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/SharedAccessTablePermissions.java similarity index 97% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/SharedAccessTablePermissions.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/SharedAccessTablePermissions.java index e3c8412eb53b1..e09c7f44ff584 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/SharedAccessTablePermissions.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/SharedAccessTablePermissions.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.util.EnumSet; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/SharedAccessTablePolicy.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/SharedAccessTablePolicy.java similarity index 61% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/SharedAccessTablePolicy.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/SharedAccessTablePolicy.java index 885369b46230f..0b2964891bc82 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/SharedAccessTablePolicy.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/SharedAccessTablePolicy.java @@ -12,108 +12,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.util.EnumSet; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.SharedAccessPolicy; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.SharedAccessPolicy; +import com.microsoft.azure.storage.core.SR; /** * Represents a shared access policy, which specifies the start time, expiry time, and permissions for a shared access * signature. */ public final class SharedAccessTablePolicy extends SharedAccessPolicy { - - /** - * Assigns shared access permissions using the specified permissions string. - * - * @param value - * A String that represents the shared access permissions. The string must contain one or - * more of the following values. Note that they must be lower case, and the order that they are specified - * must be in the order of "raud". - *

    - *
  • r: Query access.
  • - *
  • a: Add access.
  • - *
  • u: Update access.
  • - *
  • d: Delete access.
  • - *
- * - * @return A java.util.EnumSet object that contains {@link SharedAccessTablePermissions} values that - * represents the set of shared access permissions. - * - * @deprecated As of release 0.6.0, replaced by the instance method - * {@link SharedAccessTablePolicy#setPermissions(EnumSet)}. - */ - @Deprecated - public static EnumSet permissionsFromString(final String value) { - final char[] chars = value.toCharArray(); - final EnumSet retSet = EnumSet.noneOf(SharedAccessTablePermissions.class); - - for (final char c : chars) { - switch (c) { - case 'r': - retSet.add(SharedAccessTablePermissions.QUERY); - break; - case 'a': - retSet.add(SharedAccessTablePermissions.ADD); - break; - case 'u': - retSet.add(SharedAccessTablePermissions.UPDATE); - break; - case 'd': - retSet.add(SharedAccessTablePermissions.DELETE); - break; - default: - throw new IllegalArgumentException(String.format(SR.PERMISSIONS_COULD_NOT_BE_PARSED, value)); - } - } - - return retSet; - } - - /** - * - * Converts the permissions specified for the shared access policy to a string. - * - * @param permissions - * A set of {@link SharedAccessTablePermissions} objects that represent the shared access permissions. - * - * @return A String that represents the shared access permissions in the "raud" format, which is - * described at {@link SharedAccessTablePolicy#permissionsFromString(String)}. - * - * @deprecated As of release 0.6.0, replaced by the instance method - * {@link SharedAccessTablePolicy#permissionsToString()}. - */ - @Deprecated - public static String permissionsToString(final EnumSet permissions) { - if (permissions == null) { - return Constants.EMPTY_STRING; - } - - // The service supports a fixed order => rwdl - final StringBuilder builder = new StringBuilder(); - - if (permissions.contains(SharedAccessTablePermissions.QUERY)) { - builder.append("r"); - } - - if (permissions.contains(SharedAccessTablePermissions.ADD)) { - builder.append("a"); - } - - if (permissions.contains(SharedAccessTablePermissions.UPDATE)) { - builder.append("u"); - } - - if (permissions.contains(SharedAccessTablePermissions.DELETE)) { - builder.append("d"); - } - - return builder.toString(); - } - /** * The permissions for a shared access signature associated with this shared access policy. */ @@ -148,7 +59,30 @@ public void setPermissions(final EnumSet permissio */ @Override public String permissionsToString() { - return SharedAccessTablePolicy.permissionsToString(this.permissions); + if (this.permissions == null) { + return Constants.EMPTY_STRING; + } + + // The service supports a fixed order => raud + final StringBuilder builder = new StringBuilder(); + + if (this.permissions.contains(SharedAccessTablePermissions.QUERY)) { + builder.append("r"); + } + + if (this.permissions.contains(SharedAccessTablePermissions.ADD)) { + builder.append("a"); + } + + if (this.permissions.contains(SharedAccessTablePermissions.UPDATE)) { + builder.append("u"); + } + + if (this.permissions.contains(SharedAccessTablePermissions.DELETE)) { + builder.append("d"); + } + + return builder.toString(); } /** @@ -167,6 +101,28 @@ public String permissionsToString() { */ @Override public void setPermissionsFromString(final String value) { - this.permissions = SharedAccessTablePolicy.permissionsFromString(value); + final char[] chars = value.toCharArray(); + final EnumSet retSet = EnumSet.noneOf(SharedAccessTablePermissions.class); + + for (final char c : chars) { + switch (c) { + case 'r': + retSet.add(SharedAccessTablePermissions.QUERY); + break; + case 'a': + retSet.add(SharedAccessTablePermissions.ADD); + break; + case 'u': + retSet.add(SharedAccessTablePermissions.UPDATE); + break; + case 'd': + retSet.add(SharedAccessTablePermissions.DELETE); + break; + default: + throw new IllegalArgumentException(String.format(SR.PERMISSIONS_COULD_NOT_BE_PARSED, value)); + } + } + + this.permissions = retSet; } } diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/StoreAs.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/StoreAs.java similarity index 97% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/StoreAs.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/StoreAs.java index 68042fc3dd45f..5493d19d9dca6 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/StoreAs.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/StoreAs.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableBatchOperation.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableBatchOperation.java similarity index 96% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableBatchOperation.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableBatchOperation.java index f2ff0c442ccc3..9b8a69826e989 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableBatchOperation.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableBatchOperation.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -27,20 +27,20 @@ import javax.xml.stream.XMLStreamException; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageErrorCodeStrings; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.core.ExecutionEngine; -import com.microsoft.windowsazure.storage.core.RequestLocationMode; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.StorageRequest; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.StorageErrorCodeStrings; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.core.ExecutionEngine; +import com.microsoft.azure.storage.core.RequestLocationMode; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.StorageRequest; +import com.microsoft.azure.storage.core.Utility; /** * A class which represents a batch operation. A batch operation is a collection of table operations which are executed * by the Storage Service REST API as a single atomic operation, by invoking an Entity Group Transaction. + * href="http://msdn.microsoft.com/en-us/library/azure/dd894038.aspx">Entity Group Transaction. *

* A batch operation may contain up to 100 individual table operations, with the requirement that each operation entity * must have same partition key. A batch with a retrieve operation cannot contain any other operations. Note that the @@ -443,7 +443,7 @@ public HttpURLConnection buildRequest(CloudTableClient client, TableBatchOperati this.setSendStream(new ByteArrayInputStream(batchBytes)); this.setLength((long) batchBytes.length); return TableRequest.batch(client.getTransformedEndPoint(context).getUri(this.getCurrentLocation()), - options.getTimeoutIntervalInMs(), batchID, null, options, context); + options, null, context, batchID); } @Override diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableConstants.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableConstants.java similarity index 93% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableConstants.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableConstants.java index 002d586ecb668..ae4613357586f 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableConstants.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableConstants.java @@ -13,12 +13,12 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; /** - * Holds the constants used for the Table Service. + * RESERVED FOR INTERNAL USE. Holds the constants used for the Table Service. */ -public final class TableConstants { +final class TableConstants { public static class ErrorConstants { /** * XML element for error codes. @@ -151,11 +151,6 @@ public static class HeaderConstants { */ public static final String RETURN_NO_CONTENT = "return-no-content"; - /** - * The prefix of the server header value received which indicates the table server was accessed - */ - public static final String TABLE_SERVER = "Windows-Azure-Table"; - /** * The x-http-method header to send for batch operations. */ @@ -188,11 +183,6 @@ public static class HeaderConstants { */ public static final String SELECT = "$select"; - /** - * Default client side timeout, in milliseconds, for table clients. - */ - public static final int TABLE_DEFAULT_TIMEOUT_IN_MS = 60 * 1000; - /** * The name of the property that stores the table name. */ diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableDeserializer.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableDeserializer.java similarity index 93% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableDeserializer.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableDeserializer.java index 15b634ba7d75d..4de67167f9203 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableDeserializer.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableDeserializer.java @@ -13,13 +13,12 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; -import java.text.ParseException; import java.util.Date; import java.util.HashMap; import java.util.Map.Entry; @@ -32,17 +31,16 @@ import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageErrorCodeStrings; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.core.DeserializationHelper; -import com.microsoft.windowsazure.storage.core.SR; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.StorageErrorCodeStrings; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.core.SR; /** * Reserved for internal use. A class used to read Table entities. */ -class TableDeserializer { +final class TableDeserializer { /** * Used to create Json parsers and generators. @@ -76,8 +74,6 @@ class TableDeserializer { * if an error occurs in reflection while parsing the result. * @throws XMLStreamException * if an error occurs while accessing the stream with AtomPub. - * @throws ParseException - * if an error occurs while parsing the stream. * @throws StorageException * if a storage service error occurs. * @throws IOException @@ -85,10 +81,11 @@ class TableDeserializer { * @throws JsonParseException * if an error occurs while parsing the stream. */ - protected static ODataPayload parseQueryResponse(final InputStream inStream, + @SuppressWarnings("deprecation") + static ODataPayload parseQueryResponse(final InputStream inStream, final TableRequestOptions options, final Class clazzType, final EntityResolver resolver, final OperationContext opContext) throws InstantiationException, IllegalAccessException, - XMLStreamException, ParseException, StorageException, JsonParseException, IOException { + XMLStreamException, StorageException, JsonParseException, IOException { ODataPayload payload; if (options.getTablePayloadFormat() == TablePayloadFormat.AtomPub) { payload = parseAtomQueryResponse(inStream, clazzType, resolver, opContext); @@ -127,8 +124,6 @@ protected static ODataPayload parseQueryResponse(f * if an error occurs in reflection while parsing the result. * @throws XMLStreamException * if an error occurs while accessing the stream with AtomPub. - * @throws ParseException - * if an error occurs while parsing the stream. * @throws StorageException * if a storage service error occurs. * @throws IOException @@ -136,11 +131,11 @@ protected static ODataPayload parseQueryResponse(f * @throws JsonParseException * if an error occurs while parsing the stream. */ - protected static TableResult parseSingleOpResponse(final InputStream inStream, + @SuppressWarnings("deprecation") + static TableResult parseSingleOpResponse(final InputStream inStream, final TableRequestOptions options, final int httpStatusCode, final Class clazzType, final EntityResolver resolver, final OperationContext opContext) throws InstantiationException, - IllegalAccessException, XMLStreamException, ParseException, StorageException, IOException, - JsonParseException { + IllegalAccessException, XMLStreamException, StorageException, IOException, JsonParseException { TableResult res; if (options.getTablePayloadFormat() == TablePayloadFormat.AtomPub) { res = parseSingleOpAtomResponse(inStream, httpStatusCode, clazzType, resolver, opContext); @@ -171,8 +166,6 @@ protected static TableResult parseSingleOpResponse(fi * A {@link TableResult} containing the parsed entity result of the operation. * @throws IOException * if an error occurs while accessing the stream. - * @throws ParseException - * if an error occurs while parsing the stream. * @throws InstantiationException * if an error occurs while constructing the result. * @throws IllegalAccessException @@ -187,7 +180,7 @@ protected static TableResult parseSingleOpResponse(fi private static TableResult parseJsonEntity(final JsonParser parser, final Class clazzType, HashMap classProperties, final EntityResolver resolver, final TableRequestOptions options, final OperationContext opContext) throws JsonParseException, - IOException, ParseException, StorageException, InstantiationException, IllegalAccessException { + IOException, StorageException, InstantiationException, IllegalAccessException { final TableResult res = new TableResult(); final HashMap properties = new HashMap(); @@ -364,8 +357,6 @@ else if (clazzType != null) { * @return * An {@link ODataPayload} containing a collection of {@link TableResult} objects with the parsed operation * response. - * @throws ParseException - * if an error occurs while parsing the stream. * @throws InstantiationException * if an error occurs while constructing the result. * @throws IllegalAccessException @@ -380,8 +371,8 @@ else if (clazzType != null) { @SuppressWarnings("unchecked") private static ODataPayload parseJsonQueryResponse(final InputStream inStream, final Class clazzType, final EntityResolver resolver, final TableRequestOptions options, - final OperationContext opContext) throws ParseException, InstantiationException, IllegalAccessException, - StorageException, JsonParseException, IOException { + final OperationContext opContext) throws InstantiationException, IllegalAccessException, StorageException, + JsonParseException, IOException { ODataPayload corePayload = null; ODataPayload resolvedPayload = null; ODataPayload commonPayload = null; @@ -476,8 +467,6 @@ private static ODataPayload parseJsonQueryResponse * An {@link OperationContext} object used to track the execution of the operation. * @return * A {@link TableResult} object with the parsed operation response. - * @throws ParseException - * if an error occurs while parsing the stream. * @throws InstantiationException * if an error occurs while constructing the result. * @throws IllegalAccessException @@ -491,8 +480,8 @@ private static ODataPayload parseJsonQueryResponse */ private static TableResult parseSingleOpJsonResponse(final InputStream inStream, final int httpStatusCode, final Class clazzType, final EntityResolver resolver, - final TableRequestOptions options, final OperationContext opContext) throws ParseException, - InstantiationException, IllegalAccessException, StorageException, JsonParseException, IOException { + final TableRequestOptions options, final OperationContext opContext) throws InstantiationException, + IllegalAccessException, StorageException, JsonParseException, IOException { JsonParser parser = createJsonParserFromStream(inStream); try { @@ -527,8 +516,6 @@ private static TableResult parseSingleOpJsonResponse( * * @throws XMLStreamException * if an error occurs while accessing the stream. - * @throws ParseException - * if an error occurs while parsing the stream. * @throws InstantiationException * if an error occurs while constructing the result. * @throws IllegalAccessException @@ -538,7 +525,7 @@ private static TableResult parseSingleOpJsonResponse( */ private static TableResult parseAtomEntity(final XMLStreamReader xmlr, final Class clazzType, final EntityResolver resolver, final OperationContext opContext) - throws XMLStreamException, ParseException, InstantiationException, IllegalAccessException, StorageException { + throws XMLStreamException, InstantiationException, IllegalAccessException, StorageException { int eventType = xmlr.getEventType(); final TableResult res = new TableResult(); @@ -652,8 +639,6 @@ else if (clazzType != null) { * * @throws XMLStreamException * if an error occurs while accessing the stream. - * @throws ParseException - * if an error occurs while parsing the stream. * @throws InstantiationException * if an error occurs while constructing the result. * @throws IllegalAccessException @@ -664,7 +649,7 @@ else if (clazzType != null) { @SuppressWarnings("unchecked") private static ODataPayload parseAtomQueryResponse(final InputStream inStream, final Class clazzType, final EntityResolver resolver, final OperationContext opContext) - throws XMLStreamException, ParseException, InstantiationException, IllegalAccessException, StorageException { + throws XMLStreamException, InstantiationException, IllegalAccessException, StorageException { ODataPayload corePayload = null; ODataPayload resolvedPayload = null; ODataPayload commonPayload = null; @@ -745,8 +730,6 @@ else if (eventType == XMLStreamConstants.END_ELEMENT * * @throws XMLStreamException * if an error occurs while accessing the stream. - * @throws ParseException - * if an error occurs while parsing the stream. * @throws InstantiationException * if an error occurs while constructing the result. * @throws IllegalAccessException @@ -756,7 +739,7 @@ else if (eventType == XMLStreamConstants.END_ELEMENT */ private static TableResult parseSingleOpAtomResponse(final InputStream inStream, final int httpStatusCode, final Class clazzType, final EntityResolver resolver, - final OperationContext opContext) throws XMLStreamException, ParseException, InstantiationException, + final OperationContext opContext) throws XMLStreamException, InstantiationException, IllegalAccessException, StorageException { XMLStreamReader xmlr = DeserializationHelper.createXMLStreamReaderFromStream(inStream); @@ -788,11 +771,9 @@ private static TableResult parseSingleOpAtomResponse( * {@link EntityProperty} data typed values found in the entity data. * @throws XMLStreamException * if an error occurs accessing the stream. - * @throws ParseException - * if an error occurs converting the input to a particular data type. */ private static HashMap readAtomProperties(final XMLStreamReader xmlr, - final OperationContext opContext) throws XMLStreamException, ParseException { + final OperationContext opContext) throws XMLStreamException { int eventType = xmlr.getEventType(); xmlr.require(XMLStreamConstants.START_ELEMENT, null, ODataConstants.PROPERTIES); final HashMap properties = new HashMap(); @@ -846,7 +827,7 @@ private static String getETagFromTimestamp(String timestampString) throws Unsupp return "W/\"datetime'" + timestampString + "'\""; } - private static EdmType evaluateEdmType(JsonToken token, String value) throws JsonParseException, IOException { + private static EdmType evaluateEdmType(JsonToken token, String value) { EdmType edmType = null; if (token == JsonToken.VALUE_NULL) { diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableEntity.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableEntity.java similarity index 97% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableEntity.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableEntity.java index f984fb24d9190..4ae56c21ca8d6 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableEntity.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableEntity.java @@ -13,13 +13,13 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.util.Date; import java.util.HashMap; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageException; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.StorageException; /** * An interface required for table entity types. The {@link TableEntity} interface declares getter and setter methods @@ -75,7 +75,7 @@ public interface TableEntity { /** * Gets the Etag value for the entity. This value is used to determine if the table entity has changed since it was - * last read from Windows Azure storage. + * last read from Microsoft Azure storage. * * @return * A String containing the Etag for the entity. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableEntitySerializer.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableEntitySerializer.java similarity index 97% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableEntitySerializer.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableEntitySerializer.java index 61b5d84921ee8..91f4063101873 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableEntitySerializer.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableEntitySerializer.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.io.IOException; import java.io.OutputStream; @@ -28,15 +28,15 @@ import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.JsonGenerator; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.core.Utility; /** * RESERVED FOR INTERNAL USE. A class used to serialize table entities to a byte array. */ -public class TableEntitySerializer { +final class TableEntitySerializer { /** * Used to create Json parsers and generators. */ @@ -63,7 +63,8 @@ public class TableEntitySerializer { * @throws IOException * if an error occurs while accessing the stream with Json. */ - protected static void writeSingleEntityToStream(final OutputStream outStream, final TablePayloadFormat format, + @SuppressWarnings("deprecation") + static void writeSingleEntityToStream(final OutputStream outStream, final TablePayloadFormat format, final TableEntity entity, final boolean isTableEntry, final OperationContext opContext) throws XMLStreamException, StorageException, IOException { if (format == TablePayloadFormat.AtomPub) { @@ -95,7 +96,8 @@ protected static void writeSingleEntityToStream(final OutputStream outStream, fi * @throws IOException * if an error occurs while accessing the stream with Json. */ - protected static void writeSingleEntityToString(final StringWriter strWriter, final TablePayloadFormat format, + @SuppressWarnings("deprecation") + static void writeSingleEntityToString(final StringWriter strWriter, final TablePayloadFormat format, final TableEntity entity, final boolean isTableEntry, final OperationContext opContext) throws XMLStreamException, StorageException, IOException { if (format == TablePayloadFormat.AtomPub) { diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableOperation.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableOperation.java similarity index 94% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableOperation.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableOperation.java index 9d129ecd14f88..b1cc06d364fff 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableOperation.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableOperation.java @@ -13,25 +13,24 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; -import java.text.ParseException; import javax.xml.stream.XMLStreamException; import com.fasterxml.jackson.core.JsonParseException; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.core.ExecutionEngine; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.StorageRequest; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.core.ExecutionEngine; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.StorageRequest; +import com.microsoft.azure.storage.core.Utility; /** * A class which represents a single table operation. @@ -45,7 +44,7 @@ */ public class TableOperation { /** - * A static factory method returning a {@link TableOperation} instance to delete the specified entity from Windows + * A static factory method returning a {@link TableOperation} instance to delete the specified entity from Microsoft * Azure storage. To execute this {@link TableOperation} on a given table, call the * {@link CloudTableClient#execute(String, TableOperation)} method on a {@link CloudTableClient} instance with the * table name and the {@link TableOperation} as arguments. @@ -62,8 +61,8 @@ public static TableOperation delete(final TableEntity entity) { } /** - * A static factory method returning a {@link TableOperation} instance to insert the specified entity into Windows - * Azure storage. To execute this {@link TableOperation} on a given table, call the + * A static factory method returning a {@link TableOperation} instance to insert the specified entity into + * Microsoft Azure storage. To execute this {@link TableOperation} on a given table, call the * {@link CloudTableClient#execute(String, TableOperation)} method on a {@link CloudTableClient} instance with the * table name and the {@link TableOperation} as arguments. * @@ -77,8 +76,8 @@ public static TableOperation insert(final TableEntity entity) { } /** - * A static factory method returning a {@link TableOperation} instance to insert the specified entity into Windows - * Azure storage. To execute this {@link TableOperation} on a given table, call the + * A static factory method returning a {@link TableOperation} instance to insert the specified entity into + * Microsoft Azure storage. To execute this {@link TableOperation} on a given table, call the * {@link CloudTableClient#execute(String, TableOperation)} method on a {@link CloudTableClient} instance with the * table name and the {@link TableOperation} as arguments. * @@ -95,8 +94,9 @@ public static TableOperation insert(final TableEntity entity, boolean echoConten } /** - * A static factory method returning a {@link TableOperation} instance to merge the specified entity into Windows - * Azure storage, or insert it if it does not exist. To execute this {@link TableOperation} on a given table, call + * A static factory method returning a {@link TableOperation} instance to merge the specified entity into + * Microsoft Azure storage, or insert it if it does not exist. To execute this {@link TableOperation} on a given + * table, call * the {@link CloudTableClient#execute(String, TableOperation)} method on a {@link CloudTableClient} instance with * the table name and the {@link TableOperation} as arguments. * @@ -111,8 +111,9 @@ public static TableOperation insertOrMerge(final TableEntity entity) { } /** - * A static factory method returning a {@link TableOperation} instance to replace the specified entity in Windows - * Azure storage, or insert it if it does not exist. To execute this {@link TableOperation} on a given table, call + * A static factory method returning a {@link TableOperation} instance to replace the specified entity in + * Microsoft Azure storage, or insert it if it does not exist. To execute this {@link TableOperation} on a given + * table, call * the {@link CloudTableClient#execute(String, TableOperation)} method on a {@link CloudTableClient} instance with * the table name and the {@link TableOperation} as arguments. * @@ -128,7 +129,7 @@ public static TableOperation insertOrReplace(final TableEntity entity) { /** * A static factory method returning a {@link TableOperation} instance to merge the specified table entity into - * Windows Azure storage. To execute this {@link TableOperation} on a given table, call the + * Microsoft Azure storage. To execute this {@link TableOperation} on a given table, call the * {@link CloudTableClient#execute(String, TableOperation)} method on a {@link CloudTableClient} instance with the * table name and the {@link TableOperation} as arguments. * @@ -259,7 +260,7 @@ protected TableOperation(final TableEntity entity, final TableOperationType opTy * Reserved for internal use. Performs a delete operation on the specified table, using the specified * {@link TableRequestOptions} and {@link OperationContext}. *

- * This method will invoke the Delete + * This method will invoke the Delete * Entity REST API to execute this table operation, using the Table service endpoint and storage account * credentials in the {@link CloudTableClient} object. * @@ -307,8 +308,8 @@ private StorageRequest deleteImpl public HttpURLConnection buildRequest(CloudTableClient client, TableOperation operation, OperationContext context) throws Exception { return TableRequest.delete(client.getTransformedEndPoint(context).getUri(this.getCurrentLocation()), - tableName, generateRequestIdentity(isTableEntry, tableIdentity, false), operation.getEntity() - .getEtag(), options.getTimeoutIntervalInMs(), null, options, context); + options, null, context, tableName, generateRequestIdentity(isTableEntry, tableIdentity, false), + operation.getEntity().getEtag()); } @Override @@ -400,11 +401,10 @@ public HttpURLConnection buildRequest(CloudTableClient client, TableOperation op this.setSendStream(new ByteArrayInputStream(entityBytes)); this.setLength((long) entityBytes.length); return TableRequest.insert( - client.getTransformedEndPoint(opContext).getUri(this.getCurrentLocation()), tableName, - generateRequestIdentity(isTableEntry, tableIdentity, false), + client.getTransformedEndPoint(opContext).getUri(this.getCurrentLocation()), options, null, + opContext, tableName, generateRequestIdentity(isTableEntry, tableIdentity, false), operation.opType != TableOperationType.INSERT ? operation.getEntity().getEtag() : null, - operation.getEchoContent(), operation.opType.getUpdateType(), - options.getTimeoutIntervalInMs(), null, options, opContext); + operation.getEchoContent(), operation.opType.getUpdateType()); } @Override @@ -548,10 +548,9 @@ public HttpURLConnection buildRequest(CloudTableClient client, TableOperation op OperationContext context) throws Exception { this.setSendStream(new ByteArrayInputStream(entityBytes)); this.setLength((long) entityBytes.length); - return TableRequest - .merge(client.getTransformedEndPoint(opContext).getUri(this.getCurrentLocation()), - tableName, generateRequestIdentity(false, null, false), operation.getEntity() - .getEtag(), options.getTimeoutIntervalInMs(), null, options, opContext); + return TableRequest.merge(client.getTransformedEndPoint(opContext) + .getUri(this.getCurrentLocation()), options, null, opContext, tableName, + generateRequestIdentity(false, null, false), operation.getEntity().getEtag()); } @Override @@ -650,9 +649,9 @@ public HttpURLConnection buildRequest(CloudTableClient client, TableOperation op this.setSendStream(new ByteArrayInputStream(entityBytes)); this.setLength((long) entityBytes.length); return TableRequest.update( - client.getTransformedEndPoint(context).getUri(this.getCurrentLocation()), tableName, - generateRequestIdentity(false, null, false), operation.getEntity().getEtag(), - options.getTimeoutIntervalInMs(), null, options, context); + client.getTransformedEndPoint(context).getUri(this.getCurrentLocation()), options, null, + context, tableName, generateRequestIdentity(false, null, false), operation.getEntity() + .getEtag()); } @Override @@ -849,8 +848,6 @@ protected synchronized final TableOperationType getOperationType() { * * @throws XMLStreamException * if an error occurs accessing the {@link InputStream} with AtomPub. - * @throws ParseException - * if an error occurs in parsing the response. * @throws InstantiationException * if an error occurs in object construction. * @throws IllegalAccessException @@ -864,8 +861,7 @@ protected synchronized final TableOperationType getOperationType() { */ protected TableResult parseResponse(final InputStream inStream, final int httpStatusCode, String etagFromHeader, final OperationContext opContext, final TableRequestOptions options) throws XMLStreamException, - ParseException, InstantiationException, IllegalAccessException, StorageException, JsonParseException, - IOException { + InstantiationException, IllegalAccessException, StorageException, JsonParseException, IOException { TableResult resObj; if (this.opType == TableOperationType.INSERT && this.echoContent) { diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableOperationType.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableOperationType.java similarity index 97% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableOperationType.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableOperationType.java index 6c4c1fb1a6c55..ff11066f46b2c 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableOperationType.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableOperationType.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; /** * Reserved for internal use. An enumeration type which represents the type of operation a {@link TableOperation} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TablePayloadFormat.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TablePayloadFormat.java similarity index 87% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TablePayloadFormat.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/TablePayloadFormat.java index 5bf5f7ca40623..6b246c8105b06 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TablePayloadFormat.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TablePayloadFormat.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; /** * Describes the payload formats supported for Tables. @@ -22,7 +22,10 @@ public enum TablePayloadFormat { /** * Use AtomPub. + * + * @Deprecated Deprecated as of 0.7.0 in favor of Json format. */ + @Deprecated AtomPub, /** diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TablePermissions.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TablePermissions.java similarity index 86% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TablePermissions.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/TablePermissions.java index 31fdb293f1d2c..a4cba85717b7a 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TablePermissions.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TablePermissions.java @@ -13,9 +13,9 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; -import com.microsoft.windowsazure.storage.core.Permissions; +import com.microsoft.azure.storage.Permissions; /** * Represents the permissions for a table. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableQuery.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableQuery.java similarity index 87% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableQuery.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableQuery.java index 0666b2e05edb2..3d3dde5ca878b 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableQuery.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableQuery.java @@ -13,17 +13,17 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.util.Date; import java.util.Formatter; import java.util.UUID; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.UriQueryBuilder; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.core.SR; +import com.microsoft.azure.storage.core.UriQueryBuilder; +import com.microsoft.azure.storage.core.Utility; /** * A class which represents a query against a specified table. A {@link TableQuery} instance aggregates the query @@ -60,14 +60,13 @@ * constant. The PartitionKey and RowKey property values are String types for comparison purposes. *

* The values that may be used in table queries are explained in more detail in the MSDN topic Querying Tables and Entities, but note - * that the space characters within values do not need to be URL-encoded, as this will be done when the query is - * executed. + * href="http://msdn.microsoft.com/en-us/library/azure/dd894031.aspx">Querying Tables and Entities, but note that + * the space characters within values do not need to be URL-encoded, as this will be done when the query is executed. *

- * The {@link TableQuery#TableQuery(String, Class)} constructor and {@link TableQuery#from(String, Class)} static - * factory methods require a class type which implements {@link TableEntity} and contains a nullary constructor. If the - * query will be executed using an {@link EntityResolver}, the caller may specify {@link TableServiceEntity} - * .class as the class type. + * The {@link TableQuery#TableQuery(Class)} constructor and {@link TableQuery#from(Class)} static factory methods + * require a class type which implements {@link TableEntity} and contains a nullary constructor. If the query will be + * executed using an {@link EntityResolver}, the caller may specify {@link TableServiceEntity} .class as + * the class type. * * @param * A class type which implements {@link TableEntity} and contains a nullary constructor. Note: when using an @@ -150,33 +149,6 @@ public static TableQuery from(final Class clazzTyp return new TableQuery(clazzType); } - /** - * A static factory method that constructs a {@link TableQuery} instance and defines its source table and - * table entity type. The method returns the {@link TableQuery} instance reference, allowing additional methods to - * be chained to modify the query. - *

- * The created {@link TableQuery} instance is specialized for table entities of the specified class type T, using - * the table with the specified name as data source. Callers may specify {@link TableServiceEntity} - * .class as the class type parameter if no more specialized type is required. - * - * @param tablename - * A String containing the name of the source table to query. - * @param clazzType - * The java.lang.Class of the class T implementing the {@link TableEntity} - * interface that - * represents the table entity type for the query. - * - * @return - * The {@link TableQuery} instance with the source table name and entity type specialization set. - * - * @deprecated As of release 0.6.0, replaced by {link {@link TableQuery#from(Class)} as execute should now be called - * from {@link CloudTable} rather than {@link CloudTableClient} - */ - @Deprecated - public static TableQuery from(final String tablename, final Class clazzType) { - return new TableQuery(tablename, clazzType); - } - /** * Generates a property filter condition string for a boolean value. Creates a formatted string to use * in a filter expression that uses the specified operation to compare the property with the value, formatted as a @@ -369,11 +341,11 @@ public static String generateFilterCondition(String propertyName, String operati * in a filter expression that uses the specified operation to compare the property with the value, formatted as * a string value, as in the following example: *

- * String condition = generateFilterCondition("Platform", QueryComparisons.EQUAL, "Windows Azure"); + * String condition = generateFilterCondition("Platform", QueryComparisons.EQUAL, "Azure"); *

* This statement sets condition to the following value: *

- * Platform eq 'Windows Azure' + * Platform eq 'Azure' * * @param propertyName * A String containing the name of the property to compare. @@ -497,28 +469,6 @@ public TableQuery(final Class clazzType) { this.setClazzType(clazzType); } - /** - * - * Initializes a {@link TableQuery} with the specified source table and table entity type. Callers may specify - * {@link TableServiceEntity}.class as the class type parameter if no more specialized type is - * required. - * - * @param tableName - * A String containing the name of the source table to query. - * @param clazzType - * The java.lang.Class of the class T that represents the table entity type for - * the query. Class T must be a type that implements {@link TableEntity} and has a nullary - * constructor. - * - * @deprecated As of release 0.6.0, replaced by replaced by {link {@link TableQuery#TableQuery(Class)} as execute - * should now be called from {@link CloudTable} rather than {@link CloudTableClient} - */ - @Deprecated - public TableQuery(final String tableName, final Class clazzType) { - this.setSourceTableName(tableName); - this.setClazzType(clazzType); - } - /** * Gets the class type of the table entities returned by the query. * @@ -554,7 +504,9 @@ public String[] getColumns() { * The java.lang.Class of the class T implementing the {@link TableEntity} * interface that * represents the table entity type for the query. + * @deprecated Deprecated as of 0.7.0. Please use getClazzType() instead. */ + @Deprecated public Class getEntityClass() { return this.clazzType; } @@ -576,12 +528,8 @@ public String getFilterString() { * * @return * A String containing the name of the source table used in the query. - * - * @deprecated As of release 0.6.0, removed as execute should now be called from {@link CloudTable} rather than - * {@link CloudTableClient} meaning table name will not be set on the {@link TableQuery} itself. */ - @Deprecated - public String getSourceTableName() { + protected String getSourceTableName() { return this.sourceTableName; } @@ -668,9 +616,9 @@ public void setColumns(final String[] columns) { *

* The values that may be used in table queries are explained in more detail in the MSDN topic * - * Querying Tables and Entities, - * but note that the space characters within values do not need to be URL-encoded, as this will be done when the - * query is executed. + * Querying Tables and Entities, but note + * that the space characters within values do not need to be URL-encoded, as this will be done when the query is + * executed. *

* Note that no more than 15 discrete comparisons are permitted within a filter string. * @@ -687,12 +635,8 @@ public void setFilterString(final String filterString) { * * @param sourceTableName * A String containing the name of the source table to use in the query. - * - * @deprecated As of release 0.6.0, removed as execute should now be called from {@link CloudTable} rather than - * {@link CloudTableClient} meaning table name will not be set on the {@link TableQuery} itself. */ - @Deprecated - public void setSourceTableName(final String sourceTableName) { + protected void setSourceTableName(final String sourceTableName) { Utility.assertNotNullOrEmpty("tableName", sourceTableName); this.sourceTableName = sourceTableName; } @@ -751,9 +695,9 @@ public TableQuery take(final Integer take) { *

* The values that may be used in table queries are explained in more detail in the MSDN topic * - * Querying Tables and Entities, - * but note that the space characters within values do not need to be URL-encoded, as this will be done when the - * query is executed. + * Querying Tables and Entities, but note + * that the space characters within values do not need to be URL-encoded, as this will be done when the query is + * executed. *

* Note that no more than 15 discrete comparisons are permitted within a filter string. * diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableRequest.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableRequest.java similarity index 81% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableRequest.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableRequest.java index d9f3595572677..5a4cc28adcc33 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableRequest.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableRequest.java @@ -13,21 +13,21 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URI; import java.net.URISyntaxException; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.ResultContinuation; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.core.BaseRequest; -import com.microsoft.windowsazure.storage.core.PathUtility; -import com.microsoft.windowsazure.storage.core.UriQueryBuilder; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.ResultContinuation; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.core.BaseRequest; +import com.microsoft.azure.storage.core.PathUtility; +import com.microsoft.azure.storage.core.UriQueryBuilder; +import com.microsoft.azure.storage.core.Utility; /** * Reserved for internal use. A class used to generate requests for Table objects. @@ -67,19 +67,16 @@ private static void applyContinuationToQueryBuilder(final UriQueryBuilder builde * * @param rootUri * A java.net.URI containing an absolute URI to the resource. - * @param timeoutInMs - * The server timeout interval in milliseconds. - * @param batchID - * The String containing the batch identifier. - * @param queryBuilder - * The {@link UriQueryBuilder} for the operation. * @param tableOptions * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout * settings for the operation. This parameter is unused. + * @param queryBuilder + * The {@link UriQueryBuilder} for the operation. * @param opContext * An {@link OperationContext} object for tracking the current operation. Specify null to * safely ignore operation context. - * + * @param batchID + * The String containing the batch identifier. * @return * An HttpURLConnection to use to perform the operation. * @@ -90,12 +87,12 @@ private static void applyContinuationToQueryBuilder(final UriQueryBuilder builde * @throws StorageException * if a storage service error occurred during the operation. */ - public static HttpURLConnection batch(final URI rootUri, final int timeoutInMs, final String batchID, - final UriQueryBuilder queryBuilder, final TableRequestOptions tableOptions, final OperationContext opContext) + public static HttpURLConnection batch(final URI rootUri, final TableRequestOptions tableOptions, + final UriQueryBuilder queryBuilder, final OperationContext opContext, final String batchID) throws IOException, URISyntaxException, StorageException { final URI queryUri = PathUtility.appendPathToSingleUri(rootUri, "$batch"); - final HttpURLConnection retConnection = BaseRequest.createURLConnection(queryUri, timeoutInMs, queryBuilder, + final HttpURLConnection retConnection = BaseRequest.createURLConnection(queryUri, tableOptions, queryBuilder, opContext); setAcceptHeaderForHttpWebRequest(retConnection, tableOptions.getTablePayloadFormat()); @@ -115,24 +112,21 @@ public static HttpURLConnection batch(final URI rootUri, final int timeoutInMs, * * @param rootUri * A java.net.URI containing an absolute URI to the resource. + * @param queryBuilder + * The UriQueryBuilder for the request. + * @param opContext + * An {@link OperationContext} object for tracking the current operation. * @param tableName * The name of the table. * @param identity * The identity of the entity, to pass in the Service Managment REST operation URI as * tableName(identity). If null, only the tableName * value will be passed. - * @param timeoutInMs - * The server timeout interval in milliseconds. - * @param queryBuilder - * The UriQueryBuilder for the request. * @param requestMethod * The HTTP request method to set. * @param options * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout * settings for the operation. This parameter is unused. - * @param opContext - * An {@link OperationContext} object for tracking the current operation. - * * @return * An HttpURLConnection to use to perform the operation. * @@ -143,10 +137,10 @@ public static HttpURLConnection batch(final URI rootUri, final int timeoutInMs, * @throws StorageException * if a storage service error occurred during the operation. */ - private static HttpURLConnection coreCreate(final URI rootUri, final String tableName, final String eTag, - final String identity, final int timeoutInMs, final UriQueryBuilder queryBuilder, - final String requestMethod, final TableRequestOptions tableOptions, final OperationContext opContext) - throws IOException, URISyntaxException, StorageException { + private static HttpURLConnection coreCreate(final URI rootUri, final TableRequestOptions tableOptions, + final UriQueryBuilder queryBuilder, final OperationContext opContext, final String tableName, + final String eTag, final String identity, final String requestMethod) throws IOException, + URISyntaxException, StorageException { URI queryUri = null; @@ -158,7 +152,7 @@ private static HttpURLConnection coreCreate(final URI rootUri, final String tabl queryUri = PathUtility.appendPathToSingleUri(rootUri, tableName); } - final HttpURLConnection retConnection = BaseRequest.createURLConnection(queryUri, timeoutInMs, queryBuilder, + final HttpURLConnection retConnection = BaseRequest.createURLConnection(queryUri, tableOptions, queryBuilder, opContext); setAcceptHeaderForHttpWebRequest(retConnection, tableOptions.getTablePayloadFormat()); @@ -180,6 +174,15 @@ private static HttpURLConnection coreCreate(final URI rootUri, final String tabl * * @param rootUri * A java.net.URI containing an absolute URI to the resource. + * @param tableOptions + * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudTableClient}. + * @param queryBuilder + * The {@link UriQueryBuilder} for the operation. + * @param opContext + * An {@link OperationContext} object for tracking the current operation. Specify null to + * safely ignore operation context. * @param tableName * The name of the table. * @param identity @@ -187,18 +190,6 @@ private static HttpURLConnection coreCreate(final URI rootUri, final String tabl * null or empty. * @param eTag * The etag of the entity. - * @param timeoutInMs - * The server timeout interval in milliseconds. - * @param queryBuilder - * The {@link UriQueryBuilder} for the operation. - * @param options - * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout - * settings for the operation. Specify null to use the request options specified on the - * {@link CloudTableClient}. - * @param opContext - * An {@link OperationContext} object for tracking the current operation. Specify null to - * safely ignore operation context. - * * @return * An HttpURLConnection to use to perform the operation. * @@ -209,13 +200,11 @@ private static HttpURLConnection coreCreate(final URI rootUri, final String tabl * @throws StorageException * if a storage service error occurred during the operation. */ - public static HttpURLConnection delete(final URI rootUri, final String tableName, final String identity, - final String eTag, final int timeoutInMs, final UriQueryBuilder queryBuilder, - final TableRequestOptions tableOptions, final OperationContext opContext) throws IOException, - URISyntaxException, StorageException { + public static HttpURLConnection delete(final URI rootUri, final TableRequestOptions tableOptions, + final UriQueryBuilder queryBuilder, final OperationContext opContext, final String tableName, + final String identity, final String eTag) throws IOException, URISyntaxException, StorageException { - return coreCreate(rootUri, tableName, eTag, identity, timeoutInMs, queryBuilder, "DELETE", tableOptions, - opContext); + return coreCreate(rootUri, tableOptions, queryBuilder, opContext, tableName, eTag, identity, "DELETE"); } /** @@ -223,6 +212,15 @@ public static HttpURLConnection delete(final URI rootUri, final String tableName * * @param rootUri * A java.net.URI containing an absolute URI to the resource. + * @param tableOptions + * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudTableClient}. + * @param queryBuilder + * The {@link UriQueryBuilder} for the operation. + * @param opContext + * An {@link OperationContext} object for tracking the current operation. Specify null to + * safely ignore operation context. * @param tableName * The name of the table. * @param identity @@ -233,18 +231,6 @@ public static HttpURLConnection delete(final URI rootUri, final String tableName * @param updateType * The {@link TableUpdateType} type of update to be performed. Specify null for straight * inserts. - * @param timeoutInMs - * The server timeout interval in milliseconds. - * @param queryBuilder - * The {@link UriQueryBuilder} for the operation. - * @param options - * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout - * settings for the operation. Specify null to use the request options specified on the - * {@link CloudTableClient}. - * @param opContext - * An {@link OperationContext} object for tracking the current operation. Specify null to - * safely ignore operation context. - * * @return * An HttpURLConnection to use to perform the operation. * @@ -255,28 +241,28 @@ public static HttpURLConnection delete(final URI rootUri, final String tableName * @throws StorageException * if a storage service error occurred during the operation. */ - public static HttpURLConnection insert(final URI rootUri, final String tableName, final String identity, - final String eTag, final boolean echoContent, final TableUpdateType updateType, final int timeoutInMs, - final UriQueryBuilder queryBuilder, final TableRequestOptions tableOptions, final OperationContext opContext) + public static HttpURLConnection insert(final URI rootUri, final TableRequestOptions tableOptions, + final UriQueryBuilder queryBuilder, final OperationContext opContext, final String tableName, + final String identity, final String eTag, final boolean echoContent, final TableUpdateType updateType) throws IOException, URISyntaxException, StorageException { HttpURLConnection retConnection = null; if (updateType == null) { - retConnection = coreCreate(rootUri, tableName, eTag, null/* identity */, timeoutInMs, queryBuilder, - "POST", tableOptions, opContext); + retConnection = coreCreate(rootUri, tableOptions, queryBuilder, opContext, tableName, eTag, + null/* identity */, "POST"); retConnection.setRequestProperty(TableConstants.HeaderConstants.PREFER, echoContent ? TableConstants.HeaderConstants.RETURN_CONTENT : TableConstants.HeaderConstants.RETURN_NO_CONTENT); } else if (updateType == TableUpdateType.MERGE) { - retConnection = coreCreate(rootUri, tableName, null/* ETAG */, identity, timeoutInMs, queryBuilder, - "POST", tableOptions, opContext); + retConnection = coreCreate(rootUri, tableOptions, queryBuilder, opContext, tableName, null/* ETAG */, + identity, "POST"); retConnection.setRequestProperty(TableConstants.HeaderConstants.X_HTTP_METHOD, "MERGE"); } else if (updateType == TableUpdateType.REPLACE) { - retConnection = coreCreate(rootUri, tableName, null/* ETAG */, identity, timeoutInMs, queryBuilder, "PUT", - tableOptions, opContext); + retConnection = coreCreate(rootUri, tableOptions, queryBuilder, opContext, tableName, null/* ETAG */, + identity, "PUT"); } retConnection.setDoOutput(true); @@ -289,6 +275,15 @@ else if (updateType == TableUpdateType.REPLACE) { * * @param rootUri * A java.net.URI containing an absolute URI to the resource. + * @param tableOptions + * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudTableClient}. + * @param queryBuilder + * The {@link UriQueryBuilder} for the operation. + * @param opContext + * An {@link OperationContext} object for tracking the current operation. Specify null to + * safely ignore operation context. * @param tableName * The name of the table. * @param identity @@ -296,18 +291,6 @@ else if (updateType == TableUpdateType.REPLACE) { * null or empty. * @param eTag * The etag of the entity. - * @param timeoutInMs - * The server timeout interval in milliseconds. - * @param queryBuilder - * The {@link UriQueryBuilder} for the operation. - * @param options - * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout - * settings for the operation. Specify null to use the request options specified on the - * {@link CloudTableClient}. - * @param opContext - * An {@link OperationContext} object for tracking the current operation. Specify null to - * safely ignore operation context. - * * @return * An HttpURLConnection to use to perform the operation. * @@ -318,12 +301,11 @@ else if (updateType == TableUpdateType.REPLACE) { * @throws StorageException * if a storage service error occurred during the operation. */ - public static HttpURLConnection merge(final URI rootUri, final String tableName, final String identity, - final String eTag, final int timeoutInMs, final UriQueryBuilder queryBuilder, - final TableRequestOptions tableOptions, final OperationContext opContext) throws IOException, - URISyntaxException, StorageException { - final HttpURLConnection retConnection = coreCreate(rootUri, tableName, eTag, identity, timeoutInMs, - queryBuilder, "POST", tableOptions, opContext); + public static HttpURLConnection merge(final URI rootUri, final TableRequestOptions tableOptions, + final UriQueryBuilder queryBuilder, final OperationContext opContext, final String tableName, + final String identity, final String eTag) throws IOException, URISyntaxException, StorageException { + final HttpURLConnection retConnection = coreCreate(rootUri, tableOptions, queryBuilder, opContext, tableName, + eTag, identity, "POST"); retConnection.setRequestProperty(TableConstants.HeaderConstants.X_HTTP_METHOD, "MERGE"); retConnection.setDoOutput(true); return retConnection; @@ -334,23 +316,20 @@ public static HttpURLConnection merge(final URI rootUri, final String tableName, * * @param rootUri * A java.net.URI containing an absolute URI to the resource. - * @param tableName - * The name of the table. - * @param identity - * The identity of the entity. The resulting request will be formatted as /tableName(identity) if not - * null or empty. - * @param timeoutInMs - * The server timeout interval in milliseconds. - * @param queryBuilder - * The {@link UriQueryBuilder} for the operation. - * @param options + * @param tableOptions * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout * settings for the operation. Specify null to use the request options specified on the * {@link CloudTableClient}. + * @param queryBuilder + * The {@link UriQueryBuilder} for the operation. * @param opContext * An {@link OperationContext} object for tracking the current operation. Specify null to * safely ignore operation context. - * + * @param tableName + * The name of the table. + * @param identity + * The identity of the entity. The resulting request will be formatted as /tableName(identity) if not + * null or empty. * @return * An HttpURLConnection to use to perform the operation. * @@ -361,17 +340,17 @@ public static HttpURLConnection merge(final URI rootUri, final String tableName, * @throws StorageException * if a storage service error occurred during the operation. */ - public static HttpURLConnection query(final URI rootUri, final String tableName, final String identity, - final int timeoutInMs, UriQueryBuilder queryBuilder, final ResultContinuation continuationToken, - final TableRequestOptions tableOptions, final OperationContext opContext) throws IOException, - URISyntaxException, StorageException { + public static HttpURLConnection query(final URI rootUri, final TableRequestOptions tableOptions, + UriQueryBuilder queryBuilder, final OperationContext opContext, final String tableName, + final String identity, final ResultContinuation continuationToken) throws IOException, URISyntaxException, + StorageException { if (queryBuilder == null) { queryBuilder = new UriQueryBuilder(); } applyContinuationToQueryBuilder(queryBuilder, continuationToken); - final HttpURLConnection retConnection = coreCreate(rootUri, tableName, null, identity, timeoutInMs, - queryBuilder, "GET", tableOptions, opContext); + final HttpURLConnection retConnection = coreCreate(rootUri, tableOptions, queryBuilder, opContext, tableName, + null, identity, "GET"); return retConnection; } @@ -381,6 +360,15 @@ public static HttpURLConnection query(final URI rootUri, final String tableName, * * @param rootUri * A java.net.URI containing an absolute URI to the resource. + * @param tableOptions + * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout + * settings for the operation. Specify null to use the request options specified on the + * {@link CloudTableClient}. + * @param queryBuilder + * The {@link UriQueryBuilder} for the operation. + * @param opContext + * An {@link OperationContext} object for tracking the current operation. Specify null to + * safely ignore operation context. * @param tableName * The name of the table. * @param identity @@ -388,18 +376,6 @@ public static HttpURLConnection query(final URI rootUri, final String tableName, * using /tableName(identity) if identity is not >code>null or empty. * @param eTag * The etag of the entity. - * @param timeoutInMs - * The server timeout interval in milliseconds. - * @param queryBuilder - * The {@link UriQueryBuilder} for the operation. - * @param options - * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout - * settings for the operation. Specify null to use the request options specified on the - * {@link CloudTableClient}. - * @param opContext - * An {@link OperationContext} object for tracking the current operation. Specify null to - * safely ignore operation context. - * * @return * An HttpURLConnection to use to perform the operation. * @@ -410,23 +386,22 @@ public static HttpURLConnection query(final URI rootUri, final String tableName, * @throws StorageException * if a storage service error occurred during the operation. */ - public static HttpURLConnection update(final URI rootUri, final String tableName, final String identity, - final String eTag, final int timeoutInMs, final UriQueryBuilder queryBuilder, - final TableRequestOptions tableOptions, final OperationContext opContext) throws IOException, - URISyntaxException, StorageException { - final HttpURLConnection retConnection = coreCreate(rootUri, tableName, eTag, identity, timeoutInMs, - queryBuilder, "PUT", tableOptions, opContext); + public static HttpURLConnection update(final URI rootUri, final TableRequestOptions tableOptions, + final UriQueryBuilder queryBuilder, final OperationContext opContext, final String tableName, + final String identity, final String eTag) throws IOException, URISyntaxException, StorageException { + final HttpURLConnection retConnection = coreCreate(rootUri, tableOptions, queryBuilder, opContext, tableName, + eTag, identity, "PUT"); retConnection.setDoOutput(true); return retConnection; } /** - * Sets the ACL for the table. , Sign with length of aclBytes. + * Sets the ACL for the table. Sign with length of aclBytes. * * @param rootUri * A java.net.URI containing an absolute URI to the resource. - * @param options + * @param tableOptions * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout * settings for the operation. Specify null to use the request options specified on the * {@link CloudTableClient}. @@ -443,8 +418,8 @@ public static HttpURLConnection setAcl(final URI rootUri, final TableRequestOpti UriQueryBuilder queryBuilder = new UriQueryBuilder(); queryBuilder.add(Constants.QueryConstants.COMPONENT, "acl"); - final HttpURLConnection retConnection = BaseRequest.createURLConnection(rootUri, - options.getTimeoutIntervalInMs(), queryBuilder, opContext); + final HttpURLConnection retConnection = BaseRequest.createURLConnection(rootUri, options, queryBuilder, + opContext); retConnection.setRequestMethod("PUT"); retConnection.setDoOutput(true); @@ -456,7 +431,7 @@ public static HttpURLConnection setAcl(final URI rootUri, final TableRequestOpti * * @param rootUri * A java.net.URI containing an absolute URI to the resource. - * @param options + * @param tableOptions * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout * settings for the operation. Specify null to use the request options specified on the * {@link CloudTableClient}. @@ -473,13 +448,14 @@ public static HttpURLConnection getAcl(final URI rootUri, final TableRequestOpti UriQueryBuilder queryBuilder = new UriQueryBuilder(); queryBuilder.add(Constants.QueryConstants.COMPONENT, "acl"); - final HttpURLConnection retConnection = BaseRequest.createURLConnection(rootUri, - options.getTimeoutIntervalInMs(), queryBuilder, opContext); + final HttpURLConnection retConnection = BaseRequest.createURLConnection(rootUri, options, queryBuilder, + opContext); retConnection.setRequestMethod("GET"); return retConnection; } + @SuppressWarnings("deprecation") private static void setAcceptHeaderForHttpWebRequest(HttpURLConnection retConnection, TablePayloadFormat payloadFormat) { if (payloadFormat == TablePayloadFormat.AtomPub) { @@ -500,6 +476,7 @@ else if (payloadFormat == TablePayloadFormat.JsonNoMetadata) { } } + @SuppressWarnings("deprecation") private static void setContentTypeForHttpWebRequest(HttpURLConnection retConnection, TablePayloadFormat payloadFormat) { if (payloadFormat == TablePayloadFormat.AtomPub) { diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableRequestOptions.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableRequestOptions.java similarity index 67% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableRequestOptions.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableRequestOptions.java index 6849ef7fe6705..d78df03061489 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableRequestOptions.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableRequestOptions.java @@ -13,10 +13,10 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; -import com.microsoft.windowsazure.storage.RequestOptions; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.RequestOptions; +import com.microsoft.azure.storage.core.Utility; /** * Represents a set of timeout, payload format, and retry policy options that may be specified for a table operation @@ -95,25 +95,41 @@ public TableRequestOptions(final TableRequestOptions other) { protected static final TableRequestOptions applyDefaults(final TableRequestOptions options, final CloudTableClient client) { TableRequestOptions modifiedOptions = new TableRequestOptions(options); + TableRequestOptions.populateRequestOptions(modifiedOptions, client.getDefaultRequestOptions()); return TableRequestOptions.applyDefaultsInternal(modifiedOptions, client); } - protected static final TableRequestOptions applyDefaultsInternal(TableRequestOptions modifiedOptions, + private static final TableRequestOptions applyDefaultsInternal(final TableRequestOptions modifiedOptions, CloudTableClient client) { Utility.assertNotNull("modifiedOptions", modifiedOptions); - RequestOptions.applyBaseDefaultsInternal(modifiedOptions, client); + RequestOptions.applyBaseDefaultsInternal(modifiedOptions); + if (modifiedOptions.getTablePayloadFormat() == null) { + modifiedOptions.setTablePayloadFormat(TablePayloadFormat.Json); + } + + return modifiedOptions; + } + /** + * Populates any null fields in the first requestOptions object with values from the second requestOptions object. + */ + private static final RequestOptions populateRequestOptions(TableRequestOptions modifiedOptions, + final TableRequestOptions clientOptions) { + RequestOptions.populateRequestOptions(modifiedOptions, clientOptions, false); if (modifiedOptions.getTablePayloadFormat() == null) { - modifiedOptions.setTablePayloadFormat(client.getTablePayloadFormat()); + modifiedOptions.setTablePayloadFormat(clientOptions.getTablePayloadFormat()); + } + + if (modifiedOptions.getPropertyResolver() == null) { + modifiedOptions.setPropertyResolver(clientOptions.getPropertyResolver()); } return modifiedOptions; } /** - * Gets the for an entity property - * given the partition key, row, key, and the property name. + * given the partition key, row, key, and the property name. For more information about the {@link PropertyResolver} + * defaults, see {@link #setPropertyResolver(PropertyResolver)}. * * @return * The property resolver in use @@ -134,8 +151,12 @@ public PropertyResolver getPropertyResolver() { } /** - * Sets the + * The default {@link TablePayloadFormat} is set in the client and is by default {@link TablePayloadFormat#Json}. + * You can change the {@link TablePayloadFormat} on this request by setting this property. You can also change the + * value on the {@link TableServiceClient#getDefaultRequestOptions()} object so that all subsequent requests made + * via the service client will use that {@link TablePayloadFormat}. * * @param payloadFormat * The TablePayloadFormat to use. @@ -147,6 +168,11 @@ public void setTablePayloadFormat(TablePayloadFormat payloadFormat) { /** * Sets the interface that contains a function which is used to get the for an entity property * given the partition key, row, key, and the property name. + *

+ * The default {@link PropertyResolver} is set in the client and is by default null, indicating not to use a + * property resolver. You can change the {@link PropertyResolver} on this request by setting this property. You can + * also change the value on the {@link TableServiceClient#getDefaultRequestOptions()} object so that all subsequent + * requests made via the service client will use that {@link PropertyResolver}. * * @param propertyResolver * The property resolver to use. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableResponse.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableResponse.java similarity index 94% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableResponse.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableResponse.java index 78096e1a7de31..7a9634fd41fc0 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableResponse.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableResponse.java @@ -13,12 +13,12 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.net.HttpURLConnection; -import com.microsoft.windowsazure.storage.ResultContinuation; -import com.microsoft.windowsazure.storage.ResultContinuationType; +import com.microsoft.azure.storage.ResultContinuation; +import com.microsoft.azure.storage.ResultContinuationType; /** * Reserved for internal use. A class used to help parse responses from the Table service. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableResult.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableResult.java similarity index 94% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableResult.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableResult.java index 4b87cf3197b91..5a0e854a6f3c2 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableResult.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableResult.java @@ -13,16 +13,15 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; -import java.text.ParseException; import java.util.Date; import java.util.HashMap; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.core.Utility; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.core.Utility; /** * A class which represents the result of a table operation. The {@link TableResult} class encapsulates the HTTP @@ -156,10 +155,9 @@ protected void setResult(final Object result) { * * @param ent * An instance of an object implementing {@link TableEntity} to associate with the table operation. - * @throws ParseException * @throws UnsupportedEncodingException */ - protected void updateResultObject(final TableEntity ent) throws UnsupportedEncodingException, ParseException { + protected void updateResultObject(final TableEntity ent) throws UnsupportedEncodingException { this.result = ent; ent.setEtag(this.etag); if (this.etag != null) { @@ -167,7 +165,7 @@ protected void updateResultObject(final TableEntity ent) throws UnsupportedEncod } } - private static Date parseETagForTimestamp(String etag) throws UnsupportedEncodingException, ParseException { + private static Date parseETagForTimestamp(String etag) throws UnsupportedEncodingException { // must handle both weak and strong ETags if (etag.startsWith("W/")) { etag = etag.substring(2); diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableServiceEntity.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableServiceEntity.java similarity index 96% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableServiceEntity.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableServiceEntity.java index a445c35b9bf46..e85710da59468 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableServiceEntity.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableServiceEntity.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.lang.reflect.InvocationTargetException; import java.util.Date; @@ -21,11 +21,11 @@ import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageErrorCodeStrings; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.core.SR; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.OperationContext; +import com.microsoft.azure.storage.StorageErrorCodeStrings; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.core.SR; /** * The {@link TableServiceEntity} class represents the base object type for a table entity in the Storage service. @@ -38,7 +38,7 @@ * having to implement the serialization code themselves. When both a getter method and setter method are found for a * given property name and data type, then the appropriate method is invoked automatically to serialize or deserialize * the data. To take advantage of the automatic serialization code, your table entity classes should provide getter and - * setter methods for each property in the corresponding table entity in Windows Azure table storage. The reflection + * setter methods for each property in the corresponding table entity in Microsoft Azure table storage. The reflection * code looks for getter and setter methods in pairs of the form *

* public type getPropertyName() { ... } @@ -56,8 +56,8 @@ * serialization and deserialization. Note that the names "PartitionKey", "RowKey", "Timestamp", and "Etag" are reserved * and will be ignored if set with the {@link StoreAs} annotation in a subclass. *

- * The following table shows the supported property data types in Windows Azure storage and the corresponding Java types - * when deserialized. + * The following table shows the supported property data types in Microsoft Azure storage and the corresponding Java + * types when deserialized. * * * @@ -122,8 +122,8 @@ * *
Storage Type
*

- * See the MSDN topic Understanding the - * Table Service Data Model for an overview of tables, entities, and properties as used in the Windows Azure Storage + * See the MSDN topic Understanding the Table + * Service Data Model for an overview of tables, entities, and properties as used in the Microsoft Azure Storage * service. *

* For an overview of the available EDM primitive data types and names, see the @@ -281,7 +281,7 @@ public TableServiceEntity(String partitionKey, String rowKey) { /** * Gets the Etag value for the entity. This value is used to determine if the table entity has changed since it was - * last read from Windows Azure storage. + * last read from Microsoft Azure storage. * * @return * A String containing the Etag for the entity. @@ -362,7 +362,7 @@ public static void setReflectedEntityCacheDisabled(boolean disableReflectedEntit * This method invokes {@link TableServiceEntity#readEntityWithReflection} to populate the table entity instance the * method is called on using reflection. Table entity classes that extend {@link TableServiceEntity} can take * advantage of this behavior by implementing getter and setter methods for the particular properties of the table - * entity in Windows Azure storage the class represents. + * entity in Microsoft Azure storage the class represents. *

* Override this method in classes that extend {@link TableServiceEntity} to invoke custom serialization code. * @@ -396,7 +396,7 @@ public void readEntity(final HashMap properties, final O /** * Sets the Etag value for the entity. This value is used to determine if the table entity has changed since it was - * last read from Windows Azure storage. + * last read from Microsoft Azure storage. * * @param etag * A String containing the Etag for the entity. @@ -446,7 +446,7 @@ public void setTimestamp(final Date timeStamp) { * This method invokes {@link #writeEntityWithReflection} to serialize the table entity instance the method is * called on using reflection. Table entity classes that extend {@link TableServiceEntity} can take advantage of * this behavior by implementing getter and setter methods for the particular properties of the table entity in - * Windows Azure storage the class represents. Note that the property names "PartitionKey", "RowKey", and + * Microsoft Azure storage the class represents. Note that the property names "PartitionKey", "RowKey", and * "Timestamp" are reserved and will be ignored if set on other methods with the {@link StoreAs} annotation. *

* Override this method in classes that extend {@link TableServiceEntity} to invoke custom serialization code. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableServiceException.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableServiceException.java similarity index 96% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableServiceException.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableServiceException.java index f0fdb3e8e852e..82808b1c46063 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableServiceException.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableServiceException.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.io.IOException; import java.io.InputStream; @@ -23,9 +23,9 @@ import javax.xml.stream.XMLStreamException; import com.fasterxml.jackson.core.JsonParseException; -import com.microsoft.windowsazure.storage.RequestResult; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.StorageExtendedErrorInformation; +import com.microsoft.azure.storage.RequestResult; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.StorageExtendedErrorInformation; /** * An exception that results when a table storage service operation fails to complete successfully. diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableStorageErrorDeserializer.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableStorageErrorDeserializer.java similarity index 97% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableStorageErrorDeserializer.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableStorageErrorDeserializer.java index 35d7dc11f4316..f733f3f5205ab 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableStorageErrorDeserializer.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableStorageErrorDeserializer.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; import java.io.IOException; import java.io.Reader; @@ -27,10 +27,9 @@ import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.StorageExtendedErrorInformation; -import com.microsoft.windowsazure.storage.core.DeserializationHelper; -import com.microsoft.windowsazure.storage.core.SR; +import com.microsoft.azure.storage.Constants; +import com.microsoft.azure.storage.StorageExtendedErrorInformation; +import com.microsoft.azure.storage.core.SR; /*** * RESERVED FOR INTERNAL USE. A class to help parse the error details from an input stream, specific to tables @@ -53,6 +52,7 @@ public final class TableStorageErrorDeserializer { * @throws JsonParseException * if an error occurs while parsing the stream. */ + @SuppressWarnings("deprecation") public static StorageExtendedErrorInformation getExtendedErrorInformation(final Reader reader, final TablePayloadFormat format) throws JsonParseException, IOException, XMLStreamException { if (format == TablePayloadFormat.AtomPub) { diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableUpdateType.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableUpdateType.java similarity index 94% rename from microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableUpdateType.java rename to microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableUpdateType.java index cc3c4b7467788..a8a5596e96889 100644 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/TableUpdateType.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableUpdateType.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.microsoft.windowsazure.storage.table; +package com.microsoft.azure.storage.table; /** * Reserved for internal use. An enum that represents the type of update a given upsert operation will perform. diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/table/package.html b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/package.html new file mode 100644 index 0000000000000..2d12f34503978 --- /dev/null +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/table/package.html @@ -0,0 +1,5 @@ + + +This package contains the storage service table classes. + + diff --git a/microsoft-azure-storage/src/config/checkstyle.xml b/microsoft-azure-storage/src/config/checkstyle.xml deleted file mode 100644 index 58a40f4ac43a8..0000000000000 --- a/microsoft-azure-storage/src/config/checkstyle.xml +++ /dev/null @@ -1,240 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/GeoReplicationStatus.java b/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/GeoReplicationStatus.java deleted file mode 100644 index 0f9bc901cb54f..0000000000000 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/GeoReplicationStatus.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * 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.windowsazure.storage; - -/** - * Enumeration representing the state of geo-replication in a service. - */ -public enum GeoReplicationStatus { - - /** - * Status of geo-replication is unavailable. - */ - UNAVAILABLE, - - /** - * Geo-replication is live. - */ - LIVE, - - /** - * Data is being bootstrapped from primary to secondary. - */ - BOOTSTRAP; -} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ServicePropertiesDeserializer.java b/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ServicePropertiesDeserializer.java deleted file mode 100644 index ebc59453331c8..0000000000000 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ServicePropertiesDeserializer.java +++ /dev/null @@ -1,426 +0,0 @@ -/** - * 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.windowsazure.storage; - -import java.io.InputStream; -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.List; -import java.util.StringTokenizer; - -import javax.xml.stream.XMLStreamConstants; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; - -import com.microsoft.windowsazure.storage.core.DeserializationHelper; -import com.microsoft.windowsazure.storage.core.SR; - -/** - * RESERVED FOR INTERNAL USE. A class used to serialize ServiceProperties to a byte array. - */ -public final class ServicePropertiesDeserializer { - /** - * Deserializes the ServiceProperties object from an input stream. - * - * @param inStream - * the stream to read from. - * @param opContext - * an object used to track the execution of the operation - * @return a ServiceProperties object representing the Analytics configuration for the client. - * @throws XMLStreamException - * if the xml is invalid. - * @throws StorageException - * if unexpected xml is found. - */ - public static ServiceProperties readServicePropertiesFromStream(final InputStream inStream, - final OperationContext opContext) throws XMLStreamException, StorageException { - final ServiceProperties retProps = new ServiceProperties(); - - final XMLStreamReader xmlr = DeserializationHelper.createXMLStreamReaderFromStream(inStream); - - // Start document - int eventType = xmlr.getEventType(); - xmlr.require(XMLStreamConstants.START_DOCUMENT, null, null); - - // Get StorageServiceProperties Header - eventType = xmlr.next(); - xmlr.require(XMLStreamConstants.START_ELEMENT, null, - Constants.AnalyticsConstants.STORAGE_SERVICE_PROPERTIES_ELEMENT); - - // Check if there are more events in the input stream - while (xmlr.hasNext()) { - eventType = xmlr.next(); - if (eventType == XMLStreamConstants.START_ELEMENT) { - final String name = xmlr.getName().toString(); - if (name.equals(Constants.AnalyticsConstants.LOGGING_ELEMENT)) { - retProps.setLogging(readLoggingProperties(xmlr)); - xmlr.require(XMLStreamConstants.END_ELEMENT, null, Constants.AnalyticsConstants.LOGGING_ELEMENT); - } - else if (name.equals(Constants.AnalyticsConstants.HOUR_METRICS_ELEMENT)) { - retProps.setHourMetrics(readMetricsProperties(Constants.AnalyticsConstants.HOUR_METRICS_ELEMENT, - xmlr)); - xmlr.require(XMLStreamConstants.END_ELEMENT, null, - Constants.AnalyticsConstants.HOUR_METRICS_ELEMENT); - } - else if (name.equals(Constants.AnalyticsConstants.MINUTE_METRICS_ELEMENT)) { - retProps.setMinuteMetrics(readMetricsProperties( - Constants.AnalyticsConstants.MINUTE_METRICS_ELEMENT, xmlr)); - xmlr.require(XMLStreamConstants.END_ELEMENT, null, - Constants.AnalyticsConstants.MINUTE_METRICS_ELEMENT); - } - else if (name.equals(Constants.AnalyticsConstants.CORS_ELEMENT)) { - retProps.setCors(readCorsProperties(xmlr)); - xmlr.require(XMLStreamConstants.END_ELEMENT, null, Constants.AnalyticsConstants.CORS_ELEMENT); - } - else if (name.equals(Constants.AnalyticsConstants.DEFAULT_SERVICE_VERSION)) { - retProps.setDefaultServiceVersion(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.AnalyticsConstants.DEFAULT_SERVICE_VERSION)); - } - else { - throw new StorageException(StorageErrorCodeStrings.INVALID_XML_DOCUMENT, - SR.INVALID_RESPONSE_RECEIVED, Constants.HeaderConstants.HTTP_UNUSED_306, null, null); - } - } - else if (eventType == XMLStreamConstants.END_ELEMENT) { - if (xmlr.getName().toString().equals(Constants.AnalyticsConstants.STORAGE_SERVICE_PROPERTIES_ELEMENT)) { - break; - } - } - } - - return retProps; - } - - /** - * Returns the a populated LoggingProperties object from the xml reader. XmlStreamReader must be at start of the - * LoggingProperties element. - * - * @param xmlr - * the XMLStreamReader to read from - * @return the populated LoggingProperties object - * @throws XMLStreamException - * if the xml is invalid. - * @throws StorageException - * if unexpected xml is found. - */ - private static LoggingProperties readLoggingProperties(final XMLStreamReader xmlr) throws XMLStreamException, - StorageException { - xmlr.require(XMLStreamConstants.START_ELEMENT, null, Constants.AnalyticsConstants.LOGGING_ELEMENT); - - int eventType = xmlr.getEventType(); - String tempParseString = null; - LoggingProperties logging = new LoggingProperties(); - - while (xmlr.hasNext()) { - eventType = xmlr.next(); - - if (eventType == XMLStreamConstants.START_ELEMENT) { - final String name = xmlr.getName().toString(); - if (name.equals(Constants.AnalyticsConstants.VERSION_ELEMENT)) { - logging.setVersion(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.AnalyticsConstants.VERSION_ELEMENT)); - } - else if (name.equals(Constants.AnalyticsConstants.DELETE_ELEMENT)) { - tempParseString = DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.AnalyticsConstants.DELETE_ELEMENT); - if (Boolean.parseBoolean(tempParseString)) { - logging.getLogOperationTypes().add(LoggingOperations.DELETE); - } - } - else if (name.equals(Constants.AnalyticsConstants.READ_ELEMENT)) { - tempParseString = DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.AnalyticsConstants.READ_ELEMENT); - if (Boolean.parseBoolean(tempParseString)) { - logging.getLogOperationTypes().add(LoggingOperations.READ); - } - } - else if (name.equals(Constants.AnalyticsConstants.WRITE_ELEMENT)) { - tempParseString = DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.AnalyticsConstants.WRITE_ELEMENT); - if (Boolean.parseBoolean(tempParseString)) { - logging.getLogOperationTypes().add(LoggingOperations.WRITE); - } - } - else if (name.equals(Constants.AnalyticsConstants.RETENTION_POLICY_ELEMENT)) { - logging.setRetentionIntervalInDays(readRetentionPolicy(xmlr)); - } - else { - throw new StorageException(StorageErrorCodeStrings.INVALID_XML_DOCUMENT, - SR.INVALID_RESPONSE_RECEIVED, Constants.HeaderConstants.HTTP_UNUSED_306, null, null); - } - } - else { - xmlr.require(XMLStreamConstants.END_ELEMENT, null, Constants.AnalyticsConstants.LOGGING_ELEMENT); - break; - } - } - - return logging; - } - - /** - * Returns the a populated MetricsProperties object from the xml reader. XmlStreamReader must be at start of the - * MetricsProperties element. - * - * @param xmlr - * the XMLStreamReader to read from - * @param metricsName - * the type of metrics being parsed (Hour or Minute) - * @return the populated MetricsProperties object - * @throws XMLStreamException - * if the xml is invalid. - * @throws StorageException - * if unexpected xml is found. - */ - private static MetricsProperties readMetricsProperties(String metricsName, final XMLStreamReader xmlr) - throws XMLStreamException, StorageException { - xmlr.require(XMLStreamConstants.START_ELEMENT, null, metricsName); - - int eventType = xmlr.getEventType(); - String tempParseString = null; - MetricsProperties metrics = new MetricsProperties(); - - while (xmlr.hasNext()) { - eventType = xmlr.next(); - - if (eventType == XMLStreamConstants.START_ELEMENT) { - final String name = xmlr.getName().toString(); - if (name.equals(Constants.AnalyticsConstants.VERSION_ELEMENT)) { - metrics.setVersion(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.AnalyticsConstants.VERSION_ELEMENT)); - } - else if (name.equals(Constants.AnalyticsConstants.ENABLED_ELEMENT)) { - tempParseString = DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.AnalyticsConstants.ENABLED_ELEMENT); - - if (Boolean.parseBoolean(tempParseString)) { - metrics.setMetricsLevel(metrics.getMetricsLevel() != MetricsLevel.SERVICE_AND_API ? MetricsLevel.SERVICE - : MetricsLevel.SERVICE_AND_API); - } - else { - metrics.setMetricsLevel(MetricsLevel.DISABLED); - } - } - else if (name.equals(Constants.AnalyticsConstants.INCLUDE_APIS_ELEMENT)) { - tempParseString = DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.AnalyticsConstants.INCLUDE_APIS_ELEMENT); - if (Boolean.parseBoolean(tempParseString) && metrics.getMetricsLevel() != MetricsLevel.DISABLED) { - metrics.setMetricsLevel(MetricsLevel.SERVICE_AND_API); - } - } - else if (name.equals(Constants.AnalyticsConstants.RETENTION_POLICY_ELEMENT)) { - metrics.setRetentionIntervalInDays(readRetentionPolicy(xmlr)); - } - else { - throw new StorageException(StorageErrorCodeStrings.INVALID_XML_DOCUMENT, - SR.INVALID_RESPONSE_RECEIVED, Constants.HeaderConstants.HTTP_UNUSED_306, null, null); - } - } - else { - xmlr.require(XMLStreamConstants.END_ELEMENT, null, metricsName); - break; - } - } - - return metrics; - } - - /** - * Parses the retention policy from the xml reader. XmlStreamReader must be at start of retention policy element. - * - * @param xmlr - * the XMLStreamReader to read from - * @return a nullable Integer representing the retention policy - * @throws XMLStreamException - * if the xml is invalid. - * @throws StorageException - * if unexpected xml is found. - */ - private static Integer readRetentionPolicy(final XMLStreamReader xmlr) throws XMLStreamException, StorageException { - xmlr.require(XMLStreamConstants.START_ELEMENT, null, Constants.AnalyticsConstants.RETENTION_POLICY_ELEMENT); - - Integer retVal = -1; - int eventType = xmlr.getEventType(); - String tempParseString = null; - - while (xmlr.hasNext()) { - eventType = xmlr.next(); - - if (eventType == XMLStreamConstants.START_ELEMENT) { - final String name = xmlr.getName().toString(); - - if (name.equals(Constants.AnalyticsConstants.DAYS_ELEMENT)) { - tempParseString = DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.AnalyticsConstants.DAYS_ELEMENT); - - // if we have already detected that the retention policy is disabled dont return a value; - if (retVal != null) { - retVal = Integer.parseInt(tempParseString); - } - } - else if (name.equals(Constants.AnalyticsConstants.ENABLED_ELEMENT)) { - tempParseString = DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.AnalyticsConstants.ENABLED_ELEMENT); - - if (!Boolean.parseBoolean(tempParseString)) { - retVal = null; - } - } - else { - throw new StorageException(StorageErrorCodeStrings.INVALID_XML_DOCUMENT, - SR.INVALID_RESPONSE_RECEIVED, Constants.HeaderConstants.HTTP_UNUSED_306, null, null); - } - } - else { - xmlr.require(XMLStreamConstants.END_ELEMENT, null, - Constants.AnalyticsConstants.RETENTION_POLICY_ELEMENT); - break; - } - } - - return retVal; - } - - /** - * Returns the a populated CorsProperties object from the xml reader. XmlStreamReader must be at start of the - * CorsProperties element. - * - * @param xmlr - * the XMLStreamReader to read from - * @return the populated CorsProperties object - * @throws XMLStreamException - * if the xml is invalid. - * @throws StorageException - * if unexpected xml is found. - */ - private static CorsProperties readCorsProperties(final XMLStreamReader xmlr) throws XMLStreamException, - StorageException { - - xmlr.require(XMLStreamConstants.START_ELEMENT, null, Constants.AnalyticsConstants.CORS_ELEMENT); - - CorsProperties corsProperties = new CorsProperties(); - - int eventType = xmlr.getEventType(); - String tempParseString = null; - - while (xmlr.hasNext()) { - eventType = xmlr.next(); - - if (eventType == XMLStreamConstants.START_ELEMENT) { - if (xmlr.getName().toString().equals(Constants.AnalyticsConstants.CORS_RULE_ELEMENT)) { - CorsRule rule = new CorsRule(); - - while (xmlr.hasNext()) { - eventType = xmlr.next(); - - if (eventType == XMLStreamConstants.START_ELEMENT) { - final String name = xmlr.getName().toString(); - if (name.equals(Constants.AnalyticsConstants.ALLOWED_ORIGINS_ELEMENT)) { - tempParseString = DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.AnalyticsConstants.ALLOWED_ORIGINS_ELEMENT); - if (tempParseString != null) { - rule.setAllowedOrigins(splitToList(tempParseString, ",")); - } - } - else if (name.equals(Constants.AnalyticsConstants.ALLOWED_METHODS_ELEMENT)) { - tempParseString = DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.AnalyticsConstants.ALLOWED_METHODS_ELEMENT); - if (tempParseString != null) { - rule.setAllowedMethods(splitToEnumSet(tempParseString, ",")); - } - } - else if (name.equals(Constants.AnalyticsConstants.EXPOSED_HEADERS_ELEMENT)) { - tempParseString = DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.AnalyticsConstants.EXPOSED_HEADERS_ELEMENT); - if (tempParseString != null) { - rule.setExposedHeaders(splitToList(tempParseString, ",")); - } - } - else if (name.equals(Constants.AnalyticsConstants.ALLOWED_HEADERS_ELEMENT)) { - tempParseString = DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.AnalyticsConstants.ALLOWED_HEADERS_ELEMENT); - if (tempParseString != null) { - rule.setAllowedHeaders(splitToList(tempParseString, ",")); - } - } - else if (name.equals(Constants.AnalyticsConstants.MAX_AGE_IN_SECONDS_ELEMENT)) { - tempParseString = DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.AnalyticsConstants.MAX_AGE_IN_SECONDS_ELEMENT); - rule.setMaxAgeInSeconds(Integer.parseInt(tempParseString)); - } - else { - throw new StorageException(StorageErrorCodeStrings.INVALID_XML_DOCUMENT, - SR.INVALID_RESPONSE_RECEIVED, Constants.HeaderConstants.HTTP_UNUSED_306, null, - null); - } - } - else { - xmlr.require(XMLStreamConstants.END_ELEMENT, null, - Constants.AnalyticsConstants.CORS_RULE_ELEMENT); - corsProperties.getCorsRules().add(rule); - break; - } - } - } - else { - throw new StorageException(StorageErrorCodeStrings.INVALID_XML_DOCUMENT, - SR.INVALID_RESPONSE_RECEIVED, Constants.HeaderConstants.HTTP_UNUSED_306, null, null); - } - } - else { - xmlr.require(XMLStreamConstants.END_ELEMENT, null, Constants.AnalyticsConstants.CORS_ELEMENT); - break; - } - } - - return corsProperties; - } - - /** - * Split a delimiter separated string into an ArrayList - * - * @param str - * the string to split - * @param delimiter - * the character to split on - * @return the list of strings - */ - private static List splitToList(String str, String delimiter) { - ArrayList list = new ArrayList(); - StringTokenizer st = new StringTokenizer(str, delimiter); - while (st.hasMoreElements()) { - list.add(st.nextToken()); - } - return list; - } - - /** - * Split a delimiter separated string into a EnumSet of CorsHttpMethods - * - * @param str - * the string to split - * @param delimiter - * the character to split on - * @return the set of CorsHttpMethods - */ - private static EnumSet splitToEnumSet(String str, String delimiter) throws StorageException { - EnumSet set = EnumSet.noneOf(CorsHttpMethods.class); - StringTokenizer st = new StringTokenizer(str, delimiter); - while (st.hasMoreElements()) { - set.add(CorsHttpMethods.valueOf(st.nextToken())); - } - return set; - } -} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ServiceStatsDeserializer.java b/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ServiceStatsDeserializer.java deleted file mode 100644 index a082e192f055c..0000000000000 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/ServiceStatsDeserializer.java +++ /dev/null @@ -1,110 +0,0 @@ -/** - * 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.windowsazure.storage; - -import java.io.InputStream; -import java.text.ParseException; - -import javax.xml.stream.XMLStreamConstants; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; - -import com.microsoft.windowsazure.storage.core.DeserializationHelper; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.Utility; - -/** - * RESERVED FOR INTERNAL USE. - */ -final class ServiceStatsDeserializer { - /** - * The name of the geo-replication XML element. - */ - private final static String GEO_REPLICATION_NAME = "GeoReplication"; - - /** - * The name of the status XML element. - */ - private final static String STATUS_NAME = "Status"; - - /** - * The name of the last sync time XML element. - */ - private final static String LAST_SYNC_TIME_NAME = "LastSyncTime"; - - /** - * Constructs a {@link ServiceStats} object from an XML document received from the service. - * - * @param inStream - * The XMLStreamReader object. - * @param context - * an object used to track the execution of the operation - * @return - * A {@link ServiceStats} object containing the properties in the XML document. - * @throws XMLStreamException - * If there is an XML parsing error. - * @throws ParseException - * If the specified last sync time string is invalid. - * @throws StorageException - */ - protected static ServiceStats readServiceStatsFromStream(final InputStream inStream, final OperationContext context) - throws XMLStreamException, StorageException, ParseException { - ServiceStats serviceStats = new ServiceStats(); - GeoReplicationStats geoReplicationStats = new GeoReplicationStats(); - final XMLStreamReader xmlr = DeserializationHelper.createXMLStreamReaderFromStream(inStream); - - // Start document - int eventType = xmlr.getEventType(); - xmlr.require(XMLStreamConstants.START_DOCUMENT, null, null); - - // Get StorageServiceProperties Header - eventType = xmlr.next(); - xmlr.require(XMLStreamConstants.START_ELEMENT, null, Constants.AnalyticsConstants.STORAGE_SERVICE_STATS); - - // Get the GeoReplication XML element - eventType = xmlr.next(); - xmlr.require(XMLStreamConstants.START_ELEMENT, null, GEO_REPLICATION_NAME); - - // Check if there are more events in the input stream - while (xmlr.hasNext()) { - eventType = xmlr.next(); - if (eventType == XMLStreamConstants.START_ELEMENT) { - final String name = xmlr.getName().toString(); - if (name.equals(STATUS_NAME)) { - geoReplicationStats.setStatus(GeoReplicationStats.getGeoReplicationStatus(DeserializationHelper - .readElementFromXMLReader(xmlr, STATUS_NAME))); - xmlr.require(XMLStreamConstants.END_ELEMENT, null, STATUS_NAME); - } - else if (name.equals(LAST_SYNC_TIME_NAME)) { - String lastSyncTime = DeserializationHelper.readElementFromXMLReader(xmlr, LAST_SYNC_TIME_NAME); - geoReplicationStats.setLastSyncTime(Utility.isNullOrEmpty(lastSyncTime) ? null : Utility - .parseRFC1123DateFromStringInGMT(lastSyncTime)); - xmlr.require(XMLStreamConstants.END_ELEMENT, null, LAST_SYNC_TIME_NAME); - } - else { - throw new StorageException(StorageErrorCodeStrings.INVALID_XML_DOCUMENT, - SR.INVALID_RESPONSE_RECEIVED, Constants.HeaderConstants.HTTP_UNUSED_306, null, null); - } - } - else if (eventType == XMLStreamConstants.END_ELEMENT) { - if (xmlr.getName().toString().equals(Constants.AnalyticsConstants.STORAGE_SERVICE_STATS)) { - break; - } - } - } - serviceStats.setGeoReplication(geoReplicationStats); - return serviceStats; - } -} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageCredentials.java b/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageCredentials.java deleted file mode 100644 index 776bde62c02fd..0000000000000 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageCredentials.java +++ /dev/null @@ -1,541 +0,0 @@ -/** - * 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.windowsazure.storage; - -import java.net.HttpURLConnection; -import java.net.URI; -import java.net.URISyntaxException; -import java.security.InvalidKeyException; -import java.util.HashMap; - -import com.microsoft.windowsazure.storage.core.Base64; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.Utility; - -/** - * Represents a set of credentials used to authenticate access to a Windows Azure storage account. This is the base - * class for the {@link StorageCredentialsAccountAndKey} and {@link StorageCredentialsSharedAccessSignature} classes. - */ -public abstract class StorageCredentials { - - /** - * Tries to determine the storage credentials from a collection of name/value pairs. - * - * @param settings - * A HashMap object of the name/value pairs that represent the settings to use to configure - * the credentials. - *

- * Either include an account name with an account key (specifying values for - * {@link CloudStorageAccount#ACCOUNT_NAME_NAME} and {@link CloudStorageAccount#ACCOUNT_KEY_NAME} ), or a - * shared access signature (specifying a value for - * {@link CloudStorageAccount#SHARED_ACCESS_SIGNATURE_NAME} ). If you use an account name and account - * key, do not include a shared access signature, and vice versa. - * - * @return A {@link StorageCredentials} object representing the storage credentials determined from the name/value - * pairs. - * - * @throws InvalidKeyException - * If the key value specified for {@link CloudStorageAccount#ACCOUNT_KEY_NAME} is not a valid - * Base64-encoded string. - */ - protected static StorageCredentials tryParseCredentials(final HashMap settings) - throws InvalidKeyException { - final String accountName = settings.get(CloudStorageAccount.ACCOUNT_NAME_NAME) != null ? settings - .get(CloudStorageAccount.ACCOUNT_NAME_NAME) : null; - - final String accountKey = settings.get(CloudStorageAccount.ACCOUNT_KEY_NAME) != null ? settings - .get(CloudStorageAccount.ACCOUNT_KEY_NAME) : null; - - final String sasSignature = settings.get(CloudStorageAccount.SHARED_ACCESS_SIGNATURE_NAME) != null ? settings - .get(CloudStorageAccount.SHARED_ACCESS_SIGNATURE_NAME) : null; - - if (accountName != null && accountKey != null && sasSignature == null) { - if (Base64.validateIsBase64String(accountKey)) { - return new StorageCredentialsAccountAndKey(accountName, accountKey); - } - else { - throw new InvalidKeyException(SR.INVALID_KEY); - } - } - if (accountName == null && accountKey == null && sasSignature != null) { - return new StorageCredentialsSharedAccessSignature(sasSignature); - } - - return null; - } - - /** - * Tries to determine the storage credentials from a connection string. - * - * @param connectionString - * A String that contains the key/value pairs that represent the storage credentials. - *

- * The format for the connection string is in the pattern "keyname=value". Multiple key/value - * pairs can be separated by a semi-colon, for example, "keyname1=value1;keyname2=value2". - * - * @return A {@link StorageCredentials} object representing the storage credentials determined from the connection - * string. - * - * @throws InvalidKeyException - * If the account key specified in connectionString is not valid. - * @throws StorageException - * If a storage service error occurred. - */ - public static StorageCredentials tryParseCredentials(final String connectionString) throws InvalidKeyException, - StorageException { - return tryParseCredentials(Utility.parseAccountString(connectionString)); - } - - // - // RESERVED, for internal use only. Gets a value indicating whether the - // ComputeHmac method will return a valid HMAC-encoded - // signature string when called using the specified credentials. - // - // @return True if these credentials will yield a valid - // signature string; otherwise, false - // - /** Reserved. */ - public abstract boolean canCredentialsComputeHmac(); - - // - // RESERVED, for internal use only. Gets a value indicating whether a - // request can be signed under the Shared Key authentication scheme using - // the specified credentials. - // - // @return True if a request can be signed with these - // credentials; otherwise, false - // - /** Reserved. */ - public abstract boolean canCredentialsSignRequest(); - - // - // RESERVED, for internal use only. Gets a value indicating whether a - // request can be signed under the Shared Key Lite authentication scheme - // using the specified credentials. - // - // @return true if a request can be signed with these - // credentials; otherwise, false - // - /** Reserved. */ - public abstract boolean canCredentialsSignRequestLite(); - - /** - * Computes a signature for the specified string using the HMAC-SHA256 algorithm. - * - * @param value - * The UTF-8-encoded string to sign. - * - * @return A String that contains the HMAC-SHA256-encoded signature. - * - * @throws InvalidKeyException - * If the key is not a valid Base64-encoded string. - */ - public abstract String computeHmac256(String value) throws InvalidKeyException; - - /** - * Computes a signature for the specified string using the HMAC-SHA256 algorithm with the specified operation - * context. - * - * @param value - * The UTF-8-encoded string to sign. - * @param opContext - * An {@link OperationContext} object that 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. - * - * @return A String that contains the HMAC-SHA256-encoded signature. - * - * @throws InvalidKeyException - * If the key is not a valid Base64-encoded string. - */ - public abstract String computeHmac256(String value, OperationContext opContext) throws InvalidKeyException; - - /** - * Computes a signature for the specified string using the HMAC-SHA512 algorithm. - * - * @param value - * The UTF-8-encoded string to sign. - * - * @return A String that contains the HMAC-SHA512-encoded signature. - * - * @throws InvalidKeyException - * If the key is not a valid Base64-encoded string. - */ - public abstract String computeHmac512(String value) throws InvalidKeyException; - - /** - * Computes a signature for the specified string using the HMAC-SHA512 algorithm with the specified operation - * context. - * - * @param value - * The UTF-8-encoded string to sign. - * - * @param opContext - * An {@link OperationContext} object that 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. - * - * @return A String that contains the HMAC-SHA512-encoded signature. - * - * @throws InvalidKeyException - * If the key is not a valid Base64-encoded string. - */ - public abstract String computeHmac512(String value, OperationContext opContext) throws InvalidKeyException; - - // - // RESERVED, for internal use only. Gets a value indicating whether the - // TransformUri method should be called to transform a resource - // URI to a URI that includes a token for a shared access signature. - // - // @return True if the URI must be transformed; otherwise, - // false - // - /** Reserved. */ - public abstract boolean doCredentialsNeedTransformUri(); - - /** - * Returns the associated account name for the credentials. - * - * @return A String that represents the associated account name for the credentials - */ - public abstract String getAccountName(); - - /** - * Signs a request under the Shared Key authentication scheme. - * - * @deprecated This method has been deprecated. Please use either {@link signBlobAndQueueRequest} or - * {@link signBlobAndQueueRequestLite}, depending on your desired shared key authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * - * @throws InvalidKeyException - * If the given key is invalid. - * - * @throws StorageException - * If a storage service error occurred. - */ - @Deprecated - public abstract void signRequest(HttpURLConnection request, long contentLength) throws InvalidKeyException, - StorageException; - - /** - * Signs a request using the specified operation context under the Shared Key authentication scheme. - * - * @deprecated This method has been deprecated. Please use either {@link signBlobAndQueueRequest} or - * {@link signBlobAndQueueRequestLite}, depending on your desired shared key authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * @param opContext - * An {@link OperationContext} object that 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 InvalidKeyException - * If the given key is invalid. - * @throws StorageException - * If a storage service error occurred. - */ - @Deprecated - public abstract void signRequest(HttpURLConnection request, long contentLength, OperationContext opContext) - throws InvalidKeyException, StorageException; - - /** - * Signs a table request under the Shared Key Lite authentication scheme. - * - * @deprecated This method has been deprecated. Please use either {@link signTableRequest} or - * {@link signTableRequestLite}, depending on your desired shared key authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * - * @throws InvalidKeyException - * If the given key is invalid. - * @throws StorageException - * If an unspecified storage exception occurs. - */ - @Deprecated - public abstract void signRequestLite(HttpURLConnection request, long contentLength) throws StorageException, - InvalidKeyException; - - /** - * Signs a table request using the specified operation context under the Shared Key Lite authentication scheme. - * - * @deprecated This method has been deprecated. Please use either {@link signTableRequest} or - * {@link signTableRequestLite}, depending on your desired shared key authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * @param opContext - * An {@link OperationContext} object that 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 InvalidKeyException - * If the given key is invalid. - * @throws StorageException - * If a storage service error occurred. - */ - @Deprecated - public abstract void signRequestLite(HttpURLConnection request, long contentLength, OperationContext opContext) - throws StorageException, InvalidKeyException; - - /** - * Signs a request under the Shared Key authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * - * @throws InvalidKeyException - * If the given key is invalid. - * - * @throws StorageException - * If a storage service error occurred. - */ - public abstract void signBlobAndQueueRequest(HttpURLConnection request, long contentLength) - throws InvalidKeyException, StorageException; - - /** - * Signs a request using the specified operation context under the Shared Key authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * @param opContext - * An {@link OperationContext} object that 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 InvalidKeyException - * If the given key is invalid. - * @throws StorageException - * If a storage service error occurred. - */ - public abstract void signBlobAndQueueRequest(HttpURLConnection request, long contentLength, - OperationContext opContext) throws InvalidKeyException, StorageException; - - /** - * Signs a request under the Shared Key Lite authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * - * @throws InvalidKeyException - * If the given key is invalid. - * @throws StorageException - * If an unspecified storage exception occurs. - */ - public abstract void signBlobAndQueueRequestLite(HttpURLConnection request, long contentLength) - throws StorageException, InvalidKeyException; - - /** - * Signs a request using the specified operation context under the Shared Key Lite authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * @param opContext - * An {@link OperationContext} object that 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 InvalidKeyException - * If the given key is invalid. - * @throws StorageException - * If a storage service error occurred. - */ - public abstract void signBlobAndQueueRequestLite(HttpURLConnection request, long contentLength, - OperationContext opContext) throws StorageException, InvalidKeyException; - - /** - * Signs a table request under the Shared Key authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * - * @throws InvalidKeyException - * If the given key is invalid. - * - * @throws StorageException - * If a storage service error occurred. - */ - public abstract void signTableRequest(HttpURLConnection request, long contentLength) throws InvalidKeyException, - StorageException; - - /** - * Signs a table request using the specified operation context under the Shared Key authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * @param opContext - * An {@link OperationContext} object that 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 InvalidKeyException - * If the given key is invalid. - * @throws StorageException - * If a storage service error occurred. - */ - public abstract void signTableRequest(HttpURLConnection request, long contentLength, OperationContext opContext) - throws InvalidKeyException, StorageException; - - /** - * Signs a table request under the Shared Key Lite authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * - * @throws InvalidKeyException - * If the given key is invalid. - * @throws StorageException - * If an unspecified storage exception occurs. - */ - public abstract void signTableRequestLite(HttpURLConnection request, long contentLength) throws StorageException, - InvalidKeyException; - - /** - * Signs a table request using the specified operation context under the Shared Key Lite authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * @param opContext - * An {@link OperationContext} object that 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 InvalidKeyException - * If the given key is invalid. - * @throws StorageException - * If a storage service error occurred. - */ - - public abstract void signTableRequestLite(HttpURLConnection request, long contentLength, OperationContext opContext) - throws StorageException, InvalidKeyException; - - /** - * Returns a String that represents this instance. - * - * @param exportSecrets - * true to include sensitive data in the return string; otherwise, false. - * @return A String that represents this object, optionally including sensitive data. - */ - public abstract String toString(boolean exportSecrets); - - /** - * Transforms a resource URI into a shared access signature URI, by appending a shared access token. - * - * @param resourceUri - * A java.net.URI object that represents the resource URI to be transformed. - * - * @return A java.net.URI object that represents the signature, including the resource URI and the - * shared access token. - * - * @throws StorageException - * If a storage service error occurred. - * @throws URISyntaxException - * If the resource URI is not properly formatted. - */ - public abstract URI transformUri(URI resourceUri) throws URISyntaxException, StorageException; - - /** - * Transforms a resource URI into a shared access signature URI, by appending a shared access token. - * - * @param resourceUri - * A StorageUri object that represents the resource URI to be transformed. - * - * @return A StorageUri object that represents the signature, including the resource URI and the - * shared access token. - * - * @throws StorageException - * If a storage service error occurred. - * @throws URISyntaxException - * If the resource URI is not properly formatted. - */ - public StorageUri transformUri(StorageUri resourceUri) throws URISyntaxException, StorageException { - return this.transformUri(resourceUri, null /* opContext */); - } - - /** - * Transforms a resource URI into a shared access signature URI, by appending a shared access token and using the - * specified operation context. - * - * @param resourceUri - * A java.net.URI object that represents the resource URI to be transformed. - * @param opContext - * An {@link OperationContext} object that 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. - * - * @return A java.net.URI object that represents the signature, including the resource URI and the - * shared access token. - * - * @throws StorageException - * If a storage service error occurred. - * @throws URISyntaxException - * If the resource URI is not properly formatted. - */ - public abstract URI transformUri(URI resourceUri, OperationContext opContext) throws URISyntaxException, - StorageException; - - /** - * Transforms a resource URI into a shared access signature URI, by appending a shared access token and using the - * specified operation context. - * - * @param resourceUri - * A StorageUri object that represents the resource URI to be transformed. - * @param opContext - * An {@link OperationContext} object that 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. - * - * @return A StorageUri object that represents the signature, including the resource URI and the - * shared access token. - * - * @throws StorageException - * If a storage service error occurred. - * @throws URISyntaxException - * If the resource URI is not properly formatted. - */ - public StorageUri transformUri(StorageUri resourceUri, OperationContext opContext) throws URISyntaxException, - StorageException { - return new StorageUri(this.transformUri(resourceUri.getPrimaryUri(), opContext), this.transformUri( - resourceUri.getSecondaryUri(), opContext)); - } - -} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageCredentialsAccountAndKey.java b/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageCredentialsAccountAndKey.java deleted file mode 100644 index e954f03a43235..0000000000000 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageCredentialsAccountAndKey.java +++ /dev/null @@ -1,573 +0,0 @@ -/** - * 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.windowsazure.storage; - -import java.net.URI; -import java.net.URISyntaxException; -import java.security.InvalidKeyException; - -import com.microsoft.windowsazure.storage.core.Base64; -import com.microsoft.windowsazure.storage.core.BaseRequest; - -/** - * Represents storage account credentials, based on storage account and access key, for accessing the Windows Azure - * storage services. - */ -public final class StorageCredentialsAccountAndKey extends StorageCredentials { - - /** - * The internal Credentials associated with the StorageCredentials. - */ - private Credentials credentials; - - /** - * Creates an instance of the StorageCredentialsAccountAndKey class, using the specified storage - * account name and access key; the specified access key is in the form of a byte array. - * - * @param accountName - * A String that represents the name of the storage account. - * @param key - * An array of bytes that represent the account access key. - */ - public StorageCredentialsAccountAndKey(final String accountName, final byte[] key) { - this.credentials = new Credentials(accountName, key); - } - - /** - * Creates an instance of the StorageCredentialsAccountAndKey class, using the specified storage - * account name and access key; the specified access key is stored as a String. - * - * @param accountName - * A String that represents the name of the storage account. - * @param key - * A String that represents the Base-64-encoded account access key. - */ - public StorageCredentialsAccountAndKey(final String accountName, final String key) { - this(accountName, Base64.decode(key)); - } - - // - // RESERVED, for internal use only. Gets a value indicating whether the - // ComputeHmac method will return a valid HMAC-encoded - // signature string when called using the specified credentials. - // - // @return True - // - /** Reserved. */ - @Override - public boolean canCredentialsComputeHmac() { - return true; - } - - // - // RESERVED, for internal use only. Gets a value indicating whether a - // request can be signed under the Shared Key authentication scheme using - // the specified credentials. - // - // @return True - // - /** Reserved. */ - @Override - public boolean canCredentialsSignRequest() { - return true; - } - - // - // RESERVED, for internal use only. Gets a value indicating whether a - // request can be signed under the Shared Key Lite authentication scheme - // using the specified credentials. - // - // @return True - // - /** Reserved. */ - @Override - public boolean canCredentialsSignRequestLite() { - return true; - } - - /** - * Computes a signature for the specified string using the HMAC-SHA256 algorithm. - * - * @param value - * The UTF-8-encoded string to sign. - * - * @return A String that contains the HMAC-SHA256-encoded signature. - * - * @throws InvalidKeyException - * If the key is not a valid Base64-encoded string. - */ - @Override - public String computeHmac256(final String value) throws InvalidKeyException { - return this.computeHmac256(value, null); - } - - /** - * Computes a signature for the specified string using the HMAC-SHA256 algorithm with the specified operation - * context. - * - * @param value - * The UTF-8-encoded string to sign. - * @param opContext - * An {@link OperationContext} object that 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. - * - * @return A String that contains the HMAC-SHA256-encoded signature. - * - * @throws InvalidKeyException - * If the key is not a valid Base64-encoded string. - */ - @Override - public String computeHmac256(final String value, final OperationContext opContext) throws InvalidKeyException { - return StorageKey.computeMacSha256(this.credentials.getKey(), value); - } - - /** - * Computes a signature for the specified string using the HMAC-SHA512 algorithm. - * - * @param value - * The UTF-8-encoded string to sign. - * - * @return A String that contains the HMAC-SHA512-encoded signature. - * - * @throws InvalidKeyException - * If the key is not a valid Base64-encoded string. - */ - @Override - public String computeHmac512(final String value) throws InvalidKeyException { - return this.computeHmac512(value, null); - } - - /** - * Computes a signature for the specified string using the HMAC-SHA512 algorithm with the specified operation - * context. - * - * @param value - * The UTF-8-encoded string to sign. - * - * @param opContext - * An {@link OperationContext} object that 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. - * - * @return A String that contains the HMAC-SHA512-encoded signature. - * - * @throws InvalidKeyException - * If the key is not a valid Base64-encoded string. - */ - @Override - public String computeHmac512(final String value, final OperationContext opContext) throws InvalidKeyException { - return StorageKey.computeMacSha512(this.credentials.getKey(), value); - } - - // - // RESERVED, for internal use only. Gets a value indicating whether the - // TransformUri method should be called to transform a resource - // URI to a URI that includes a token for a shared access signature. - // - // @return False. - // - /** Reserved. */ - @Override - public boolean doCredentialsNeedTransformUri() { - return false; - } - - /** - * Returns the associated account name for the credentials. - * - * @return A String that contains the account name for the credentials. - */ - @Override - public String getAccountName() { - return this.credentials.getAccountName(); - } - - /** - * Internal usage. - * Gets the name of the key used by these credentials. - */ - public String getAccountKeyName() { - return this.credentials.getKeyName(); - } - - /** - * Internal usage. - * Sets the account name that owns the key to use when signing requests. - */ - public void setSigningAccountName(final String signingAccountName) { - this.credentials.setSigningAccountName(signingAccountName); - } - - /** - * Returns the Base64-encoded key for the credentials. - * - * @return A String that contains the Base64-encoded key. - */ - protected String getBase64EncodedKey() { - return this.credentials.getKey().getBase64EncodedKey(); - } - - /** - * Returns the internal credentials associated with the storage credentials. - * - * @return A Credentials object that contains the internal credentials associated with this instance of - * the StorageCredentialsAccountAndKey class. - */ - public Credentials getCredentials() { - return this.credentials; - } - - /** - * Sets the credentials. - * - * @param credentials - * A Credentials object that represents the credentials to set for this instance of the - * StorageCredentialsAccountAndKey class. - */ - public void setCredentials(final Credentials credentials) { - this.credentials = credentials; - } - - /** - * Signs a request under the Shared Key authentication scheme. - * - * @deprecated This method has been deprecated. Please use either {@link signBlobAndQueueRequest} or - * {@link signBlobAndQueueRequestLite}, depending on your desired shared key authentication scheme. - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * - * @throws InvalidKeyException - * If the given key is invalid. - * @throws StorageException - * If a storage service error occurred. - */ - @Override - @Deprecated - public void signRequest(final java.net.HttpURLConnection request, final long contentLength) - throws InvalidKeyException, StorageException { - this.signBlobAndQueueRequest(request, contentLength, null); - } - - /** - * Signs a request using the specified operation context under the Shared Key authentication scheme. - * - * @deprecated This method has been deprecated. Please use either {@link signBlobAndQueueRequest} or - * {@link signBlobAndQueueRequestLite}, depending on your desired shared key authentication scheme. - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * @param opContext - * An {@link OperationContext} object that 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 InvalidKeyException - * If the given key is invalid. - * @throws StorageException - * If a storage service error occurred. - */ - @Override - @Deprecated - public void signRequest(final java.net.HttpURLConnection request, final long contentLength, - OperationContext opContext) throws InvalidKeyException, StorageException { - opContext = opContext == null ? new OperationContext() : opContext; - BaseRequest.signRequestForBlobAndQueue(request, this.credentials, contentLength, opContext); - } - - /** - * Signs a request using the Shared Key Lite authentication scheme. - * - * @deprecated This method has been deprecated. Please use either {@link signTableRequest} or - * {@link signTableRequestLite}, depending on your desired shared key authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * - * @throws InvalidKeyException - * If the given key is invalid. - * @throws StorageException - * If an unspecified storage exception occurs. - */ - @Override - @Deprecated - public void signRequestLite(final java.net.HttpURLConnection request, final long contentLength) - throws InvalidKeyException, StorageException { - this.signTableRequestLite(request, contentLength, null); - } - - /** - * Signs a request using the specified operation context under the Shared Key Lite authentication scheme. - * - * @deprecated This method has been deprecated. Please use either {@link signTableRequest} or - * {@link signTableRequestLite}, depending on your desired shared key authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * @param opContext - * An {@link OperationContext} object that 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 InvalidKeyException - * If the given key is invalid. - * @throws StorageException - * If a storage service error occurred. - */ - @Override - @Deprecated - public void signRequestLite(final java.net.HttpURLConnection request, final long contentLength, - OperationContext opContext) throws StorageException, InvalidKeyException { - opContext = opContext == null ? new OperationContext() : opContext; - BaseRequest.signRequestForTableSharedKeyLite(request, this.credentials, contentLength, opContext); - } - - /** - * Signs a request under the Shared Key authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * - * @throws InvalidKeyException - * If the given key is invalid. - * @throws StorageException - * If a storage service error occurred. - */ - @Override - public void signBlobAndQueueRequest(final java.net.HttpURLConnection request, final long contentLength) - throws InvalidKeyException, StorageException { - this.signBlobAndQueueRequest(request, contentLength, null); - } - - /** - * Signs a request using the specified operation context under the Shared Key authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * @param opContext - * An {@link OperationContext} object that 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 InvalidKeyException - * If the given key is invalid. - * @throws StorageException - * If a storage service error occurred. - */ - @Override - public void signBlobAndQueueRequest(final java.net.HttpURLConnection request, final long contentLength, - OperationContext opContext) throws InvalidKeyException, StorageException { - opContext = opContext == null ? new OperationContext() : opContext; - BaseRequest.signRequestForBlobAndQueue(request, this.credentials, contentLength, opContext); - } - - /** - * Signs a request using the Shared Key Lite authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * - * @throws InvalidKeyException - * If the given key is invalid. - * @throws StorageException - * If an unspecified storage exception occurs. - */ - @Override - public void signBlobAndQueueRequestLite(final java.net.HttpURLConnection request, final long contentLength) - throws InvalidKeyException, StorageException { - this.signBlobAndQueueRequestLite(request, contentLength, null); - } - - /** - * Signs a request using the specified operation context under the Shared Key Lite authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * @param opContext - * An {@link OperationContext} object that 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 InvalidKeyException - * If the given key is invalid. - * @throws StorageException - * If a storage service error occurred. - */ - @Override - public void signBlobAndQueueRequestLite(final java.net.HttpURLConnection request, final long contentLength, - OperationContext opContext) throws StorageException, InvalidKeyException { - opContext = opContext == null ? new OperationContext() : opContext; - BaseRequest.signRequestForBlobAndQueueSharedKeyLite(request, this.credentials, contentLength, opContext); - } - - /** - * Signs a request under the Shared Key authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * - * @throws InvalidKeyException - * If the given key is invalid. - * @throws StorageException - * If a storage service error occurred. - */ - @Override - public void signTableRequest(final java.net.HttpURLConnection request, final long contentLength) - throws InvalidKeyException, StorageException { - this.signTableRequest(request, contentLength, null); - } - - /** - * Signs a request using the specified operation context under the Shared Key authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * @param opContext - * An {@link OperationContext} object that 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 InvalidKeyException - * If the given key is invalid. - * @throws StorageException - * If a storage service error occurred. - */ - @Override - public void signTableRequest(final java.net.HttpURLConnection request, final long contentLength, - OperationContext opContext) throws InvalidKeyException, StorageException { - opContext = opContext == null ? new OperationContext() : opContext; - BaseRequest.signRequestForTableSharedKey(request, this.credentials, contentLength, opContext); - } - - /** - * Signs a request using the Shared Key Lite authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * - * @throws InvalidKeyException - * If the given key is invalid. - * @throws StorageException - * If an unspecified storage exception occurs. - */ - @Override - public void signTableRequestLite(final java.net.HttpURLConnection request, final long contentLength) - throws InvalidKeyException, StorageException { - this.signTableRequestLite(request, contentLength, null); - } - - /** - * Signs a request using the specified operation context under the Shared Key Lite authentication scheme. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * @param opContext - * An {@link OperationContext} object that 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 InvalidKeyException - * If the given key is invalid. - * @throws StorageException - * If a storage service error occurred. - */ - @Override - public void signTableRequestLite(final java.net.HttpURLConnection request, final long contentLength, - OperationContext opContext) throws StorageException, InvalidKeyException { - opContext = opContext == null ? new OperationContext() : opContext; - BaseRequest.signRequestForTableSharedKeyLite(request, this.credentials, contentLength, opContext); - } - - /** - * Returns a String that represents this instance, optionally including sensitive data. - * - * @param exportSecrets - * true to include sensitive data in the return string; otherwise, false. - * - * @return A String that represents this object, optionally including sensitive data. - */ - @Override - public String toString(final boolean exportSecrets) { - return String.format("%s=%s;%s=%s", CloudStorageAccount.ACCOUNT_NAME_NAME, this.getAccountName(), - CloudStorageAccount.ACCOUNT_KEY_NAME, exportSecrets ? this.credentials.getKey().getBase64EncodedKey() - : "[key hidden]"); - } - - /** - * Transforms a resource URI into a shared access signature URI, by appending a shared access token. - * - * @param resourceUri - * A java.net.URI object that represents the resource URI to be transformed. - * - * @return A java.net.URI object that represents the signature, including the resource URI and the - * shared access token. - * - * @throws StorageException - * If a storage service error occurred. - * @throws URISyntaxException - * If the resource URI is not properly formatted. - */ - @Override - public URI transformUri(final URI resourceUri) { - return this.transformUri(resourceUri, null /* opContext */); - } - - /** - * Transforms a resource URI into a shared access signature URI, by appending a shared access token and using the - * specified operation context. - * - * @param resourceUri - * A java.net.URI object that represents the resource URI to be transformed. - * @param opContext - * An {@link OperationContext} object that 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. - * - * @return A java.net.URI object that represents the signature, including the resource URI and the - * shared access token. - * - * @throws StorageException - * If a storage service error occurred. - * @throws URISyntaxException - * If the resource URI is not properly formatted. - */ - @Override - public URI transformUri(final URI resourceUri, final OperationContext opContext) { - return resourceUri; - } -} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageCredentialsAnonymous.java b/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageCredentialsAnonymous.java deleted file mode 100644 index 4ab434cee1350..0000000000000 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageCredentialsAnonymous.java +++ /dev/null @@ -1,415 +0,0 @@ -/** - * 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.windowsazure.storage; - -import java.net.URI; - -/** - * *RESERVED FOR INTERNAL USE* Represents credentials for anonymous access. This class is used by the internal - * implementation (not a public class, so its comments are not built into the Javadoc output). - */ -public final class StorageCredentialsAnonymous extends StorageCredentials { - - /** - * Stores the singleton instance of this class. - */ - public static final StorageCredentials ANONYMOUS = new StorageCredentialsAnonymous(); - - /** - * Returns the singleton instance of the StorageCredentials class. - * - * @return the singleton instance of this class - */ - protected static StorageCredentials getInstance() { - return StorageCredentialsAnonymous.ANONYMOUS; - } - - /** - * Enforces the singleton pattern via a private constructor. - */ - protected StorageCredentialsAnonymous() { - // Empty Default Ctor - } - - // - // RESERVED, for internal use only. Gets a value indicating whether the - // ComputeHmac method will return a valid HMAC-encoded - // signature string when called using the specified credentials. - // - // @return False - // - /** Reserved. */ - @Override - public boolean canCredentialsComputeHmac() { - return false; - } - - // - // RESERVED, for internal use only. Gets a value indicating whether a - // request can be signed under the Shared Key authentication scheme using - // the specified credentials. - // - // @return False - // - /** Reserved. */ - @Override - public boolean canCredentialsSignRequest() { - return false; - } - - // - // RESERVED, for internal use only. Gets a value indicating whether a - // request can be signed under the Shared Key Lite authentication scheme - // using the specified credentials. - // - // @return False - // - /** Reserved. */ - @Override - public boolean canCredentialsSignRequestLite() { - return false; - } - - /** - * Encodes a Shared Key or Shared Key Lite signature string by using the HMAC-SHA256 algorithm over a UTF-8-encoded - * string-to-sign. This is not a valid operation for objects of type StorageCredentialsAnonymous so the - * method merely returns null. - * - * @param value - * the UTF-8-encoded string-to-sign - * @return null for objects of type StorageCredentialsAnonymous - */ - @Override - public String computeHmac256(final String value) { - return null; - } - - /** - * Encodes a Shared Key or Shared Key Lite signature string by using the HMAC-SHA256 algorithm over a UTF-8-encoded - * string-to-sign and the specified operation context. This is not a valid operation for objects of type - * StorageCredentialsAnonymous so the method merely returns null. - * - * @param value - * the UTF-8-encoded string-to-sign - * @param opContext - * an operation context, as a {@link com.microsoft.windowsazure.storage.OperationContext} object, - * that represents the current operation - * @return null for objects of type StorageCredentialsAnonymous - */ - @Override - public String computeHmac256(final String value, final OperationContext opContext) { - return null; - } - - /** - * Encodes a Shared Key signature string by using the HMAC-SHA512 algorithm over a UTF-8-encoded string-to-sign. - * This is not a valid operation for objects of type StorageCredentialsAnonymous so the method merely - * returns null. - * - * @param value - * the UTF-8-encoded string-to-sign - * @return null for objects of type StorageCredentialsAnonymous - */ - @Override - public String computeHmac512(final String value) { - return null; - } - - /** - * Encodes a Shared Key signature string by using the HMAC-SHA256 algorithm over a UTF-8-encoded string-to-sign. - * This is not a valid operation for objects of type StorageCredentialsAnonymous so the method merely - * returns null. - * - * @param value - * the UTF-8-encoded string-to-sign - * @param opContext - * an operation context, as a {@link com.microsoft.windowsazure.storage.OperationContext} object, - * that represents the current operation - * - * @return null for objects of type StorageCredentialsAnonymous - */ - @Override - public String computeHmac512(final String value, final OperationContext opContext) { - return null; - } - - // - // RESERVED, for internal use only. Gets a value indicating whether the - // TransformUri method should be called to transform a resource - // URI to a URI that includes a token for a shared access signature. - // - // @return False. - // - /** Reserved. */ - @Override - public boolean doCredentialsNeedTransformUri() { - return false; - } - - /** - * Returns the associated account name for the credentials. This is null for anonymous credentials. - * - * @return null for anonymous credentials - */ - @Override - public String getAccountName() { - return null; - } - - /** - * Signs a request using the specified credentials under the Shared Key authentication scheme. This is not a valid - * operation for objects of type StorageCredentialsAnonymous so the method performs a no-op. - * - * @deprecated This method has been deprecated. Please use either {@link signBlobAndQueueRequest} or - * {@link signBlobAndQueueRequestLite}, depending on your desired shared key authentication scheme. - * - * @param connection - * the request, as an HttpURLConnection object, to sign - * @param contentLength - * the length of the content written to the output stream. If unknown, specify -1. - */ - @Override - @Deprecated - public void signRequest(final java.net.HttpURLConnection connection, final long contentLength) { - // No op - } - - /** - * Signs a request using the specified credentials and operation context under the Shared Key authentication scheme. - * This is not a valid operation for objects of type StorageCredentialsAnonymous so the method performs - * a no-op. - * - * @deprecated This method has been deprecated. Please use either {@link signBlobAndQueueRequest} or - * {@link signBlobAndQueueRequestLite}, depending on your desired shared key authentication scheme. - * - * @param request - * the request, as an HttpURLConnection object, to sign - * @param contentLength - * the length of the content written to the output stream. If unknown, specify -1. - * @param opContext - * an operation context, as a {@link com.microsoft.windowsazure.storage.OperationContext} object, - * that represents the current operation - */ - @Override - @Deprecated - public void signRequest(final java.net.HttpURLConnection request, final long contentLength, - final OperationContext opContext) { - // No op - } - - /** - * Signs a request using the specified credentials under the Shared Key Lite authentication scheme. This is not a - * valid operation for objects of type StorageCredentialsAnonymous so the method performs a no-op. - * - * @deprecated This method has been deprecated. Please use either {@link signTableRequest} or - * {@link signTableRequestLite}, depending on your desired shared key authentication scheme. - * - * @param connection - * the request, as an HttpURLConnection object, to sign - */ - @Override - @Deprecated - public void signRequestLite(final java.net.HttpURLConnection connection, final long contentLength) { - // No op - } - - /** - * Signs a request using the specified credentials under the Shared Key Lite authentication scheme. This is not a - * valid operation for objects of type StorageCredentialsSharedAccessSignature so the method performs a - * no-op. - * - * @deprecated This method has been deprecated. Please use either {@link signTableRequest} or - * {@link signTableRequestLite}, depending on your desired shared key authentication scheme. - * - * @param request - * the request, as an HttpURLConnection object, to sign - * @param opContext - * an operation context, as a {@link com.microsoft.windowsazure.storage.OperationContext} object, - * that represents the current operation - */ - @Override - @Deprecated - public void signRequestLite(final java.net.HttpURLConnection request, final long contentLength, - final OperationContext opContext) { - // No op - } - - /** - * Signs a request using the specified credentials under the Shared Key authentication scheme. This is not a valid - * operation for objects of type StorageCredentialsAnonymous so the method performs a no-op. - * - * @param connection - * the request, as an HttpURLConnection object, to sign - * @param contentLength - * the length of the content written to the output stream. If unknown, specify -1. - */ - @Override - public void signBlobAndQueueRequest(final java.net.HttpURLConnection connection, final long contentLength) { - // No op - } - - /** - * Signs a request using the specified credentials and operation context under the Shared Key authentication scheme. - * This is not a valid operation for objects of type StorageCredentialsAnonymous so the method performs - * a no-op. - * - * @param request - * the request, as an HttpURLConnection object, to sign - * @param contentLength - * the length of the content written to the output stream. If unknown, specify -1. - * @param opContext - * an operation context, as a {@link com.microsoft.windowsazure.storage.OperationContext} object, - * that represents the current operation - */ - @Override - public void signBlobAndQueueRequest(final java.net.HttpURLConnection request, final long contentLength, - final OperationContext opContext) { - // No op - } - - /** - * Signs a request using the specified credentials under the Shared Key Lite authentication scheme. This is not a - * valid operation for objects of type StorageCredentialsAnonymous so the method performs a no-op. - * - * @param connection - * the request, as an HttpURLConnection object, to sign - */ - @Override - public void signBlobAndQueueRequestLite(final java.net.HttpURLConnection connection, final long contentLength) { - // No op - } - - /** - * Signs a request using the specified credentials under the Shared Key Lite authentication scheme. This is not a - * valid operation for objects of type StorageCredentialsSharedAccessSignature so the method performs a - * no-op. - * - * @param request - * the request, as an HttpURLConnection object, to sign - * @param opContext - * an operation context, as a {@link com.microsoft.windowsazure.storage.OperationContext} object, - * that represents the current operation - */ - @Override - public void signBlobAndQueueRequestLite(final java.net.HttpURLConnection request, final long contentLength, - final OperationContext opContext) { - // No op - } - - /** - * Signs a request using the specified credentials under the Shared Key authentication scheme. This is not a valid - * operation for objects of type StorageCredentialsAnonymous so the method performs a no-op. - * - * @param connection - * the request, as an HttpURLConnection object, to sign - * @param contentLength - * the length of the content written to the output stream. If unknown, specify -1. - */ - @Override - public void signTableRequest(final java.net.HttpURLConnection connection, final long contentLength) { - // No op - } - - /** - * Signs a request using the specified credentials and operation context under the Shared Key authentication scheme. - * This is not a valid operation for objects of type StorageCredentialsAnonymous so the method performs - * a no-op. - * - * @param request - * the request, as an HttpURLConnection object, to sign - * @param contentLength - * the length of the content written to the output stream. If unknown, specify -1. - * @param opContext - * an operation context, as a {@link com.microsoft.windowsazure.storage.OperationContext} object, - * that represents the current operation - */ - @Override - public void signTableRequest(final java.net.HttpURLConnection request, final long contentLength, - final OperationContext opContext) { - // No op - } - - /** - * Signs a request using the specified credentials under the Shared Key Lite authentication scheme. This is not a - * valid operation for objects of type StorageCredentialsAnonymous so the method performs a no-op. - * - * @param connection - * the request, as an HttpURLConnection object, to sign - */ - @Override - public void signTableRequestLite(final java.net.HttpURLConnection connection, final long contentLength) { - // No op - } - - /** - * Signs a request using the specified credentials under the Shared Key Lite authentication scheme. This is not a - * valid operation for objects of type StorageCredentialsSharedAccessSignature so the method performs a - * no-op. - * - * @param request - * the request, as an HttpURLConnection object, to sign - * @param opContext - * an operation context, as a {@link com.microsoft.windowsazure.storage.OperationContext} object, - * that represents the current operation - */ - @Override - public void signTableRequestLite(final java.net.HttpURLConnection request, final long contentLength, - final OperationContext opContext) { - // No op - } - - /** - * Returns a String object that represents this instance. - * - * @param exportSecrets - * true to include sensitive data in the string; otherwise, false - * @return a string representation of the credentials, optionally including sensitive data. - */ - @Override - public String toString(final boolean exportSecrets) { - return Constants.EMPTY_STRING; - } - - /** - * Transforms a resource URI into a shared access signature URI, by appending a shared access token. No transform - * occurs for anonymous credentials, so this method returns the same URI that is passed in. - * - * @param resourceUri - * the resource URI to be transformed - * @return the unmodified value passed in for the resourceUri parameter - */ - @Override - public URI transformUri(final URI resourceUri) { - return this.transformUri(resourceUri, null); - } - - /** - * Transforms a resource URI into a shared access signature URI, by appending a shared access token. No transform - * occurs for anonymous credentials, so this method returns the same URI that is passed in. - * - * @param resourceUri - * the resource URI to be transformed - * @param opContext - * the an operation context, as a {@link com.microsoft.windowsazure.storage.OperationContext} - * object, that represents the - * current operation - * - * @return the unmodified value passed in for the resourceUri parameter - */ - @Override - public URI transformUri(final URI resourceUri, final OperationContext opContext) { - return resourceUri; - } -} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageCredentialsSharedAccessSignature.java b/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageCredentialsSharedAccessSignature.java deleted file mode 100644 index 0440b8dda6e38..0000000000000 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/StorageCredentialsSharedAccessSignature.java +++ /dev/null @@ -1,460 +0,0 @@ -/** - * 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.windowsazure.storage; - -import java.net.URI; -import java.net.URISyntaxException; - -import com.microsoft.windowsazure.storage.core.PathUtility; - -/** - * Represents storage credentials for delegated access to Blob service resources via a shared access signature. - */ -public final class StorageCredentialsSharedAccessSignature extends StorageCredentials { - - /** - * Stores the shared access signature token. - */ - private final String token; - - /** - * Creates an instance of the StorageCredentialsSharedAccessSignature class using the specified shared - * access signature token. - * - * @param token - * A String that represents shared access signature token. - */ - public StorageCredentialsSharedAccessSignature(final String token) { - this.token = token; - } - - // - // RESERVED, for internal use only. Gets a value indicating whether the - // ComputeHmac method will return a valid HMAC-encoded - // signature string when called using the specified credentials. - // - // @return False - // - /** Reserved. */ - @Override - public boolean canCredentialsComputeHmac() { - return false; - } - - // - // RESERVED, for internal use only. Gets a value indicating whether a - // request can be signed under the Shared Key authentication scheme using - // the specified credentials. - // - // @return False - // - /** Reserved. */ - @Override - public boolean canCredentialsSignRequest() { - return false; - } - - // - // RESERVED, for internal use only. Gets a value indicating whether a - // request can be signed under the Shared Key Lite authentication scheme - // using the specified credentials. - // - // @return False - // - /** Reserved. */ - @Override - public boolean canCredentialsSignRequestLite() { - return false; - } - - /** - * Computes a signature for the specified string using the HMAC-SHA256 algorithm. This is not a valid operation for - * objects of type StorageCredentialsSharedAccessSignature so the method merely returns - * null. - * - * @param value - * The UTF-8-encoded string to sign. - * - * @return null for objects of type StorageCredentialsSharedAccessSignature. - */ - @Override - public String computeHmac256(final String value) { - return null; - } - - /** - * Computes a signature for the specified string using the HMAC-SHA256 algorithm with the specified operation - * context. This is not a valid operation for objects of type StorageCredentialsSharedAccessSignature - * so the method merely returns null. - * - * @param value - * The UTF-8-encoded string to sign. - * @param opContext - * An {@link OperationContext} object that 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. - * - * @return null for objects of type StorageCredentialsSharedAccessSignature. - */ - @Override - public String computeHmac256(final String value, final OperationContext opContext) { - return null; - } - - /** - * Computes a signature for the specified string using the HMAC-SHA512 algorithm. This is not a valid operation for - * objects of type StorageCredentialsSharedAccessSignature so the method merely returns - * null. - * - * @param value - * The UTF-8-encoded string to sign. - * - * @return null for objects of type StorageCredentialsSharedAccessSignature. - */ - @Override - public String computeHmac512(final String value) { - return null; - } - - /** - * Computes a signature for the specified string using the HMAC-SHA512 algorithm with the specified operation - * context. This is not a valid operation for objects of type StorageCredentialsSharedAccessSignature - * so the method merely returns null. - * - * @param value - * The UTF-8-encoded string to sign. - * - * @param opContext - * An {@link OperationContext} object that 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. - * - * @return null for objects of type StorageCredentialsSharedAccessSignature. - */ - @Override - public String computeHmac512(final String value, final OperationContext opContext) { - return null; - } - - // - // RESERVED, for internal use only. Gets a value indicating whether the - // TransformUri method should be called to transform a resource - // URI to a URI that includes a token for a shared access signature. - // - // @return True. - // - /** Reserved. */ - @Override - public boolean doCredentialsNeedTransformUri() { - return true; - } - - /** - * Returns the associated account name for the credentials. This is not a valid operation for objects of type - * StorageCredentialsSharedAccessSignature so the method merely returns null. - * - * @return null for objects of type StorageCredentialsSharedAccessSignature. - */ - @Override - public String getAccountName() { - return null; - } - - /** - * Returns the shared access signature token. - * - * @return A String that contains the token. - */ - public String getToken() { - return this.token; - } - - /** - * Signs a request using the specified credentials under the Shared Key authentication scheme. This is not a valid - * operation for objects of type StorageCredentialsAnonymous so the method performs a no-op. - * - * @deprecated This method has been deprecated. Please use either {@link signBlobAndQueueRequest} or - * {@link signBlobAndQueueRequestLite}, depending on your desired shared key authentication scheme. - * - * @param connection - * the request, as an HttpURLConnection object, to sign - * @param contentLength - * the length of the content written to the output stream. If unknown, specify -1. - */ - @Override - @Deprecated - public void signRequest(final java.net.HttpURLConnection connection, final long contentLength) { - // No op - } - - /** - * Signs a request using the specified credentials and operation context under the Shared Key authentication scheme. - * This is not a valid operation for objects of type StorageCredentialsAnonymous so the method performs - * a no-op. - * - * @deprecated This method has been deprecated. Please use either {@link signBlobAndQueueRequest} or - * {@link signBlobAndQueueRequestLite}, depending on your desired shared key authentication scheme. - * - * @param request - * the request, as an HttpURLConnection object, to sign - * @param contentLength - * the length of the content written to the output stream. If unknown, specify -1. - * @param opContext - * an operation context, as a {@link com.microsoft.windowsazure.storage.OperationContext} object, - * that represents the current operation - */ - @Override - @Deprecated - public void signRequest(final java.net.HttpURLConnection request, final long contentLength, - final OperationContext opContext) { - // No op - } - - /** - * Signs a request using the specified credentials under the Shared Key Lite authentication scheme. This is not a - * valid operation for objects of type StorageCredentialsAnonymous so the method performs a no-op. - * - * @deprecated This method has been deprecated. Please use either {@link signTableRequest} or - * {@link signTableRequestLite}, depending on your desired shared key authentication scheme. - * - * @param connection - * the request, as an HttpURLConnection object, to sign - */ - @Override - @Deprecated - public void signRequestLite(final java.net.HttpURLConnection connection, final long contentLength) { - // No op - } - - /** - * Signs a request using the specified credentials under the Shared Key Lite authentication scheme. This is not a - * valid operation for objects of type StorageCredentialsSharedAccessSignature so the method performs a - * no-op. - * - * @deprecated This method has been deprecated. Please use either {@link signTableRequest} or - * {@link signTableRequestLite}, depending on your desired shared key authentication scheme. - * - * @param request - * the request, as an HttpURLConnection object, to sign - * @param opContext - * an operation context, as a {@link com.microsoft.windowsazure.storage.OperationContext} object, - * that represents the current operation - */ - @Override - @Deprecated - public void signRequestLite(final java.net.HttpURLConnection request, final long contentLength, - final OperationContext opContext) { - // No op - } - - /** - * Signs a request under the Shared Key authentication scheme. This is not a valid operation for objects of type - * StorageCredentialsSharedAccessSignature so the method performs a no-op. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - */ - @Override - public void signBlobAndQueueRequest(final java.net.HttpURLConnection request, final long contentLength) { - // No op - } - - /** - * Signs a request using the specified operation context under the Shared Key authentication scheme. This is not a - * valid operation for objects of type StorageCredentialsSharedAccessSignature so the method performs a - * no-op. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * @param opContext - * An {@link OperationContext} object that 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. - */ - @Override - public void signBlobAndQueueRequest(final java.net.HttpURLConnection request, final long contentLength, - final OperationContext opContext) { - // No op - } - - /** - * Signs a request under the Shared Key Lite authentication scheme. This is not a valid operation for objects of - * type StorageCredentialsSharedAccessSignature so the method performs a no-op. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - */ - @Override - public void signBlobAndQueueRequestLite(final java.net.HttpURLConnection request, final long contentLength) { - // No op - } - - /** - * Signs a request using the specified operation context under the Shared Key Lite authentication scheme. This is - * not a valid operation for objects of type StorageCredentialsSharedAccessSignature so the method - * performs a no-op. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * @param opContext - * An {@link OperationContext} object that 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. - */ - @Override - public void signBlobAndQueueRequestLite(final java.net.HttpURLConnection request, final long contentLength, - final OperationContext opContext) { - // No op - } - - /** - * Signs a request under the Shared Key authentication scheme. This is not a valid operation for objects of type - * StorageCredentialsSharedAccessSignature so the method performs a no-op. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - */ - @Override - public void signTableRequest(final java.net.HttpURLConnection request, final long contentLength) { - // No op - } - - /** - * Signs a request using the specified operation context under the Shared Key authentication scheme. This is not a - * valid operation for objects of type StorageCredentialsSharedAccessSignature so the method performs a - * no-op. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * @param opContext - * An {@link OperationContext} object that 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. - */ - @Override - public void signTableRequest(final java.net.HttpURLConnection request, final long contentLength, - final OperationContext opContext) { - // No op - } - - /** - * Signs a request under the Shared Key Lite authentication scheme. This is not a valid operation for objects of - * type StorageCredentialsSharedAccessSignature so the method performs a no-op. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - */ - @Override - public void signTableRequestLite(final java.net.HttpURLConnection request, final long contentLength) { - // No op - } - - /** - * Signs a request using the specified operation context under the Shared Key Lite authentication scheme. This is - * not a valid operation for objects of type StorageCredentialsSharedAccessSignature so the method - * performs a no-op. - * - * @param request - * An HttpURLConnection object that represents the request to sign. - * @param contentLength - * The length of the content written to the output stream. If unknown, specify -1. - * @param opContext - * An {@link OperationContext} object that 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. - */ - @Override - public void signTableRequestLite(final java.net.HttpURLConnection request, final long contentLength, - final OperationContext opContext) { - // No op - } - - /** - * Returns a String that represents this instance, optionally including sensitive data. - * - * @param exportSecrets - * true to include sensitive data in the return string; otherwise, false. - * @return A String that represents this object, optionally including sensitive data. - */ - @Override - public String toString(final boolean exportSecrets) { - return String.format("%s=%s", CloudStorageAccount.SHARED_ACCESS_SIGNATURE_NAME, exportSecrets ? this.token - : "[signature hidden]"); - } - - /** - * Transforms a resource URI into a shared access signature URI, by appending a shared access token. - * - * @param resourceUri - * A java.net.URI object that represents the resource URI to be transformed. - * - * @return A java.net.URI object that represents the signature, including the resource URI and the - * shared access token. - * - * @throws IllegalArgumentException - * If a parameter is invalid. - * @throws StorageException - * If a storage service error occurred. - * @throws URISyntaxException - * If the resource URI is not properly formatted. - */ - @Override - public URI transformUri(final URI resourceUri) throws URISyntaxException, StorageException { - return this.transformUri(resourceUri, null); - } - - /** - * Transforms a resource URI into a shared access signature URI, by appending a shared access token and using the - * specified operation context. - * - * @param resourceUri - * A java.net.URI object that represents the resource URI to be transformed. - * @param opContext - * An {@link OperationContext} object that 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. - * - * @return A java.net.URI object that represents the signature, including the resource URI and the - * shared access token. - * - * @throws StorageException - * If a storage service error occurred. - * @throws URISyntaxException - * If the resource URI is not properly formatted. - */ - @Override - public URI transformUri(final URI resourceUri, final OperationContext opContext) throws URISyntaxException, - StorageException { - if (resourceUri == null) { - return null; - } - - return PathUtility.addToQuery(resourceUri, this.token); - } -} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobDeserializer.java b/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobDeserializer.java deleted file mode 100644 index 0ab4d8424628a..0000000000000 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobDeserializer.java +++ /dev/null @@ -1,962 +0,0 @@ -/** - * 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.windowsazure.storage.blob; - -import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.HashMap; - -import javax.xml.stream.XMLStreamConstants; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; - -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.LeaseDuration; -import com.microsoft.windowsazure.storage.LeaseState; -import com.microsoft.windowsazure.storage.LeaseStatus; -import com.microsoft.windowsazure.storage.StorageErrorCodeStrings; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.StorageUri; -import com.microsoft.windowsazure.storage.core.DeserializationHelper; -import com.microsoft.windowsazure.storage.core.ListResponse; -import com.microsoft.windowsazure.storage.core.PathUtility; -import com.microsoft.windowsazure.storage.core.Utility; - -/** - * RESERVED FOR INTERNAL USE. - */ -public class BlobDeserializer { - public static ListBlobsResponse getBlobList(final InputStream stream, final CloudBlobClient serviceClient, - final CloudBlobContainer container) throws XMLStreamException, StorageException { - final XMLStreamReader xmlr = DeserializationHelper.createXMLStreamReaderFromStream(stream); - - final ListBlobsResponse blobs = new ListBlobsResponse(); - - String tempParseString = null; - - // Start document - int eventType = xmlr.getEventType(); - xmlr.require(XMLStreamConstants.START_DOCUMENT, null, null); - - // 1. get enumerationResults Header - eventType = xmlr.next(); - xmlr.require(XMLStreamConstants.START_ELEMENT, null, "EnumerationResults"); - - // check if there are more events in the input stream - while (xmlr.hasNext()) { - eventType = xmlr.next(); - - if (eventType == XMLStreamConstants.START_ELEMENT || eventType == XMLStreamConstants.END_ELEMENT) { - final String name = xmlr.getName().toString(); - if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(Constants.MAX_RESULTS_ELEMENT)) { - tempParseString = DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.MAX_RESULTS_ELEMENT); - blobs.setMaxResults(Integer.parseInt(tempParseString)); - } - else if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(Constants.MARKER_ELEMENT)) { - blobs.setMarker(DeserializationHelper.readElementFromXMLReader(xmlr, Constants.MARKER_ELEMENT)); - } - else if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(Constants.NEXT_MARKER_ELEMENT)) { - blobs.setNextMarker(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.NEXT_MARKER_ELEMENT)); - } - else if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(Constants.PREFIX_ELEMENT)) { - blobs.setPrefix(DeserializationHelper.readElementFromXMLReader(xmlr, Constants.PREFIX_ELEMENT)); - } - else if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(Constants.DELIMITER_ELEMENT)) { - blobs.setDelimiter(DeserializationHelper - .readElementFromXMLReader(xmlr, Constants.DELIMITER_ELEMENT)); - } - else if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(BlobConstants.BLOBS_ELEMENT)) { - try { - blobs.setResults(readBlobItems(xmlr, serviceClient, container)); - } - catch (final URISyntaxException e) { - throw new XMLStreamException(e); - } - catch (final ParseException e) { - throw new XMLStreamException(e); - } - - xmlr.require(XMLStreamConstants.END_ELEMENT, null, BlobConstants.BLOBS_ELEMENT); - } - else if (eventType == XMLStreamConstants.END_ELEMENT && "EnumerationResults".equals(name)) { - break; - } - } - } - - return blobs; - } - - /** - * Reads BlobItems from the XMLStreamReader, reader must be at Start element of BlobsElement - * - * @param xmlr - * the XMLStreamReader to read from - * @param serviceClient - * the CloudBlobClient associated with the objects. - * @param container - * the container associated with the objects. - * @return the BlobItems from the stream - * @throws XMLStreamException - * if there is an error parsing the stream - * @throws ParseException - * if there is an error in parsing a date - * @throws URISyntaxException - * if the uri is invalid - * @throws StorageException - */ - private static ArrayList readBlobItems(final XMLStreamReader xmlr, - final CloudBlobClient serviceClient, final CloudBlobContainer container) throws XMLStreamException, - ParseException, URISyntaxException, StorageException { - int eventType = xmlr.getEventType(); - final ArrayList retBlobs = new ArrayList(); - - xmlr.require(XMLStreamConstants.START_ELEMENT, null, BlobConstants.BLOBS_ELEMENT); - - // check if there are more events in the input stream - while (xmlr.hasNext()) { - eventType = xmlr.next(); - final String name = xmlr.getName().toString(); - - if (eventType == XMLStreamConstants.START_ELEMENT) { - if (name.equals(BlobConstants.BLOB_ELEMENT)) { - retBlobs.add(readBlob(xmlr, serviceClient, container)); - } - else if (name.equals(BlobConstants.BLOB_PREFIX_ELEMENT)) { - retBlobs.add(readDirectory(xmlr, container)); - } - else { - throw new StorageException(StorageErrorCodeStrings.INVALID_XML_DOCUMENT, - "The response received is invalid or improperly formatted.", - Constants.HeaderConstants.HTTP_UNUSED_306, null, null); - } - } - else { - break; - } - } - - xmlr.require(XMLStreamConstants.END_ELEMENT, null, BlobConstants.BLOBS_ELEMENT); - return retBlobs; - } - - /** - * Reserved for internal use. Populates the blob from an XMLStreamReader, reader must be at Start element of Blob - * - * @param xmlr - * the XMLStreamReader to read from - * @param serviceClient - * the CloudBlobClient associated with the objects. - * @throws XMLStreamException - * if there is an error parsing the stream - * @throws ParseException - * if there is an error in parsing a date - * @throws URISyntaxException - * if the uri is invalid - * @throws StorageException - */ - private static CloudBlob readBlob(final XMLStreamReader xmlr, final CloudBlobClient serviceClient, - final CloudBlobContainer container) throws XMLStreamException, ParseException, URISyntaxException, - StorageException { - xmlr.require(XMLStreamConstants.START_ELEMENT, null, BlobConstants.BLOB_ELEMENT); - - String blobName = Constants.EMPTY_STRING; - - String snapshotID = null; - HashMap metadata = null; - BlobProperties properties = null; - - int eventType = xmlr.getEventType(); - // check if there are more events in the input stream - while (xmlr.hasNext()) { - eventType = xmlr.next(); - final String name = xmlr.getName().toString(); - - if (eventType == XMLStreamConstants.START_ELEMENT) { - if (name.equals(Constants.NAME_ELEMENT)) { - blobName = DeserializationHelper.readElementFromXMLReader(xmlr, Constants.NAME_ELEMENT); - } - else if (name.equals(BlobConstants.SNAPSHOT_ELEMENT)) { - snapshotID = DeserializationHelper.readElementFromXMLReader(xmlr, BlobConstants.SNAPSHOT_ELEMENT); - } - else if (name.equals(BlobConstants.PROPERTIES)) { - properties = readBlobProperties(xmlr); - xmlr.require(XMLStreamConstants.END_ELEMENT, null, BlobConstants.PROPERTIES); - } - else if (name.equals(Constants.METADATA_ELEMENT)) { - metadata = DeserializationHelper.parseMetadateFromXML(xmlr); - xmlr.require(XMLStreamConstants.END_ELEMENT, null, Constants.METADATA_ELEMENT); - } - } - else if (eventType == XMLStreamConstants.END_ELEMENT && name.equals(BlobConstants.BLOB_ELEMENT)) { - break; - } - } - - xmlr.require(XMLStreamConstants.END_ELEMENT, null, BlobConstants.BLOB_ELEMENT); - - // Assemble and return - if (properties != null) { - CloudBlob retBlob = null; - - StorageUri blobUri = serviceClient.getStorageUri(); - blobUri = PathUtility.appendPathToUri(blobUri, container.getName()); - blobUri = PathUtility.appendPathToUri(blobUri, blobName); - - if (properties.getBlobType() == BlobType.BLOCK_BLOB) { - retBlob = new CloudBlockBlob(blobUri, serviceClient, container); - } - else if (properties.getBlobType() == BlobType.PAGE_BLOB) { - retBlob = new CloudPageBlob(blobUri, serviceClient, container); - } - else { - throw new StorageException(StorageErrorCodeStrings.INVALID_XML_DOCUMENT, - "The response received is invalid or improperly formatted.", - Constants.HeaderConstants.HTTP_UNUSED_306, null, null); - } - - retBlob.setStorageUri(blobUri); - retBlob.snapshotID = snapshotID; - retBlob.properties = properties; - retBlob.metadata = metadata; - return retBlob; - } - else { - throw new StorageException(StorageErrorCodeStrings.INVALID_XML_DOCUMENT, - "The response received is invalid or improperly formatted.", - Constants.HeaderConstants.HTTP_UNUSED_306, null, null); - } - } - - /** - * Populates the CloudBlobDirectory from an XMLStreamReader, reader must be at Start element of BlobPrefix - * - * @param xmlr - * the XMLStreamReader to read from - * @param serviceClient - * the CloudBlobClient associated with the objects. - * @param container - * the container associated with the objects. - * @return a CloudBlobDirectory parsed from the stream. - * @throws XMLStreamException - * if there is an error parsing the stream - * @throws ParseException - * if there is an error in parsing a date - * @throws URISyntaxException - * if the uri is invalid - * @throws StorageException - */ - private static CloudBlobDirectory readDirectory(final XMLStreamReader xmlr, final CloudBlobContainer container) - throws XMLStreamException, ParseException, URISyntaxException, StorageException { - xmlr.require(XMLStreamConstants.START_ELEMENT, null, BlobConstants.BLOB_PREFIX_ELEMENT); - - // Move to Name element - xmlr.next(); - xmlr.require(XMLStreamConstants.START_ELEMENT, null, Constants.NAME_ELEMENT); - - final String prefixName = DeserializationHelper.readElementFromXMLReader(xmlr, Constants.NAME_ELEMENT); - - // Move from End name element to end prefix element - xmlr.next(); - xmlr.require(XMLStreamConstants.END_ELEMENT, null, BlobConstants.BLOB_PREFIX_ELEMENT); - - return container.getDirectoryReference(prefixName); - } - - /** - * Populates the object from the XMLStreamReader, reader must be at Start element of Properties - * - * @param xmlr - * the XMLStreamReader object - * @return the BlobProperties that was read. - * @throws XMLStreamException - * if there is a parsing exception - * @throws ParseException - * if a date value is not correctly encoded - * @throws StorageException - * @throws URISyntaxException - */ - private static BlobProperties readBlobProperties(final XMLStreamReader xmlr) throws XMLStreamException, - ParseException, StorageException, URISyntaxException { - xmlr.require(XMLStreamConstants.START_ELEMENT, null, BlobConstants.PROPERTIES); - int eventType = xmlr.getEventType(); - final BlobProperties properties = new BlobProperties(); - CopyState copyState = null; - - while (xmlr.hasNext()) { - eventType = xmlr.next(); - final String name = xmlr.getName().toString(); - - if (eventType == XMLStreamConstants.START_ELEMENT) { - if (name.equals(Constants.LAST_MODIFIED_ELEMENT)) { - properties.setLastModified(Utility.parseRFC1123DateFromStringInGMT(DeserializationHelper - .readElementFromXMLReader(xmlr, Constants.LAST_MODIFIED_ELEMENT))); - } - else if (name.equals(Constants.ETAG_ELEMENT)) { - properties.setEtag(DeserializationHelper.readETagFromXMLReader(xmlr)); - } - else if (name.equals(Constants.HeaderConstants.CONTENT_LENGTH)) { - final String tempString = DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.HeaderConstants.CONTENT_LENGTH); - properties.setLength(Long.parseLong(tempString)); - } - else if (name.equals(Constants.HeaderConstants.CONTENT_TYPE)) { - properties.setContentType(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.HeaderConstants.CONTENT_TYPE)); - } - else if (name.equals(Constants.HeaderConstants.CONTENT_ENCODING)) { - properties.setContentEncoding(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.HeaderConstants.CONTENT_ENCODING)); - } - else if (name.equals(Constants.HeaderConstants.CONTENT_LANGUAGE)) { - properties.setContentLanguage(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.HeaderConstants.CONTENT_LANGUAGE)); - } - else if (name.equals(Constants.HeaderConstants.CONTENT_MD5)) { - properties.setContentMD5(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.HeaderConstants.CONTENT_MD5)); - } - else if (name.equals(Constants.HeaderConstants.CACHE_CONTROL)) { - properties.setCacheControl(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.HeaderConstants.CACHE_CONTROL)); - } - else if (name.equals(Constants.HeaderConstants.CONTENT_DISPOSITION)) { - properties.setContentDisposition(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.HeaderConstants.CONTENT_DISPOSITION)); - } - else if (name.equals(BlobConstants.SEQUENCE_NUMBER)) { - DeserializationHelper.readElementFromXMLReader(xmlr, BlobConstants.SEQUENCE_NUMBER); - } - else if (name.equals(BlobConstants.BLOB_TYPE_ELEMENT)) { - final String tempString = DeserializationHelper.readElementFromXMLReader(xmlr, - BlobConstants.BLOB_TYPE_ELEMENT); - if (tempString.equals(BlobConstants.BLOCK_BLOB_VALUE)) { - properties.setBlobType(BlobType.BLOCK_BLOB); - } - else if (tempString.equals(BlobConstants.PAGE_BLOB_VALUE)) { - properties.setBlobType(BlobType.PAGE_BLOB); - } - else { - throw new StorageException(StorageErrorCodeStrings.INVALID_XML_DOCUMENT, - "The response received is invalid or improperly formatted.", - Constants.HeaderConstants.HTTP_UNUSED_306, null, null); - } - } - else if (name.equals(Constants.LEASE_STATUS_ELEMENT)) { - final LeaseStatus tempStatus = LeaseStatus.parse(DeserializationHelper.readElementFromXMLReader( - xmlr, Constants.LEASE_STATUS_ELEMENT)); - if (!tempStatus.equals(LeaseStatus.UNSPECIFIED)) { - properties.setLeaseStatus(tempStatus); - } - else { - throw new StorageException(StorageErrorCodeStrings.INVALID_XML_DOCUMENT, - "The response received is invalid or improperly formatted.", - Constants.HeaderConstants.HTTP_UNUSED_306, null, null); - } - } - else if (name.equals(Constants.LEASE_STATE_ELEMENT)) { - final LeaseState tempState = LeaseState.parse(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.LEASE_STATE_ELEMENT)); - if (!tempState.equals(LeaseState.UNSPECIFIED)) { - properties.setLeaseState(tempState); - } - else { - throw new StorageException(StorageErrorCodeStrings.INVALID_XML_DOCUMENT, - "The response received is invalid or improperly formatted.", - Constants.HeaderConstants.HTTP_UNUSED_306, null, null); - } - } - else if (name.equals(Constants.LEASE_DURATION_ELEMENT)) { - final LeaseDuration tempDuration = LeaseDuration.parse(DeserializationHelper - .readElementFromXMLReader(xmlr, Constants.LEASE_DURATION_ELEMENT)); - if (!tempDuration.equals(LeaseDuration.UNSPECIFIED)) { - properties.setLeaseDuration(tempDuration); - } - else { - throw new StorageException(StorageErrorCodeStrings.INVALID_XML_DOCUMENT, - "The response received is invalid or improperly formatted.", - Constants.HeaderConstants.HTTP_UNUSED_306, null, null); - } - } - else if (name.equals(Constants.COPY_ID_ELEMENT)) { - if (copyState == null) { - copyState = new CopyState(); - } - copyState - .setCopyId(DeserializationHelper.readElementFromXMLReader(xmlr, Constants.COPY_ID_ELEMENT)); - } - else if (name.equals(Constants.COPY_COMPLETION_TIME_ELEMENT)) { - if (copyState == null) { - copyState = new CopyState(); - } - copyState.setCompletionTime(Utility.parseRFC1123DateFromStringInGMT(DeserializationHelper - .readElementFromXMLReader(xmlr, Constants.COPY_COMPLETION_TIME_ELEMENT))); - } - else if (name.equals(Constants.COPY_STATUS_ELEMENT)) { - if (copyState == null) { - copyState = new CopyState(); - } - copyState.setStatus(CopyStatus.parse(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.COPY_STATUS_ELEMENT))); - } - else if (name.equals(Constants.COPY_SOURCE_ELEMENT)) { - if (copyState == null) { - copyState = new CopyState(); - } - copyState.setSource(new URI(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.COPY_SOURCE_ELEMENT))); - } - else if (name.equals(Constants.COPY_PROGRESS_ELEMENT)) { - if (copyState == null) { - copyState = new CopyState(); - } - - final String tempString = DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.COPY_PROGRESS_ELEMENT); - String[] progressSequence = tempString.split("/"); - copyState.setBytesCopied(Long.parseLong(progressSequence[0])); - copyState.setTotalBytes(Long.parseLong(progressSequence[1])); - } - else if (name.equals(Constants.COPY_STATUS_DESCRIPTION_ELEMENT)) { - if (copyState == null) { - copyState = new CopyState(); - } - copyState.setStatusDescription(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.COPY_STATUS_DESCRIPTION_ELEMENT)); - } - else if (name.equals(Constants.COPY_ID_ELEMENT)) { - if (copyState == null) { - copyState = new CopyState(); - } - copyState - .setCopyId(DeserializationHelper.readElementFromXMLReader(xmlr, Constants.COPY_ID_ELEMENT)); - } - else if (name.equals(Constants.COPY_COMPLETION_TIME_ELEMENT)) { - if (copyState == null) { - copyState = new CopyState(); - } - copyState.setCompletionTime(Utility.parseRFC1123DateFromStringInGMT(DeserializationHelper - .readElementFromXMLReader(xmlr, Constants.COPY_COMPLETION_TIME_ELEMENT))); - } - else if (name.equals(Constants.COPY_STATUS_ELEMENT)) { - if (copyState == null) { - copyState = new CopyState(); - } - copyState.setStatus(CopyStatus.parse(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.COPY_STATUS_ELEMENT))); - } - else if (name.equals(Constants.COPY_SOURCE_ELEMENT)) { - if (copyState == null) { - copyState = new CopyState(); - } - copyState.setSource(new URI(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.COPY_SOURCE_ELEMENT))); - } - else if (name.equals(Constants.COPY_PROGRESS_ELEMENT)) { - if (copyState == null) { - copyState = new CopyState(); - } - - final String tempString = DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.COPY_PROGRESS_ELEMENT); - String[] progressSequence = tempString.split("/"); - copyState.setBytesCopied(Long.parseLong(progressSequence[0])); - copyState.setTotalBytes(Long.parseLong(progressSequence[1])); - } - else if (name.equals(Constants.COPY_STATUS_DESCRIPTION_ELEMENT)) { - if (copyState == null) { - copyState = new CopyState(); - } - copyState.setStatusDescription(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.COPY_STATUS_DESCRIPTION_ELEMENT)); - } - } - else if (eventType == XMLStreamConstants.END_ELEMENT) { - // expect end of properties - xmlr.require(XMLStreamConstants.END_ELEMENT, null, BlobConstants.PROPERTIES); - break; - } - } - properties.setCopyState(copyState); - - return properties; - } - - /** - * Parses the XML stream. - * - * @param serviceClient - * a reference to the client object associated with this object. - * @throws XMLStreamException - * @throws StorageException - */ - public static ListResponse getContainerList(final InputStream stream, - final CloudBlobClient serviceClient) throws XMLStreamException, StorageException { - final XMLStreamReader xmlr = DeserializationHelper.createXMLStreamReaderFromStream(stream); - - final ListResponse containers = new ListResponse(); - - String tempParseString = null; - - // Start document - int eventType = xmlr.getEventType(); - xmlr.require(XMLStreamConstants.START_DOCUMENT, null, null); - - // 1. get enumerationResults Header - eventType = xmlr.next(); - xmlr.require(XMLStreamConstants.START_ELEMENT, null, "EnumerationResults"); - - // check if there are more events in the input stream - while (xmlr.hasNext()) { - eventType = xmlr.next(); - - if (eventType == XMLStreamConstants.START_ELEMENT || eventType == XMLStreamConstants.END_ELEMENT) { - final String name = xmlr.getName().toString(); - if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(Constants.MAX_RESULTS_ELEMENT)) { - tempParseString = DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.MAX_RESULTS_ELEMENT); - containers.setMaxResults(Integer.parseInt(tempParseString)); - } - else if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(Constants.MARKER_ELEMENT)) { - containers - .setMarker(DeserializationHelper.readElementFromXMLReader(xmlr, Constants.MARKER_ELEMENT)); - } - else if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(Constants.NEXT_MARKER_ELEMENT)) { - containers.setNextMarker(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.NEXT_MARKER_ELEMENT)); - } - else if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(Constants.PREFIX_ELEMENT)) { - containers - .setPrefix(DeserializationHelper.readElementFromXMLReader(xmlr, Constants.PREFIX_ELEMENT)); - } - else if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(BlobConstants.CONTAINERS_ELEMENT)) { - try { - containers.setResults(readContainers(xmlr, serviceClient)); - } - catch (final URISyntaxException e) { - throw new XMLStreamException(e); - } - catch (final ParseException e) { - throw new XMLStreamException(e); - } - - xmlr.require(XMLStreamConstants.END_ELEMENT, null, BlobConstants.CONTAINERS_ELEMENT); - // eventType = xmlr.next(); - } - else if (eventType == XMLStreamConstants.END_ELEMENT && "EnumerationResults".equals(name)) { - break; - } - } - } - - return containers; - } - - /** - * Populates the container from an XMLStreamReader - * - * @param xmlr - * the XMLStreamReader to read from - * @throws XMLStreamException - * if there is an error parsing the stream - * @throws ParseException - * if there is an error in parsing a date - * @throws URISyntaxException - * if the uri is invalid - * @throws StorageException - */ - private static CloudBlobContainer readContainer(final XMLStreamReader xmlr, final CloudBlobClient serviceClient) - throws XMLStreamException, ParseException, URISyntaxException, StorageException { - - xmlr.require(XMLStreamConstants.START_ELEMENT, null, BlobConstants.CONTAINER_ELEMENT); - - final BlobContainerAttributes attributes = readBlobContainerAttributes(xmlr); - - StorageUri containerUri = serviceClient.getStorageUri(); - containerUri = PathUtility.appendPathToUri(containerUri, attributes.getName()); - - attributes.setStorageUri(containerUri); - - final CloudBlobContainer retContainer = new CloudBlobContainer(attributes.getStorageUri(), serviceClient); - retContainer.setMetadata(attributes.getMetadata()); - retContainer.setName(attributes.getName()); - retContainer.setProperties(attributes.getProperties()); - retContainer.setStorageUri(attributes.getStorageUri()); - - xmlr.require(XMLStreamConstants.END_ELEMENT, null, BlobConstants.CONTAINER_ELEMENT); - return retContainer; - } - - /** - * Populates the object from the XMLStreamReader - * - * @param xmlr - * the XMLStreamReader to read from - * @throws XMLStreamException - * if there is an error parsing the stream - * @throws ParseException - * if there is an error in parsing a date - * @throws URISyntaxException - * if the uri is invalid - */ - private static BlobContainerAttributes readBlobContainerAttributes(final XMLStreamReader xmlr) - throws XMLStreamException, ParseException, URISyntaxException { - int eventType = xmlr.getEventType(); - - final BlobContainerAttributes attributes = new BlobContainerAttributes(); - - while (xmlr.hasNext()) { - eventType = xmlr.next(); - final String name = xmlr.getName().toString(); - if (eventType == XMLStreamConstants.START_ELEMENT) { - if (name.equals(Constants.NAME_ELEMENT)) { - attributes.setName(DeserializationHelper.readElementFromXMLReader(xmlr, Constants.NAME_ELEMENT)); - } - else if (name.equals(BlobConstants.PROPERTIES)) { - attributes.setProperties(readBlobContainerProperties(xmlr)); - xmlr.require(XMLStreamConstants.END_ELEMENT, null, BlobConstants.PROPERTIES); - } - else if (name.equals(Constants.METADATA_ELEMENT)) { - // parse metadata - attributes.setMetadata(DeserializationHelper.parseMetadateFromXML(xmlr)); - xmlr.require(XMLStreamConstants.END_ELEMENT, null, Constants.METADATA_ELEMENT); - } - } - else if (eventType == XMLStreamConstants.END_ELEMENT && name.equals(BlobConstants.CONTAINER_ELEMENT)) { - break; - } - } - - return attributes; - } - - /** - * Populates the object from the XMLStreamReader, reader must be at Start element of Properties - * - * @param xmlr - * the XMLStreamReader object - * @throws XMLStreamException - * if there is a parsing exception - * @throws ParseException - * if a date value is not correctly encoded - */ - private static BlobContainerProperties readBlobContainerProperties(final XMLStreamReader xmlr) - throws XMLStreamException, ParseException { - xmlr.require(XMLStreamConstants.START_ELEMENT, null, BlobConstants.PROPERTIES); - int eventType = xmlr.getEventType(); - final BlobContainerProperties properties = new BlobContainerProperties(); - - while (xmlr.hasNext()) { - eventType = xmlr.next(); - final String name = xmlr.getName().toString(); - if (eventType == XMLStreamConstants.START_ELEMENT) { - if (name.equals(Constants.LAST_MODIFIED_ELEMENT)) { - properties.setLastModified(Utility.parseRFC1123DateFromStringInGMT(DeserializationHelper - .readElementFromXMLReader(xmlr, Constants.LAST_MODIFIED_ELEMENT))); - } - else if (name.equals(Constants.ETAG_ELEMENT)) { - properties.setEtag(DeserializationHelper.readETagFromXMLReader(xmlr)); - } - else if (name.equals(Constants.LEASE_STATUS_ELEMENT)) { - properties.setLeaseStatus(LeaseStatus.parse(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.LEASE_STATUS_ELEMENT))); - } - else if (name.equals(Constants.LEASE_STATE_ELEMENT)) { - properties.setLeaseState(LeaseState.parse(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.LEASE_STATE_ELEMENT))); - } - else if (name.equals(Constants.LEASE_DURATION_ELEMENT)) { - properties.setLeaseDuration(LeaseDuration.parse(DeserializationHelper.readElementFromXMLReader( - xmlr, Constants.LEASE_DURATION_ELEMENT))); - } - } - else { - // expect end of properties - xmlr.require(XMLStreamConstants.END_ELEMENT, null, BlobConstants.PROPERTIES); - break; - } - } - - return properties; - } - - /** - * Populates CloudBlobContainer objects from the XMLStreamReader, reader must be at Start element of - * ContainersElement - * - * @param xmlr - * the XMLStreamReader object - * @param serviceClient - * the CloudBlobClient associated with the objects. - * @return an ArrayList of CloudBlobContainer from the stream. - * @throws XMLStreamException - * if there is a parsing exception - * @throws ParseException - * if a date value is not correctly encoded - * @throws URISyntaxException - * @throws StorageException - */ - private static ArrayList readContainers(final XMLStreamReader xmlr, - final CloudBlobClient serviceClient) throws XMLStreamException, ParseException, URISyntaxException, - StorageException { - int eventType = xmlr.getEventType(); - xmlr.require(XMLStreamConstants.START_ELEMENT, null, BlobConstants.CONTAINERS_ELEMENT); - - final ArrayList containers = new ArrayList(); - - eventType = xmlr.next(); - while (eventType == XMLStreamConstants.START_ELEMENT && xmlr.hasName() - && BlobConstants.CONTAINER_ELEMENT.equals(xmlr.getName().toString())) { - containers.add(readContainer(xmlr, serviceClient)); - eventType = xmlr.next(); - } - - xmlr.require(XMLStreamConstants.END_ELEMENT, null, BlobConstants.CONTAINERS_ELEMENT); - return containers; - } - - /** - * Parses the XML stream. - * - * @throws XMLStreamException - * @throws StorageException - */ - public static ArrayList getBlockList(InputStream streamRef) throws XMLStreamException, StorageException { - final XMLStreamReader xmlr = DeserializationHelper.createXMLStreamReaderFromStream(streamRef); - - final ArrayList blocks = new ArrayList(); - - // Start document - int eventType = xmlr.getEventType(); - xmlr.require(XMLStreamConstants.START_DOCUMENT, null, null); - - // 1. get BlockList Header - eventType = xmlr.next(); - xmlr.require(XMLStreamConstants.START_ELEMENT, null, BlobConstants.BLOCK_LIST_ELEMENT); - - // check if there are more events in the input stream - while (xmlr.hasNext()) { - eventType = xmlr.next(); - if (eventType == XMLStreamConstants.START_ELEMENT || eventType == XMLStreamConstants.END_ELEMENT) { - final String name = xmlr.getName().toString(); - if (name.equals(BlobConstants.COMMITTED_BLOCKS_ELEMENT)) { - // Move to block element - eventType = xmlr.next(); - if (eventType == XMLStreamConstants.START_ELEMENT - && BlobConstants.BLOCK_ELEMENT.equals(xmlr.getName().toString())) { - blocks.addAll(readBlobBlocks(xmlr, BlockSearchMode.COMMITTED)); - xmlr.require(XMLStreamConstants.END_ELEMENT, null, BlobConstants.COMMITTED_BLOCKS_ELEMENT); - } - } - else if (name.equals(BlobConstants.UNCOMMITTED_BLOCKS_ELEMENT)) { - // Move to block element - eventType = xmlr.next(); - if (eventType == XMLStreamConstants.START_ELEMENT - && BlobConstants.BLOCK_ELEMENT.equals(xmlr.getName().toString())) { - blocks.addAll(readBlobBlocks(xmlr, BlockSearchMode.UNCOMMITTED)); - xmlr.require(XMLStreamConstants.END_ELEMENT, null, BlobConstants.UNCOMMITTED_BLOCKS_ELEMENT); - } - } - else if (name.equals(BlobConstants.BLOCK_LIST_ELEMENT) && eventType == XMLStreamConstants.END_ELEMENT) { - break; - } - else { - throw new StorageException(StorageErrorCodeStrings.INVALID_XML_DOCUMENT, - "The response received is invalid or improperly formatted.", - Constants.HeaderConstants.HTTP_UNUSED_306, null, null); - } - } - } - - return blocks; - } - - /** - * Reads BlobItems from the XMLStreamReader, reader must be at Start element of BlobsElement - * - * @param xmlr - * the XMLStreamReader to read from - * @param searchMode - * the block search mode - * @return BlockEntry from the stream. - * @throws XMLStreamException - * if there is an error parsing the stream - * @throws ParseException - * if there is an error in parsing a date - * @throws URISyntaxException - * if the uri is invalid - * @throws StorageException - */ - private static ArrayList readBlobBlocks(final XMLStreamReader xmlr, final BlockSearchMode searchMode) - throws XMLStreamException, StorageException { - int eventType = xmlr.getEventType(); - final ArrayList retBlocks = new ArrayList(); - - xmlr.require(XMLStreamConstants.START_ELEMENT, null, BlobConstants.BLOCK_ELEMENT); - - // check if there are more events in the input stream - while (xmlr.hasNext() && BlobConstants.BLOCK_ELEMENT.equals(xmlr.getName().toString())) { - String blockName = null; - long blockSize = -1; - - // Read a block - while (xmlr.hasNext()) { - eventType = xmlr.next(); - final String name = xmlr.getName().toString(); - - if (eventType == XMLStreamConstants.START_ELEMENT) { - if (name.equals(Constants.NAME_ELEMENT)) { - blockName = DeserializationHelper.readElementFromXMLReader(xmlr, Constants.NAME_ELEMENT); - } - else if (name.equals(BlobConstants.SIZE_ELEMENT)) { - final String sizeString = DeserializationHelper.readElementFromXMLReader(xmlr, - BlobConstants.SIZE_ELEMENT); - blockSize = Long.parseLong(sizeString); - } - else { - throw new StorageException(StorageErrorCodeStrings.INVALID_XML_DOCUMENT, - "The response received is invalid or improperly formatted.", - Constants.HeaderConstants.HTTP_UNUSED_306, null, null); - } - } - else if (eventType == XMLStreamConstants.END_ELEMENT) { - final BlockEntry newBlock = new BlockEntry(blockName, searchMode); - newBlock.setSize(blockSize); - retBlocks.add(newBlock); - break; - } - } - - eventType = xmlr.next(); - } - - return retBlocks; - } - - /** - * Returns an ArrayList of Page Ranges for the given page blob. - * - * @return an ArrayList of Page Ranges for the given page blob. - * @throws XMLStreamException - * @throws StorageException - */ - public static ArrayList getPageRanges(InputStream streamRef) throws XMLStreamException, StorageException { - final XMLStreamReader xmlr = DeserializationHelper.createXMLStreamReaderFromStream(streamRef); - - ArrayList pageRanges = new ArrayList(); - - // Start document - int eventType = xmlr.getEventType(); - xmlr.require(XMLStreamConstants.START_DOCUMENT, null, null); - - // 1. get BlockList Header - eventType = xmlr.next(); - xmlr.require(XMLStreamConstants.START_ELEMENT, null, BlobConstants.PAGE_LIST_ELEMENT); - - // check if there are more events in the input stream - while (xmlr.hasNext()) { - eventType = xmlr.next(); - if (eventType == XMLStreamConstants.START_ELEMENT || eventType == XMLStreamConstants.END_ELEMENT) { - final String name = xmlr.getName().toString(); - - if (name.equals(BlobConstants.PAGE_RANGE_ELEMENT)) { - pageRanges = readPageRanges(xmlr); - } - else if (name.equals(BlobConstants.PAGE_LIST_ELEMENT) && eventType == XMLStreamConstants.END_ELEMENT) { - break; - } - else { - throw new StorageException(StorageErrorCodeStrings.INVALID_XML_DOCUMENT, - "The response received is invalid or improperly formatted.", - Constants.HeaderConstants.HTTP_UNUSED_306, null, null); - } - } - } - - return pageRanges; - } - - /** - * Reads PageRanges from the XMLStreamReader, reader must be at Start element of PageRangeElement - * - * @param xmlr - * the XMLStreamReader to read from - * @return the PageRange from the stream. - * @throws XMLStreamException - * if there is an error parsing the stream - * @throws ParseException - * if there is an error in parsing a date - * @throws URISyntaxException - * if the uri is invalid - * @throws StorageException - */ - private static ArrayList readPageRanges(final XMLStreamReader xmlr) throws XMLStreamException, - StorageException { - int eventType = xmlr.getEventType(); - final ArrayList retRanges = new ArrayList(); - - xmlr.require(XMLStreamConstants.START_ELEMENT, null, BlobConstants.PAGE_RANGE_ELEMENT); - - // check if there are more events in the input stream - while (xmlr.hasNext() && BlobConstants.PAGE_RANGE_ELEMENT.equals(xmlr.getName().toString())) { - long startOffset = -1; - long endOffset = -1; - - // Read a Page Range - while (xmlr.hasNext()) { - eventType = xmlr.next(); - final String name = xmlr.getName().toString(); - - if (eventType == XMLStreamConstants.START_ELEMENT) { - if (name.equals(BlobConstants.START_ELEMENT)) { - final String sizeString = DeserializationHelper.readElementFromXMLReader(xmlr, - BlobConstants.START_ELEMENT); - startOffset = Long.parseLong(sizeString); - } - else if (name.equals(Constants.END_ELEMENT)) { - final String sizeString = DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.END_ELEMENT); - endOffset = Long.parseLong(sizeString); - } - else { - throw new StorageException(StorageErrorCodeStrings.INVALID_XML_DOCUMENT, - "The response received is invalid or improperly formatted.", - Constants.HeaderConstants.HTTP_UNUSED_306, null, null); - } - } - else if (eventType == XMLStreamConstants.END_ELEMENT) { - if (startOffset == -1 || endOffset == -1) { - throw new StorageException(StorageErrorCodeStrings.INVALID_XML_DOCUMENT, - "The response received is invalid or improperly formatted.", - Constants.HeaderConstants.HTTP_UNUSED_306, null, null); - } - - final PageRange pageRef = new PageRange(startOffset, endOffset); - retRanges.add(pageRef); - break; - } - } - - eventType = xmlr.next(); - } - - return retRanges; - } -} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobRequest.java b/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobRequest.java deleted file mode 100644 index bddf48487dfa5..0000000000000 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/BlobRequest.java +++ /dev/null @@ -1,1085 +0,0 @@ -/** - * 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.windowsazure.storage.blob; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.HashMap; - -import com.microsoft.windowsazure.storage.AccessCondition; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.Constants.HeaderConstants; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.core.BaseRequest; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.UriQueryBuilder; -import com.microsoft.windowsazure.storage.core.Utility; - -/** - * RESERVED FOR INTERNAL USE. Provides a set of methods for constructing requests for blob operations. - */ -final class BlobRequest { - - private static final String BLOCK_QUERY_ELEMENT_NAME = "block"; - - private static final String BLOCK_ID_QUERY_ELEMENT_NAME = "blockid"; - - private static final String BLOCK_LIST_QUERY_ELEMENT_NAME = "blocklist"; - - private static final String BLOCK_LIST_TYPE_QUERY_ELEMENT_NAME = "blocklisttype"; - - private static final String COPY_QUERY_ELEMENT_NAME = "copy"; - - private static final String PAGE_QUERY_ELEMENT_NAME = "page"; - - private static final String PAGE_LIST_QUERY_ELEMENT_NAME = "pagelist"; - - private static final String SNAPSHOTS_QUERY_ELEMENT_NAME = "snapshots"; - - private static final String UNCOMMITTED_BLOBS_QUERY_ELEMENT_NAME = "uncommittedblobs"; - - /** - * Adds the metadata. - * - * @param request - * The request. - * @param metadata - * The metadata. - */ - public static void addMetadata(final HttpURLConnection request, final HashMap metadata, - final OperationContext opContext) { - BaseRequest.addMetadata(request, metadata, opContext); - } - - /** - * Adds the metadata. - * - * @param request - * The request. - * @param name - * The metadata name. - * @param value - * The metadata value. - */ - public static void addMetadata(final HttpURLConnection request, final String name, final String value, - final OperationContext opContext) { - BaseRequest.addMetadata(request, name, value, opContext); - } - - /** - * Adds the metadata. - * - * @param request - * The request. - * @param name - * The metadata name. - * @param value - * The metadata value. - */ - private static void addProperties(final HttpURLConnection request, BlobProperties properties) { - BaseRequest.addOptionalHeader(request, Constants.HeaderConstants.CACHE_CONTROL_HEADER, - properties.getCacheControl()); - BaseRequest.addOptionalHeader(request, BlobConstants.CONTENT_DISPOSITION_HEADER, - properties.getContentDisposition()); - BaseRequest.addOptionalHeader(request, BlobConstants.CONTENT_ENCODING_HEADER, properties.getContentEncoding()); - BaseRequest.addOptionalHeader(request, BlobConstants.CONTENT_LANGUAGE_HEADER, properties.getContentLanguage()); - BaseRequest.addOptionalHeader(request, BlobConstants.BLOB_CONTENT_MD5_HEADER, properties.getContentMD5()); - BaseRequest.addOptionalHeader(request, BlobConstants.CONTENT_TYPE_HEADER, properties.getContentType()); - } - - /** - * Creates a request to copy a blob, Sign with 0 length. - * - * @param uri - * The absolute URI to the container. - * @param timeout - * The server timeout interval. - * @param source - * The canonical path to the source blob, in the form ///. - * @param sourceSnapshotID - * The snapshot version, if the source blob is a snapshot. - * @param sourceAccessConditionType - * A type of condition to check on the source blob. - * @param sourceAccessConditionValue - * The value of the condition to check on the source blob - * @param blobOptions - * the options to use for the request. - * @param opContext - * a tracking object for the request - * @return a HttpURLConnection configured for the operation. - * @throws StorageException - * an exception representing any error which occurred during the operation. - * @throws IllegalArgumentException - * @throws IOException - * @throws URISyntaxException - */ - public static HttpURLConnection copyFrom(final URI uri, final int timeout, String source, - final String sourceSnapshotID, final AccessCondition sourceAccessCondition, - final AccessCondition destinationAccessCondition, final BlobRequestOptions blobOptions, - final OperationContext opContext) throws StorageException, IOException, URISyntaxException { - - if (sourceSnapshotID != null) { - source = source.concat("?snapshot="); - source = source.concat(sourceSnapshotID); - } - - final HttpURLConnection request = BaseRequest.createURLConnection(uri, timeout, null, opContext); - - request.setFixedLengthStreamingMode(0); - request.setDoOutput(true); - request.setRequestMethod(Constants.HTTP_PUT); - - request.setRequestProperty(Constants.HeaderConstants.COPY_SOURCE_HEADER, source); - - if (sourceAccessCondition != null) { - sourceAccessCondition.applyConditionToRequest(request, true); - } - - if (destinationAccessCondition != null) { - destinationAccessCondition.applyConditionToRequest(request); - } - - return request; - } - - /** - * Generates a web request to abort a copy operation. - * - * @param uri - * The absolute URI to the container. - * @param timeout - * The server timeout interval. - * @param copyId - * A String object that identifying the copy operation. - * @param accessCondition - * The access condition to apply to the request. Only lease conditions are supported for this operation. - * @param blobOptions - * the options to use for the request. - * @param opContext - * a tracking object for the request - * @return a HttpURLConnection configured for the operation. - * @throws StorageException - * an exception representing any error which occurred during the operation. - * @throws IllegalArgumentException - * @throws IOException - * @throws URISyntaxException - */ - public static HttpURLConnection abortCopy(final URI uri, final int timeout, final String copyId, - final AccessCondition accessCondition, final BlobRequestOptions blobOptions, - final OperationContext opContext) throws StorageException, IOException, URISyntaxException { - - final UriQueryBuilder builder = new UriQueryBuilder(); - - builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.COPY); - builder.add(Constants.QueryConstants.COPY_ID, copyId); - - final HttpURLConnection request = BaseRequest.createURLConnection(uri, timeout, builder, opContext); - - request.setFixedLengthStreamingMode(0); - request.setDoOutput(true); - request.setRequestMethod(Constants.HTTP_PUT); - - request.setRequestProperty(Constants.HeaderConstants.COPY_ACTION_HEADER, - Constants.HeaderConstants.COPY_ACTION_ABORT); - - if (accessCondition != null) { - accessCondition.applyConditionToRequest(request, true); - } - - return request; - } - - /** - * Creates the web request. - * - * @param uri - * The absolute URI to the container. - * @param timeout - * The server timeout interval. - * @param query - * The query builder to use. - * @param blobOptions - * the options to use for the request. - * @param opContext - * a tracking object for the request - * @return a HttpURLConnection configured for the operation. - * @throws StorageException - * an exception representing any error which occurred during the operation. - * @throws IllegalArgumentException - */ - private static HttpURLConnection createURLConnection(final URI uri, final int timeout, final UriQueryBuilder query, - final BlobRequestOptions blobOptions, final OperationContext opContext) throws IOException, - URISyntaxException, StorageException { - return BaseRequest.createURLConnection(uri, timeout, query, opContext); - } - - /** - * Constructs a HttpURLConnection to delete the blob, Sign with no length specified. - * - * @param uri - * The absolute URI to the blob - * @param timeout - * The server timeout interval - * @param snapshotVersion - * The snapshot version, if the blob is a snapshot. - * @param deleteSnapshotsOption - * A set of options indicating whether to delete only blobs, only snapshots, or both. - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for the blob. - * @param blobOptions - * the options to use for the request. - * @param opContext - * a tracking object for the request - * @return a HttpURLConnection to use to perform the operation. - * @throws IOException - * if there is an error opening the connection - * @throws URISyntaxException - * if the resource URI is invalid - * @throws StorageException - * an exception representing any error which occurred during the operation. - * @throws IllegalArgumentException - */ - public static HttpURLConnection delete(final URI uri, final int timeout, final String snapshotVersion, - final DeleteSnapshotsOption deleteSnapshotsOption, final AccessCondition accessCondition, - final BlobRequestOptions blobOptions, final OperationContext opContext) throws IOException, - URISyntaxException, StorageException { - - if (snapshotVersion != null && deleteSnapshotsOption != DeleteSnapshotsOption.NONE) { - throw new IllegalArgumentException(String.format(SR.DELETE_SNAPSHOT_NOT_VALID_ERROR, - "deleteSnapshotsOption", "snapshot")); - } - - final UriQueryBuilder builder = new UriQueryBuilder(); - BaseRequest.addSnapshot(builder, snapshotVersion); - final HttpURLConnection request = BaseRequest.delete(uri, timeout, builder, opContext); - - if (accessCondition != null) { - accessCondition.applyConditionToRequest(request); - } - - switch (deleteSnapshotsOption) { - case NONE: - // nop - break; - case INCLUDE_SNAPSHOTS: - request.setRequestProperty(Constants.HeaderConstants.DELETE_SNAPSHOT_HEADER, - BlobConstants.INCLUDE_SNAPSHOTS_VALUE); - break; - case DELETE_SNAPSHOTS_ONLY: - request.setRequestProperty(Constants.HeaderConstants.DELETE_SNAPSHOT_HEADER, - BlobConstants.SNAPSHOTS_ONLY_VALUE); - break; - default: - break; - } - - return request; - } - - /** - * Constructs a HttpURLConnection to download the blob, Sign with no length specified. - * - * @param uri - * The absolute URI to the blob - * @param timeout - * The server timeout interval - * @param snapshotVersion - * The snapshot version, if the blob is a snapshot. - * @param offset - * The offset at which to begin returning content. - * @param count - * The number of bytes to return. - * @param requestRangeContentMD5 - * If set to true, request an MD5 header for the specified range. - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for the blob. - * @param blobOptions - * the options to use for the request. - * @param opContext - * a tracking object for the request - * @return a HttpURLConnection to use to perform the operation. - * @throws IOException - * if there is an error opening the connection - * @throws URISyntaxException - * if the resource URI is invalid - * @throws StorageException - * an exception representing any error which occurred during the operation. - * @throws IllegalArgumentException - */ - public static HttpURLConnection get(final URI uri, final int timeout, final String snapshotVersion, - final Long offset, final Long count, boolean requestRangeContentMD5, final AccessCondition accessCondition, - final BlobRequestOptions blobOptions, final OperationContext opContext) throws IOException, - URISyntaxException, StorageException { - - if (offset != null && requestRangeContentMD5) { - Utility.assertNotNull("count", count); - Utility.assertInBounds("count", count, 1, Constants.MAX_BLOCK_SIZE); - } - - final HttpURLConnection request = get(uri, timeout, snapshotVersion, accessCondition, blobOptions, opContext); - - if (offset != null) { - long rangeStart = offset; - long rangeEnd; - if (count != null) { - rangeEnd = offset + count - 1; - request.setRequestProperty(Constants.HeaderConstants.STORAGE_RANGE_HEADER, String.format( - Utility.LOCALE_US, Constants.HeaderConstants.RANGE_HEADER_FORMAT, rangeStart, rangeEnd)); - } - else { - request.setRequestProperty(Constants.HeaderConstants.STORAGE_RANGE_HEADER, String.format( - Utility.LOCALE_US, Constants.HeaderConstants.BEGIN_RANGE_HEADER_FORMAT, rangeStart)); - } - } - - if (offset != null && requestRangeContentMD5) { - request.setRequestProperty(Constants.HeaderConstants.RANGE_GET_CONTENT_MD5, Constants.TRUE); - } - - return request; - } - - /** - * Constructs a HttpURLConnection to download the blob, Sign with no length specified. - * - * @param uri - * The absolute URI to the blob - * @param timeout - * The server timeout interval - * @param snapshotVersion - * The snapshot version, if the blob is a snapshot. - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for the blob. - * @param blobOptions - * the options to use for the request. - * @param opContext - * a tracking object for the request - * @return a HttpURLConnection to use to perform the operation. - * @throws IOException - * if there is an error opening the connection - * @throws URISyntaxException - * if the resource URI is invalid - * @throws StorageException - * an exception representing any error which occurred during the operation. - * @throws IllegalArgumentException - */ - public static HttpURLConnection get(final URI uri, final int timeout, final String snapshotVersion, - final AccessCondition accessCondition, final BlobRequestOptions blobOptions, - final OperationContext opContext) throws IOException, URISyntaxException, StorageException { - - final UriQueryBuilder builder = new UriQueryBuilder(); - BaseRequest.addSnapshot(builder, snapshotVersion); - final HttpURLConnection request = BaseRequest.createURLConnection(uri, timeout, builder, opContext); - request.setRequestMethod(Constants.HTTP_GET); - - if (accessCondition != null) { - accessCondition.applyConditionToRequest(request); - } - - return request; - } - - /** - * Constructs a HttpURLConnection to return a list of the block blobs blocks. Sign with no length specified. - * - * @param uri - * The absolute URI to the blob - * @param timeout - * The server timeout interval - * @param snapshotVersion - * The snapshot version, if the blob is a snapshot. - * @param blockFilter - * The types of blocks to include in the list: committed, uncommitted, or both. - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for the blob. - * @param blobOptions - * the options to use for the request. - * @param opContext - * a tracking object for the request - * @return a HttpURLConnection to use to perform the operation. - * @throws IOException - * if there is an error opening the connection - * @throws URISyntaxException - * if the resource URI is invalid - * @throws StorageException - * an exception representing any error which occurred during the operation. - * @throws IllegalArgumentException - */ - public static HttpURLConnection getBlockList(final URI uri, final int timeout, final String snapshotVersion, - final BlockListingFilter blockFilter, final AccessCondition accessCondition, - final BlobRequestOptions blobOptions, final OperationContext opContext) throws StorageException, - IOException, URISyntaxException { - - final UriQueryBuilder builder = new UriQueryBuilder(); - - builder.add(Constants.QueryConstants.COMPONENT, BLOCK_LIST_QUERY_ELEMENT_NAME); - builder.add(BLOCK_LIST_TYPE_QUERY_ELEMENT_NAME, blockFilter.toString()); - BaseRequest.addSnapshot(builder, snapshotVersion); - - final HttpURLConnection request = BaseRequest.createURLConnection(uri, timeout, builder, opContext); - request.setRequestMethod(Constants.HTTP_GET); - - if (accessCondition != null) { - accessCondition.applyConditionToRequest(request); - } - - return request; - } - - /** - * Constructs a HttpURLConnection to return a list of the PageBlob's page ranges. Sign with no length specified. - * - * @param uri - * The absolute URI to the blob - * @param timeout - * The server timeout interval - * @param snapshotVersion - * The snapshot version, if the blob is a snapshot. - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for the blob. - * @param blobOptions - * the options to use for the request. - * @param opContext - * a tracking object for the request - * @return a HttpURLConnection to use to perform the operation. - * @throws IOException - * if there is an error opening the connection - * @throws URISyntaxException - * if the resource URI is invalid - * @throws StorageException - * an exception representing any error which occurred during the operation. - * @throws IllegalArgumentException - */ - public static HttpURLConnection getPageRanges(final URI uri, final int timeout, final String snapshotVersion, - final AccessCondition accessCondition, final BlobRequestOptions blobOptions, - final OperationContext opContext) throws StorageException, IOException, URISyntaxException { - - final UriQueryBuilder builder = new UriQueryBuilder(); - builder.add(Constants.QueryConstants.COMPONENT, PAGE_LIST_QUERY_ELEMENT_NAME); - BaseRequest.addSnapshot(builder, snapshotVersion); - - final HttpURLConnection request = BlobRequest - .createURLConnection(uri, timeout, builder, blobOptions, opContext); - request.setRequestMethod(Constants.HTTP_GET); - - if (accessCondition != null) { - accessCondition.applyConditionToRequest(request); - } - - BaseRequest.addOptionalHeader(request, BlobConstants.SNAPSHOT, snapshotVersion); - return request; - } - - /** - * Constructs a HttpURLConnection to return the blob's system properties, Sign with no length specified. - * - * @param uri - * The absolute URI to the blob - * @param timeout - * The server timeout interval - * @param snapshotVersion - * The snapshot version, if the blob is a snapshot. - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for the blob. - * @param blobOptions - * the options to use for the request. - * @param opContext - * a tracking object for the request - * @return a HttpURLConnection to use to perform the operation. - * @throws IOException - * if there is an error opening the connection - * @throws URISyntaxException - * if the resource URI is invalid - * @throws StorageException - * an exception representing any error which occurred during the operation. - * @throws IllegalArgumentException - */ - public static HttpURLConnection getProperties(final URI uri, final int timeout, final String snapshotVersion, - final AccessCondition accessCondition, final BlobRequestOptions blobOptions, - final OperationContext opContext) throws StorageException, IOException, URISyntaxException { - - final UriQueryBuilder builder = new UriQueryBuilder(); - BaseRequest.addSnapshot(builder, snapshotVersion); - final HttpURLConnection request = BaseRequest.getProperties(uri, timeout, builder, opContext); - - if (accessCondition != null) { - accessCondition.applyConditionToRequest(request); - } - - return request; - } - - /** - * Constructs a HttpURLConnection to Acquire,Release,Break, or Renew a blob lease. Sign with 0 length. - * - * @param uri - * The absolute URI to the blob - * @param timeout - * The server timeout interval - * @param action - * the LeaseAction to perform - * - * @param visibilityTimeoutInSeconds - * Specifies the the span of time for which to acquire the lease, in seconds. - * If null, an infinite lease will be acquired. If not null, this must be greater than zero. - * - * @param proposedLeaseId - * A String that represents the proposed lease ID for the new lease, - * or null if no lease ID is proposed. - * - * @param breakPeriodInSeconds - * Specifies the amount of time to allow the lease to remain, in seconds. - * If null, the break period is the remainder of the current lease, or zero for infinite leases. - * - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for the blob. - * @param blobOptions - * the options to use for the request. - * @param opContext - * a tracking object for the request - * @return a HttpURLConnection to use to perform the operation. - * @throws IOException - * if there is an error opening the connection - * @throws URISyntaxException - * if the resource URI is invalid - * @throws StorageException - * an exception representing any error which occurred during the operation. - * @throws IllegalArgumentException - */ - public static HttpURLConnection lease(final URI uri, final int timeout, final LeaseAction action, - final Integer leaseTimeInSeconds, final String proposedLeaseId, final Integer breakPeriodInSeconds, - final AccessCondition accessCondition, final BlobRequestOptions blobOptions, - final OperationContext opContext) throws IOException, URISyntaxException, StorageException { - - final UriQueryBuilder builder = new UriQueryBuilder(); - builder.add(Constants.QueryConstants.COMPONENT, BlobConstants.LEASE); - - final HttpURLConnection request = BlobRequest - .createURLConnection(uri, timeout, builder, blobOptions, opContext); - - request.setDoOutput(true); - request.setRequestMethod(Constants.HTTP_PUT); - request.setFixedLengthStreamingMode(0); - request.setRequestProperty(HeaderConstants.LEASE_ACTION_HEADER, action.toString()); - - request.setRequestProperty(HeaderConstants.LEASE_DURATION, leaseTimeInSeconds == null ? "-1" - : leaseTimeInSeconds.toString()); - - if (proposedLeaseId != null) { - request.setRequestProperty(HeaderConstants.PROPOSED_LEASE_ID_HEADER, proposedLeaseId); - } - - if (breakPeriodInSeconds != null) { - request.setRequestProperty(HeaderConstants.LEASE_BREAK_PERIOD_HEADER, breakPeriodInSeconds.toString()); - } - - if (accessCondition != null) { - accessCondition.applyConditionToRequest(request); - } - return request; - } - - /** - * Constructs a HttpURLConnection to list blobs. Sign with no length specified. - * - * @param uri - * The absolute URI to the blob - * @param timeout - * The server timeout interval - * @param listingContext - * A set of parameters for the listing operation. - * @param blobOptions - * the options to use for the request. - * @param opContext - * a tracking object for the request - * @return a HttpURLConnection configured for the operation. - * @throws IOException - * if there is an error opening the connection - * @throws URISyntaxException - * if the resource URI is invalid - * @throws StorageException - * an exception representing any error which occurred during the operation. - * @throws IllegalArgumentException - * */ - public static HttpURLConnection list(final URI uri, final int timeout, final BlobListingContext listingContext, - final BlobRequestOptions blobOptions, final OperationContext opContext) throws URISyntaxException, - IOException, StorageException { - - final UriQueryBuilder builder = ContainerRequest.getContainerUriQueryBuilder(); - builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.LIST); - - if (listingContext != null) { - if (!Utility.isNullOrEmpty(listingContext.getPrefix())) { - builder.add(Constants.QueryConstants.PREFIX, listingContext.getPrefix()); - } - - if (!Utility.isNullOrEmpty(listingContext.getDelimiter())) { - builder.add(Constants.QueryConstants.DELIMITER, listingContext.getDelimiter()); - } - - if (!Utility.isNullOrEmpty(listingContext.getMarker())) { - builder.add(Constants.QueryConstants.MARKER, listingContext.getMarker()); - } - - if (listingContext.getMaxResults() != null && listingContext.getMaxResults() > 0) { - builder.add(Constants.QueryConstants.MAX_RESULTS, listingContext.getMaxResults().toString()); - } - - if (listingContext.getListingDetails().size() > 0) { - final StringBuilder sb = new StringBuilder(); - - boolean started = false; - - if (listingContext.getListingDetails().contains(BlobListingDetails.SNAPSHOTS)) { - if (!started) { - started = true; - } - else { - sb.append(","); - } - - sb.append(SNAPSHOTS_QUERY_ELEMENT_NAME); - } - - if (listingContext.getListingDetails().contains(BlobListingDetails.UNCOMMITTED_BLOBS)) { - if (!started) { - started = true; - } - else { - sb.append(","); - } - - sb.append(UNCOMMITTED_BLOBS_QUERY_ELEMENT_NAME); - } - - if (listingContext.getListingDetails().contains(BlobListingDetails.COPY)) { - if (!started) { - started = true; - } - else { - sb.append(","); - } - - sb.append(COPY_QUERY_ELEMENT_NAME); - } - - if (listingContext.getListingDetails().contains(BlobListingDetails.METADATA)) { - if (!started) { - started = true; - } - else { - sb.append(","); - } - - sb.append(Constants.QueryConstants.METADATA); - } - - builder.add(Constants.QueryConstants.INCLUDE, sb.toString()); - } - } - - final HttpURLConnection request = BlobRequest - .createURLConnection(uri, timeout, builder, blobOptions, opContext); - - request.setRequestMethod(Constants.HTTP_GET); - - return request; - } - - /** - * Constructs a HttpURLConnection to upload a blob. Sign with blob length, or -1 for pageblob create. - * - * @param uri - * The absolute URI to the blob - * @param timeout - * The server timeout interval - * @param properties - * The properties to set for the blob. - * @param blobType - * The type of the blob. - * @param pageBlobSize - * For a page blob, the size of the blob. This parameter is ignored for block blobs. - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for the blob. - * @param blobOptions - * the options to use for the request. - * @param opContext - * a tracking object for the request - * @return a HttpURLConnection to use to perform the operation. - * @throws IOException - * if there is an error opening the connection - * @throws URISyntaxException - * if the resource URI is invalid - * @throws StorageException - * an exception representing any error which occurred during the operation. - * @throws IllegalArgumentException - */ - public static HttpURLConnection put(final URI uri, final int timeout, final BlobProperties properties, - final BlobType blobType, final long pageBlobSize, final AccessCondition accessCondition, - final BlobRequestOptions blobOptions, final OperationContext opContext) throws IOException, - URISyntaxException, StorageException { - if (blobType == BlobType.UNSPECIFIED) { - throw new IllegalArgumentException(SR.BLOB_TYPE_NOT_DEFINED); - } - - final HttpURLConnection request = BlobRequest.createURLConnection(uri, timeout, null, blobOptions, opContext); - - request.setDoOutput(true); - - request.setRequestMethod(Constants.HTTP_PUT); - - addProperties(request, properties); - - if (blobType == BlobType.PAGE_BLOB) { - request.setFixedLengthStreamingMode(0); - request.setRequestProperty(Constants.HeaderConstants.CONTENT_LENGTH, "0"); - - request.setRequestProperty(BlobConstants.BLOB_TYPE_HEADER, BlobConstants.PAGE_BLOB); - request.setRequestProperty(BlobConstants.SIZE, String.valueOf(pageBlobSize)); - - properties.setLength(pageBlobSize); - } - else { - request.setRequestProperty(BlobConstants.BLOB_TYPE_HEADER, BlobConstants.BLOCK_BLOB); - } - - if (accessCondition != null) { - accessCondition.applyConditionToRequest(request); - } - - return request; - } - - /** - * Constructs a HttpURLConnection to upload a block. Sign with length of block data. - * - * @param uri - * The absolute URI to the blob - * @param timeout - * The server timeout interval - * @param blockId - * the Base64 ID for the block - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for the blob. - * @param blobOptions - * the options to use for the request. - * @param opContext - * a tracking object for the request - * @return a HttpURLConnection to use to perform the operation. - * @throws IOException - * if there is an error opening the connection - * @throws URISyntaxException - * if the resource URI is invalid - * @throws StorageException - * an exception representing any error which occurred during the operation. - * @throws IllegalArgumentException - */ - public static HttpURLConnection putBlock(final URI uri, final int timeout, final String blockId, - final AccessCondition accessCondition, final BlobRequestOptions blobOptions, - final OperationContext opContext) throws IOException, URISyntaxException, StorageException { - final UriQueryBuilder builder = new UriQueryBuilder(); - builder.add(Constants.QueryConstants.COMPONENT, BLOCK_QUERY_ELEMENT_NAME); - builder.add(BLOCK_ID_QUERY_ELEMENT_NAME, blockId); - - final HttpURLConnection request = BlobRequest - .createURLConnection(uri, timeout, builder, blobOptions, opContext); - - request.setDoOutput(true); - request.setRequestMethod(Constants.HTTP_PUT); - - if (accessCondition != null) { - accessCondition.applyConditionToRequest(request); - } - - return request; - } - - /** - * Constructs a HttpURLConnection to set the blob's properties, Sign with zero length specified. - * - * @param uri - * The absolute URI to the blob - * @param timeout - * The server timeout interval - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for the blob. - * @param blobOptions - * the options to use for the request. - * @param opContext - * a tracking object for the request - * @return a HttpURLConnection to use to perform the operation. - * @throws IOException - * if there is an error opening the connection - * @throws URISyntaxException - * if the resource URI is invalid - * @throws StorageException - * an exception representing any error which occurred during the operation. - * @throws IllegalArgumentException - */ - public static HttpURLConnection putBlockList(final URI uri, final int timeout, final BlobProperties properties, - final AccessCondition accessCondition, final BlobRequestOptions blobOptions, - final OperationContext opContext) throws IOException, URISyntaxException, StorageException { - - final UriQueryBuilder builder = new UriQueryBuilder(); - builder.add(Constants.QueryConstants.COMPONENT, BLOCK_LIST_QUERY_ELEMENT_NAME); - - final HttpURLConnection request = BlobRequest - .createURLConnection(uri, timeout, builder, blobOptions, opContext); - - request.setDoOutput(true); - request.setRequestMethod(Constants.HTTP_PUT); - - if (accessCondition != null) { - accessCondition.applyConditionToRequest(request); - } - - addProperties(request, properties); - - return request; - } - - /** - * Constructs a HttpURLConnection to upload a page. Sign with page length for update, or 0 for clear. - * - * @param uri - * The absolute URI to the blob - * @param timeout - * The server timeout interval - * @param properties - * the page properties - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for the blob. - * @param blobOptions - * the options to use for the request. - * @param opContext - * a tracking object for the request - * @return a HttpURLConnection to use to perform the operation. - * @throws IOException - * if there is an error opening the connection - * @throws URISyntaxException - * if the resource URI is invalid - * @throws StorageException - * an exception representing any error which occurred during the operation. - * @throws IllegalArgumentException - */ - public static HttpURLConnection putPage(final URI uri, final int timeout, final PageProperties properties, - final AccessCondition accessCondition, final BlobRequestOptions blobOptions, - final OperationContext opContext) throws IOException, URISyntaxException, StorageException { - final UriQueryBuilder builder = new UriQueryBuilder(); - builder.add(Constants.QueryConstants.COMPONENT, PAGE_QUERY_ELEMENT_NAME); - - final HttpURLConnection request = BlobRequest - .createURLConnection(uri, timeout, builder, blobOptions, opContext); - - request.setDoOutput(true); - request.setRequestMethod(Constants.HTTP_PUT); - - if (properties.getPageOperation() == PageOperationType.CLEAR) { - request.setFixedLengthStreamingMode(0); - } - - // Page write is either update or clean; required - request.setRequestProperty(BlobConstants.PAGE_WRITE, properties.getPageOperation().toString()); - request.setRequestProperty(Constants.HeaderConstants.STORAGE_RANGE_HEADER, properties.getRange().toString()); - - if (accessCondition != null) { - accessCondition.applyConditionToRequest(request); - } - - return request; - } - - /** - * Constructs a HttpURLConnection to set the blob's metadata, Sign with 0 length. - * - * @param uri - * The absolute URI to the blob - * @param timeout - * The server timeout interval - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for the blob. - * @param blobOptions - * the options to use for the request. - * @param opContext - * a tracking object for the request - * @return a HttpURLConnection to use to perform the operation. - * @throws IOException - * if there is an error opening the connection - * @throws URISyntaxException - * if the resource URI is invalid - * @throws StorageException - * an exception representing any error which occurred during the operation. - * @throws IllegalArgumentException - */ - public static HttpURLConnection setMetadata(final URI uri, final int timeout, - final AccessCondition accessCondition, final BlobRequestOptions blobOptions, - final OperationContext opContext) throws IOException, URISyntaxException, StorageException { - final HttpURLConnection request = BaseRequest.setMetadata(uri, timeout, null, opContext); - - if (accessCondition != null) { - accessCondition.applyConditionToRequest(request); - } - - return request; - } - - /** - * Constructs a HttpURLConnection to set the blob's properties, Sign with zero length specified. - * - * @param uri - * The absolute URI to the blob - * @param timeout - * The server timeout interval - * @param properties - * The properties to upload. - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for the blob. - * @param blobOptions - * the options to use for the request. - * @param opContext - * a tracking object for the request - * @return a HttpURLConnection to use to perform the operation. - * @throws IOException - * if there is an error opening the connection - * @throws URISyntaxException - * if the resource URI is invalid - * @throws StorageException - * an exception representing any error which occurred during the operation. - * @throws IllegalArgumentException - */ - public static HttpURLConnection setProperties(final URI uri, final int timeout, final BlobProperties properties, - final AccessCondition accessCondition, final BlobRequestOptions blobOptions, - final OperationContext opContext) throws IOException, URISyntaxException, StorageException { - final UriQueryBuilder builder = new UriQueryBuilder(); - builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.PROPERTIES); - - final HttpURLConnection request = BlobRequest - .createURLConnection(uri, timeout, builder, blobOptions, opContext); - - request.setFixedLengthStreamingMode(0); - request.setDoOutput(true); - request.setRequestMethod(Constants.HTTP_PUT); - - if (accessCondition != null) { - accessCondition.applyConditionToRequest(request); - } - - if (properties != null) { - addProperties(request, properties); - } - - return request; - } - - /** - * Constructs a HttpURLConnection to set the blob's size, Sign with zero length specified. - * - * @param uri - * The absolute URI to the blob - * @param timeout - * The server timeout interval - * @param newBlobSize - * The new blob size, if the blob is a page blob. Set this parameter to null to keep the existing blob - * size. - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for the blob. - * @param blobOptions - * the options to use for the request. - * @param opContext - * a tracking object for the request - * @return a HttpURLConnection to use to perform the operation. - * @throws IOException - * if there is an error opening the connection - * @throws URISyntaxException - * if the resource URI is invalid - * @throws StorageException - * an exception representing any error which occurred during the operation. - * @throws IllegalArgumentException - */ - public static HttpURLConnection resize(final URI uri, final int timeout, final Long newBlobSize, - final AccessCondition accessCondition, final BlobRequestOptions blobOptions, - final OperationContext opContext) throws IOException, URISyntaxException, StorageException { - final UriQueryBuilder builder = new UriQueryBuilder(); - builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.PROPERTIES); - - final HttpURLConnection request = BlobRequest - .createURLConnection(uri, timeout, builder, blobOptions, opContext); - - request.setFixedLengthStreamingMode(0); - request.setDoOutput(true); - request.setRequestMethod(Constants.HTTP_PUT); - - if (accessCondition != null) { - accessCondition.applyConditionToRequest(request); - } - - if (newBlobSize != null) { - request.setRequestProperty(BlobConstants.SIZE, newBlobSize.toString()); - } - - return request; - } - - /** - * Constructs a HttpURLConnection to create a snapshot of the blob. Sign with 0 length. - * - * @param uri - * The absolute URI to the blob - * @param timeout - * The server timeout interval - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for the blob. - * @param blobOptions - * the options to use for the request. - * @param opContext - * a tracking object for the request - * @return a HttpURLConnection to use to perform the operation. - * @throws IOException - * if there is an error opening the connection - * @throws URISyntaxException - * if the resource URI is invalid - * @throws StorageException - * an exception representing any error which occurred during the operation. - * @throws IllegalArgumentException - */ - public static HttpURLConnection snapshot(final URI uri, final int timeout, final AccessCondition accessCondition, - final BlobRequestOptions blobOptions, final OperationContext opContext) throws IOException, - URISyntaxException, StorageException { - final UriQueryBuilder builder = new UriQueryBuilder(); - builder.add(Constants.QueryConstants.COMPONENT, BlobConstants.SNAPSHOT); - final HttpURLConnection request = BlobRequest - .createURLConnection(uri, timeout, builder, blobOptions, opContext); - - request.setFixedLengthStreamingMode(0); - request.setDoOutput(true); - request.setRequestMethod(Constants.HTTP_PUT); - - if (accessCondition != null) { - accessCondition.applyConditionToRequest(request); - } - - return request; - } - - /** - * Private Default Ctor - */ - private BlobRequest() { - // No op - } -} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/ContainerRequest.java b/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/ContainerRequest.java deleted file mode 100644 index 8d75901fd92a1..0000000000000 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/ContainerRequest.java +++ /dev/null @@ -1,447 +0,0 @@ -/** - * 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.windowsazure.storage.blob; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.URI; -import java.net.URISyntaxException; -import java.security.InvalidKeyException; -import java.util.HashMap; - -import com.microsoft.windowsazure.storage.AccessCondition; -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.Constants.HeaderConstants; -import com.microsoft.windowsazure.storage.Credentials; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.core.BaseRequest; -import com.microsoft.windowsazure.storage.core.ListingContext; -import com.microsoft.windowsazure.storage.core.UriQueryBuilder; -import com.microsoft.windowsazure.storage.core.Utility; - -/** - * RESERVED FOR INTERNAL USE. A class used to generate requests for contianer objects. - */ -final class ContainerRequest { - /** - * Adds user-defined metadata to the request as one or more name-value pairs. - * - * @param request - * The web request. - * @param metadata - * The user-defined metadata. - * */ - public static void addMetadata(final HttpURLConnection request, final HashMap metadata, - final OperationContext opContext) { - BaseRequest.addMetadata(request, metadata, opContext); - } - - /** - * Adds user-defined metadata to the request as a single name-value pair. - * - * @param request - * The web request. - * @param name - * The metadata name. - * @param value - * The metadata value. - * */ - public static void addMetadata(final HttpURLConnection request, final String name, final String value, - final OperationContext opContext) { - BaseRequest.addMetadata(request, name, value, opContext); - } - - /** - * Constructs a web request to create a new container. Sign with 0 length. - * - * @param uri - * The absolute URI to the container. - * @param timeout - * The server timeout interval. - * @return a HttpURLConnection configured for the operation. - * @throws StorageException - * @throws IllegalArgumentException - */ - public static HttpURLConnection create(final URI uri, final int timeout, final OperationContext opContext) - throws IOException, URISyntaxException, StorageException { - final UriQueryBuilder containerBuilder = getContainerUriQueryBuilder(); - return BaseRequest.create(uri, timeout, containerBuilder, opContext); - } - - /** - * Creates the web request. - * - * @param uri - * The absolute URI to the container. - * @param timeout - * The server timeout interval. - * @param query - * The query builder to use. - * @return a HttpURLConnection configured for the operation. - * @throws StorageException - * @throws IllegalArgumentException - */ - private static HttpURLConnection createURLConnection(final URI uri, final int timeout, final UriQueryBuilder query, - final OperationContext opContext) throws IOException, URISyntaxException, StorageException { - return BaseRequest.createURLConnection(uri, timeout, query, opContext); - } - - /** - * Constructs a web request to delete the container and all of blobs within it. Sign with no length specified. - * - * @param uri - * The absolute URI to the container. - * @param timeout - * The server timeout interval. - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for the container. - * @return a HttpURLConnection configured for the operation. - * @throws StorageException - * @throws IllegalArgumentException - */ - public static HttpURLConnection delete(final URI uri, final int timeout, final AccessCondition accessCondition, - final OperationContext opContext) throws IOException, URISyntaxException, StorageException { - final UriQueryBuilder containerBuilder = getContainerUriQueryBuilder(); - HttpURLConnection request = BaseRequest.delete(uri, timeout, containerBuilder, opContext); - if (accessCondition != null) { - accessCondition.applyConditionToRequest(request); - } - - return request; - } - - /** - * Constructs a web request to return the ACL for this container. Sign with no length specified. - * - * @param uri - * The absolute URI to the container. - * @param timeout - * The server timeout interval. - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for the container. - * @param opContext - * An {@link OperationContext} object that 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. - * @return a HttpURLConnection configured for the operation. - * @throws StorageException - */ - public static HttpURLConnection getAcl(final URI uri, final int timeout, final AccessCondition accessCondition, - final OperationContext opContext) throws IOException, URISyntaxException, StorageException { - final UriQueryBuilder builder = getContainerUriQueryBuilder(); - builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.ACL); - - final HttpURLConnection request = createURLConnection(uri, timeout, builder, opContext); - - request.setRequestMethod(Constants.HTTP_GET); - - if (accessCondition != null && !Utility.isNullOrEmpty(accessCondition.getLeaseID())) { - BaseRequest.addLeaseId(request, accessCondition.getLeaseID()); - } - - return request; - } - - /** - * Gets the container Uri query builder. - * - * A UriQueryBuilder for the container. - * - * @throws StorageException - */ - protected static UriQueryBuilder getContainerUriQueryBuilder() throws StorageException { - final UriQueryBuilder uriBuilder = new UriQueryBuilder(); - try { - uriBuilder.add(Constants.QueryConstants.RESOURCETYPE, "container"); - } - catch (final IllegalArgumentException e) { - throw Utility.generateNewUnexpectedStorageException(e); - } - return uriBuilder; - } - - /** - * Constructs a web request to retrieve the container's metadata. Sign with no length specified. - * - * @param uri - * The absolute URI to the container. - * @param timeout - * The server timeout interval. - * @return a HttpURLConnection configured for the operation. - * @throws StorageException - */ - public static HttpURLConnection getMetadata(final URI uri, final int timeout, AccessCondition accessCondition, - final OperationContext opContext) throws IOException, URISyntaxException, StorageException { - final UriQueryBuilder containerBuilder = getContainerUriQueryBuilder(); - HttpURLConnection request = BaseRequest.getMetadata(uri, timeout, containerBuilder, opContext); - if (accessCondition != null && !Utility.isNullOrEmpty(accessCondition.getLeaseID())) { - BaseRequest.addLeaseId(request, accessCondition.getLeaseID()); - } - return request; - } - - /** - * Constructs a web request to return the user-defined metadata for this container. Sign with no length specified. - * - * @param uri - * The absolute URI to the container. - * @param timeout - * The server timeout interval. - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for the container. - * @return a HttpURLConnection configured for the operation. - * @throws StorageException - * */ - public static HttpURLConnection getProperties(final URI uri, final int timeout, AccessCondition accessCondition, - final OperationContext opContext) throws IOException, URISyntaxException, StorageException { - final UriQueryBuilder containerBuilder = getContainerUriQueryBuilder(); - HttpURLConnection request = BaseRequest.getProperties(uri, timeout, containerBuilder, opContext); - if (accessCondition != null && !Utility.isNullOrEmpty(accessCondition.getLeaseID())) { - BaseRequest.addLeaseId(request, accessCondition.getLeaseID()); - } - - return request; - } - - /** - * Constructs a request to return a listing of all containers in this storage account. Sign with no length - * specified. - * - * @param uri - * The absolute URI for the account. - * @param timeout - * The absolute URI for the account. - * @param listingContext - * A set of parameters for the listing operation. - * @param detailsIncluded - * Additional details to return with the listing. - * @param opContext - * a tracking object for the request - * @return a HttpURLConnection configured for the operation. - * @throws IOException - * @throws URISyntaxException - * @throws StorageException - * @throws IllegalArgumentException - */ - public static HttpURLConnection list(final URI uri, final int timeout, final ListingContext listingContext, - final ContainerListingDetails detailsIncluded, final OperationContext opContext) throws URISyntaxException, - IOException, StorageException { - - final UriQueryBuilder builder = getContainerUriQueryBuilder(); - builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.LIST); - - if (listingContext != null) { - if (!Utility.isNullOrEmpty(listingContext.getPrefix())) { - builder.add(Constants.QueryConstants.PREFIX, listingContext.getPrefix()); - } - - if (!Utility.isNullOrEmpty(listingContext.getMarker())) { - builder.add(Constants.QueryConstants.MARKER, listingContext.getMarker()); - } - - if (listingContext.getMaxResults() != null && listingContext.getMaxResults() > 0) { - builder.add(Constants.QueryConstants.MAX_RESULTS, listingContext.getMaxResults().toString()); - } - } - - if (detailsIncluded == ContainerListingDetails.ALL || detailsIncluded == ContainerListingDetails.METADATA) { - builder.add(Constants.QueryConstants.INCLUDE, Constants.QueryConstants.METADATA); - } - - final HttpURLConnection request = createURLConnection(uri, timeout, builder, opContext); - - request.setRequestMethod(Constants.HTTP_GET); - - return request; - } - - /** - * Sets the ACL for the container. , Sign with length of aclBytes. - * - * @param uri - * The absolute URI to the container. - * @param timeout - * The server timeout interval. - * @param publicAccess - * The type of public access to allow for the container. - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for the container. - * @param opContext - * An {@link OperationContext} object that 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. - * @return a HttpURLConnection configured for the operation. - * @throws StorageException - * */ - public static HttpURLConnection setAcl(final URI uri, final int timeout, - final BlobContainerPublicAccessType publicAccess, final AccessCondition accessCondition, - final OperationContext opContext) throws IOException, URISyntaxException, StorageException { - final UriQueryBuilder builder = getContainerUriQueryBuilder(); - builder.add(Constants.QueryConstants.COMPONENT, Constants.QueryConstants.ACL); - - final HttpURLConnection request = createURLConnection(uri, timeout, builder, opContext); - - request.setRequestMethod(Constants.HTTP_PUT); - request.setDoOutput(true); - - if (publicAccess != BlobContainerPublicAccessType.OFF) { - request.setRequestProperty(BlobConstants.BLOB_PUBLIC_ACCESS_HEADER, publicAccess.toString().toLowerCase()); - } - - if (accessCondition != null && !Utility.isNullOrEmpty(accessCondition.getLeaseID())) { - BaseRequest.addLeaseId(request, accessCondition.getLeaseID()); - } - - return request; - } - - /** - * Constructs a web request to set user-defined metadata for the container, Sign with 0 Length. - * - * @param uri - * The absolute URI to the container. - * @param timeout - * The server timeout interval. - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for the container. - * @param opContext - * An {@link OperationContext} object that 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. - * @return a HttpURLConnection configured for the operation. - * @throws StorageException - * */ - public static HttpURLConnection setMetadata(final URI uri, final int timeout, - final AccessCondition accessCondition, final OperationContext opContext) throws IOException, - URISyntaxException, StorageException { - final UriQueryBuilder containerBuilder = getContainerUriQueryBuilder(); - HttpURLConnection request = BaseRequest.setMetadata(uri, timeout, containerBuilder, opContext); - if (accessCondition != null) { - accessCondition.applyConditionToRequest(request); - } - - return request; - } - - /** - * Constructs a HttpURLConnection to Acquire,Release,Break, or Renew a blob lease. Sign with 0 length. - * - * @param uri - * The absolute URI to the blob - * @param timeout - * The server timeout interval - * @param action - * the LeaseAction to perform - * - * @param visibilityTimeoutInSeconds - * Specifies the the span of time for which to acquire the lease, in seconds. - * If null, an infinite lease will be acquired. If not null, this must be greater than zero. - * - * @param proposedLeaseId - * A String that represents the proposed lease ID for the new lease, - * or null if no lease ID is proposed. - * - * @param breakPeriodInSeconds - * Specifies the amount of time to allow the lease to remain, in seconds. - * If null, the break period is the remainder of the current lease, or zero for infinite leases. - * - * @param accessCondition - * An {@link AccessCondition} object that represents the access conditions for the blob. - * @param blobOptions - * the options to use for the request. - * @param opContext - * a tracking object for the request - * @return a HttpURLConnection to use to perform the operation. - * @throws IOException - * if there is an error opening the connection - * @throws URISyntaxException - * if the resource URI is invalid - * @throws StorageException - * an exception representing any error which occurred during the operation. - * @throws IllegalArgumentException - */ - public static HttpURLConnection lease(final URI uri, final int timeout, final LeaseAction action, - final Integer leaseTimeInSeconds, final String proposedLeaseId, final Integer breakPeriodInSeconds, - final AccessCondition accessCondition, final BlobRequestOptions blobOptions, - final OperationContext opContext) throws IOException, URISyntaxException, StorageException { - - final UriQueryBuilder builder = getContainerUriQueryBuilder(); - builder.add(Constants.QueryConstants.COMPONENT, BlobConstants.LEASE); - - final HttpURLConnection request = createURLConnection(uri, timeout, builder, opContext); - - request.setDoOutput(true); - request.setRequestMethod(Constants.HTTP_PUT); - request.setFixedLengthStreamingMode(0); - request.setRequestProperty(HeaderConstants.LEASE_ACTION_HEADER, action.toString()); - - if (leaseTimeInSeconds != null) { - request.setRequestProperty(HeaderConstants.LEASE_DURATION, leaseTimeInSeconds.toString()); - } - else { - request.setRequestProperty(HeaderConstants.LEASE_DURATION, "-1"); - } - - if (proposedLeaseId != null) { - request.setRequestProperty(HeaderConstants.PROPOSED_LEASE_ID_HEADER, proposedLeaseId); - } - - if (breakPeriodInSeconds != null) { - request.setRequestProperty(HeaderConstants.LEASE_BREAK_PERIOD_HEADER, breakPeriodInSeconds.toString()); - } - - if (accessCondition != null) { - accessCondition.applyConditionToRequest(request); - } - return request; - } - - /** - * Signs the request for Shared Key authentication. - * - * @param request - * The web request. - * @param credentials - * The account credentials. - * @throws StorageException - * */ - public static void signRequest(final HttpURLConnection request, final Credentials credentials, - final Long contentLength, final OperationContext opContext) throws InvalidKeyException, StorageException { - BaseRequest.signRequestForBlobAndQueue(request, credentials, contentLength, opContext); - } - - /** - * Signs the request for Shared Key Lite authentication. - * - * @param request - * The web request. - * @param credentials - * The account credentials. - * @throws StorageException - * @throws InvalidKeyException - * */ - public static void signRequestForSharedKeyLite(final HttpURLConnection request, final Credentials credentials, - final Long contentLength, final OperationContext opContext) throws InvalidKeyException, StorageException { - BaseRequest.signRequestForBlobAndQueueSharedKeyLite(request, credentials, contentLength, opContext); - } - - /** - * Private Default Ctor - */ - private ContainerRequest() { - // No op - } -} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/ContainerResponse.java b/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/ContainerResponse.java deleted file mode 100644 index 9974abe534560..0000000000000 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/ContainerResponse.java +++ /dev/null @@ -1,78 +0,0 @@ -/** - * 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.windowsazure.storage.blob; - -import java.net.HttpURLConnection; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Date; - -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.core.BaseResponse; -import com.microsoft.windowsazure.storage.core.PathUtility; -import com.microsoft.windowsazure.storage.core.Utility; - -/** - * RESERVED FOR INTERNAL USE. A class used to parse the response from container operations - */ -final class ContainerResponse extends BaseResponse { - - /** - * Gets the ACL for the container from the response. - * - * @param request - * the request object for this operation - * @return the ACL value indicating the public access level for the container - */ - public static String getAcl(final HttpURLConnection request) { - return request.getHeaderField(BlobConstants.BLOB_PUBLIC_ACCESS_HEADER); - } - - /** - * Gets the BlobContainerAttributes from the given request. - * - * @param request - * the request to get attributes from. - * @param usePathStyleUris - * a value indicating if the account is using pathSytleUris. - * @return the BlobContainerAttributes from the given request. - * @throws StorageException - */ - public static BlobContainerAttributes getAttributes(final HttpURLConnection request, final boolean usePathStyleUris) - throws StorageException { - final BlobContainerAttributes containerAttributes = new BlobContainerAttributes(); - URI tempURI; - try { - tempURI = PathUtility.stripSingleURIQueryAndFragment(request.getURL().toURI()); - } - catch (final URISyntaxException e) { - final StorageException wrappedUnexpectedException = Utility.generateNewUnexpectedStorageException(e); - throw wrappedUnexpectedException; - } - - containerAttributes.setName(PathUtility.getContainerNameFromUri(tempURI, usePathStyleUris)); - - final BlobContainerProperties containerProperties = containerAttributes.getProperties(); - containerProperties.setEtag(BaseResponse.getEtag(request)); - containerProperties.setLastModified(new Date(request.getLastModified())); - containerAttributes.setMetadata(getMetadata(request)); - - containerProperties.setLeaseStatus(BaseResponse.getLeaseStatus(request)); - containerProperties.setLeaseState(BaseResponse.getLeaseState(request)); - containerProperties.setLeaseDuration(BaseResponse.getLeaseDuration(request)); - - return containerAttributes; - } -} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/package.html b/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/package.html deleted file mode 100644 index cbf5ee75f3777..0000000000000 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/blob/package.html +++ /dev/null @@ -1,5 +0,0 @@ - - -This package contains the integrated blob service client classes and implementation. - - diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/SharedAccessPolicyDeserializer.java b/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/SharedAccessPolicyDeserializer.java deleted file mode 100644 index b3d38a2148a6e..0000000000000 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/SharedAccessPolicyDeserializer.java +++ /dev/null @@ -1,221 +0,0 @@ -/** - * 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.windowsazure.storage.core; - -import java.io.InputStream; -import java.text.ParseException; -import java.util.HashMap; - -import javax.xml.stream.XMLStreamConstants; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; - -import com.microsoft.windowsazure.storage.Constants; - -/** - * RESERVED FOR INTERNAL USE. A class used to parse SharedAccessPolicies from an input stream. - */ -public final class SharedAccessPolicyDeserializer { - - /** - * Gets the HashMap of SharedAccessPolicies from the response. - * - * @param stream - * the stream to read from - * @param cls - * the SharedAccessPolicy class type - * @return the HashMap of SharedAccessPolicies from the response - * @throws XMLStreamException - * if an XMLStreamException occurs. - * @throws ParseException - * if a date is incorrectly encoded in the stream - * @throws InstantiationException - * the class cls cannot be instantiated - * @throws IllegalAccessException - * the class cls cannot be instantiated - */ - public static HashMap getAccessIdentifiers(final InputStream stream, - final Class cls) throws XMLStreamException, ParseException, InstantiationException, - IllegalAccessException { - final XMLStreamReader xmlr = DeserializationHelper.createXMLStreamReaderFromStream(stream); - - final HashMap policies = new HashMap(); - - // Start document - int eventType = xmlr.getEventType(); - xmlr.require(XMLStreamConstants.START_DOCUMENT, null, null); - - // check if there are more events in the input stream - while (xmlr.hasNext()) { - eventType = xmlr.next(); - - if (eventType == XMLStreamConstants.START_ELEMENT || eventType == XMLStreamConstants.END_ELEMENT) { - final String name = xmlr.getName().toString(); - - if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(Constants.SIGNED_IDENTIFIERS_ELEMENT)) { - readPolicies(xmlr, policies, cls); - } - } - } - - return policies; - } - - /** - * Reads all the policies from the XMLStreamReader - * - * @param xmlr - * the XMLStreamReader to read from - * @param cls - * the SharedAccessPolicy class type - * @param policies - * the HashMap of SharedAccessPolicies to add to - * @throws XMLStreamException - * if an XMLStreamException occurs. - * @throws ParseException - * if a date is incorrectly encoded in the stream - * @throws InstantiationException - * the class cls cannot be instantiated - * @throws IllegalAccessException - * the class cls cannot be instantiated - */ - private static void readPolicies(final XMLStreamReader xmlr, - HashMap policies, final Class cls) throws XMLStreamException, ParseException, - InstantiationException, IllegalAccessException { - int eventType = xmlr.getEventType(); - - xmlr.require(XMLStreamConstants.START_ELEMENT, null, Constants.SIGNED_IDENTIFIERS_ELEMENT); - - while (xmlr.hasNext()) { - eventType = xmlr.next(); - - if (eventType == XMLStreamConstants.START_ELEMENT || eventType == XMLStreamConstants.END_ELEMENT) { - final String name = xmlr.getName().toString(); - - if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(Constants.SIGNED_IDENTIFIER_ELEMENT)) { - readSignedIdentifier(xmlr, policies, cls); - } - else if (eventType == XMLStreamConstants.END_ELEMENT - && name.equals(Constants.SIGNED_IDENTIFIERS_ELEMENT)) { - break; - } - } - } - - xmlr.require(XMLStreamConstants.END_ELEMENT, null, Constants.SIGNED_IDENTIFIERS_ELEMENT); - } - - /** - * Reads a policy identifier / Shared Access Policy pair from the stream - * - * @param xmlr - * the XMLStreamReader to read from - * @param cls - * the SharedAccessPolicy class type - * @param policies - * the HashMap of SharedAccessPolicies to add to - * @throws XMLStreamException - * if an XMLStreamException occurs. - * @throws ParseException - * if a date is incorrectly encoded in the stream - * @throws InstantiationException - * the class cls cannot be instantiated - * @throws IllegalAccessException - * the class cls cannot be instantiated - */ - private static void readSignedIdentifier(final XMLStreamReader xmlr, - HashMap policies, final Class cls) throws XMLStreamException, ParseException, - InstantiationException, IllegalAccessException { - int eventType = xmlr.getEventType(); - xmlr.require(XMLStreamConstants.START_ELEMENT, null, Constants.SIGNED_IDENTIFIER_ELEMENT); - - String id = null; - T policy = null; - while (xmlr.hasNext()) { - eventType = xmlr.next(); - - if (eventType == XMLStreamConstants.START_ELEMENT || eventType == XMLStreamConstants.END_ELEMENT) { - final String name = xmlr.getName().toString(); - - if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(Constants.ID)) { - id = DeserializationHelper.readElementFromXMLReader(xmlr, Constants.ID); - } - else if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(Constants.ACCESS_POLICY)) { - policy = readPolicyFromXML(xmlr, cls); - } - else if (eventType == XMLStreamConstants.END_ELEMENT - && name.equals(Constants.SIGNED_IDENTIFIER_ELEMENT)) { - policies.put(id, policy); - break; - } - } - } - - xmlr.require(XMLStreamConstants.END_ELEMENT, null, Constants.SIGNED_IDENTIFIER_ELEMENT); - } - - /** - * Populates the object from the XMLStreamReader, reader must be at Start element of AccessPolicy. - * - * @param xmlr - * the XMLStreamReader to read from - * @param cls - * the SharedAccessPolicy class type - * @return the SharedAccessPolicy of class cls - * @throws XMLStreamException - * if an XMLStreamException occurs. - * @throws ParseException - * if a date is incorrectly encoded in the stream - * @throws InstantiationException - * the class cls cannot be instantiated - * @throws IllegalAccessException - * the class cls cannot be instantiated - */ - private static T readPolicyFromXML(final XMLStreamReader xmlr, final Class cls) - throws XMLStreamException, ParseException, InstantiationException, IllegalAccessException { - int eventType = xmlr.getEventType(); - - xmlr.require(XMLStreamConstants.START_ELEMENT, null, Constants.ACCESS_POLICY); - - final T retPolicy = cls.newInstance(); - - while (xmlr.hasNext()) { - eventType = xmlr.next(); - - if (eventType == XMLStreamConstants.START_ELEMENT || eventType == XMLStreamConstants.END_ELEMENT) { - final String name = xmlr.getName().toString(); - - if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(Constants.PERMISSION)) { - retPolicy.setPermissionsFromString(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.PERMISSION)); - } - else if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(Constants.START)) { - final String tempString = DeserializationHelper.readElementFromXMLReader(xmlr, Constants.START); - retPolicy.setSharedAccessStartTime(Utility.parseISO8061LongDateFromString(tempString)); - } - else if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(Constants.EXPIRY)) { - final String tempString = DeserializationHelper.readElementFromXMLReader(xmlr, Constants.EXPIRY); - retPolicy.setSharedAccessExpiryTime(Utility.parseISO8061LongDateFromString(tempString)); - } - else if (eventType == XMLStreamConstants.END_ELEMENT && name.equals(Constants.ACCESS_POLICY)) { - break; - } - } - } - - xmlr.require(XMLStreamConstants.END_ELEMENT, null, Constants.ACCESS_POLICY); - return retPolicy; - } -} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/StorageErrorDeserializer.java b/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/StorageErrorDeserializer.java deleted file mode 100644 index aba3d5bbd0209..0000000000000 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/core/StorageErrorDeserializer.java +++ /dev/null @@ -1,163 +0,0 @@ -/** - * 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.windowsazure.storage.core; - -import java.io.InputStream; -import java.io.Reader; -import java.util.HashMap; - -import javax.xml.stream.XMLStreamConstants; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; - -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.StorageExtendedErrorInformation; - -/*** - * RESERVED FOR INTERNAL USE. A class to help parse the Error details from an input stream. - */ -public final class StorageErrorDeserializer { - - /** - * Gets the Extended Error information from the response stream. - * - * @return the Extended Error information from the response stream - * @throws XMLStreamException - * if an xml exception occurs - */ - public static StorageExtendedErrorInformation getExtendedErrorInformation(final Reader reader) - throws XMLStreamException { - final XMLStreamReader xmlr = DeserializationHelper.createXMLStreamReaderFromReader(reader); - return parseResponse(xmlr); - } - - /** - * Gets the Extended Error information from the response stream. - * - * @return the Extended Error information from the response stream - * @throws XMLStreamException - * if an xml exception occurs - */ - public static StorageExtendedErrorInformation getExtendedErrorInformation(final InputStream stream) - throws XMLStreamException { - final XMLStreamReader xmlr = DeserializationHelper.createXMLStreamReaderFromStream(stream); - return parseResponse(xmlr); - } - - /** - * Parses the extended error information from the response stream. - * - * @throws XMLStreamException - * if an xml exception occurs - */ - private static StorageExtendedErrorInformation parseResponse(final XMLStreamReader xmlr) throws XMLStreamException { - final StorageExtendedErrorInformation errorInfo = new StorageExtendedErrorInformation(); - - String tempParseString; - - // Start document - int eventType = xmlr.getEventType(); - xmlr.require(XMLStreamConstants.START_DOCUMENT, null, null); - - // 1. get Error Root Header - eventType = xmlr.next(); - xmlr.require(XMLStreamConstants.START_ELEMENT, null, Constants.ERROR_ROOT_ELEMENT); - - while (xmlr.hasNext()) { - eventType = xmlr.next(); - if (eventType == XMLStreamConstants.CHARACTERS) { - continue; - } - - if (eventType == XMLStreamConstants.END_ELEMENT) { - break; - } - - String name = xmlr.getName().getLocalPart().toString(); - - if (eventType == XMLStreamConstants.START_ELEMENT) { - - if (name.equals(Constants.ERROR_CODE)) { - errorInfo.setErrorCode(DeserializationHelper.readElementFromXMLReader(xmlr, Constants.ERROR_CODE)); - } - else if (name.equals(Constants.ERROR_MESSAGE)) { - errorInfo.setErrorMessage(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.ERROR_MESSAGE)); - } - else if (name.equals(Constants.ERROR_EXCEPTION)) { - // get error exception - errorInfo.getAdditionalDetails().putAll(parseErrorException(xmlr)); - xmlr.require(XMLStreamConstants.END_ELEMENT, null, Constants.ERROR_EXCEPTION); - } - else { - // get additional details - tempParseString = DeserializationHelper.readElementFromXMLReader(xmlr, name); - - errorInfo.getAdditionalDetails().put(name, new String[] { tempParseString }); - - xmlr.require(XMLStreamConstants.END_ELEMENT, null, null); - } - } - } - - return errorInfo; - } - - /** - * Parses the Error Exception details from the response. - * - * @param xmlr - * the XMLStreamReader to read from - * @throws XMLStreamException - * if an xml exception occurs - */ - private static HashMap parseErrorException(final XMLStreamReader xmlr) throws XMLStreamException { - int eventType = xmlr.getEventType(); - - xmlr.require(XMLStreamConstants.START_ELEMENT, null, Constants.ERROR_EXCEPTION); - - HashMap additionalDetails = new HashMap(); - while (xmlr.hasNext()) { - eventType = xmlr.next(); - if (eventType == XMLStreamConstants.CHARACTERS) { - continue; - } - - final String name = xmlr.getName().toString(); - - if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(Constants.ERROR_EXCEPTION_MESSAGE)) { - final String errorExceptionMessage = DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.ERROR_EXCEPTION_MESSAGE); - additionalDetails.put(Constants.ERROR_EXCEPTION_MESSAGE, new String[] { errorExceptionMessage }); - - } - else if (eventType == XMLStreamConstants.START_ELEMENT - && name.equals(Constants.ERROR_EXCEPTION_STACK_TRACE)) { - final String errorExceptionStack = DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.ERROR_EXCEPTION_STACK_TRACE); - additionalDetails.put(Constants.ERROR_EXCEPTION_STACK_TRACE, new String[] { errorExceptionStack }); - } - else if (eventType == XMLStreamConstants.END_ELEMENT) { - break; - } - } - - xmlr.require(XMLStreamConstants.END_ELEMENT, null, Constants.ERROR_EXCEPTION); - - return additionalDetails; - } - -} \ No newline at end of file diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/package.html b/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/package.html deleted file mode 100644 index b1450b0ca78a2..0000000000000 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/package.html +++ /dev/null @@ -1,5 +0,0 @@ - - -This package contains the blob service core class and interface, - - diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueDeserializer.java b/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueDeserializer.java deleted file mode 100644 index a8cfd7eb21ef8..0000000000000 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/QueueDeserializer.java +++ /dev/null @@ -1,329 +0,0 @@ -/** - * 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.windowsazure.storage.queue; - -import java.io.InputStream; -import java.net.URISyntaxException; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.HashMap; - -import javax.xml.stream.XMLStreamConstants; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; - -import com.microsoft.windowsazure.storage.Constants; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.StorageUri; -import com.microsoft.windowsazure.storage.core.DeserializationHelper; -import com.microsoft.windowsazure.storage.core.ListResponse; -import com.microsoft.windowsazure.storage.core.PathUtility; -import com.microsoft.windowsazure.storage.core.Utility; - -/** - * RESERVED FOR INTERNAL USE. A class used to parse a message list response stream. - */ -final class QueueDeserializer { - /** - * Parses the input stream containing the response body of the list queues - * request result and populates the class data. - * - * @param serviceClient - * A {@link CloudQueueClient} object associated with the storage - * service. - * - * @throws XMLStreamException - * If the input stream cannot be read or parsed as a list queues - * response. - * @throws StorageException - */ - public static ListResponse getQueues(final InputStream stream, final CloudQueueClient serviceClient) - throws XMLStreamException, StorageException { - final XMLStreamReader xmlr = DeserializationHelper.createXMLStreamReaderFromStream(stream); - - ListResponse queues = new ListResponse(); - - String tempParseString = null; - - // Start document - int eventType = xmlr.getEventType(); - xmlr.require(XMLStreamConstants.START_DOCUMENT, null, null); - - // 1. get enumerationResults Header - eventType = xmlr.next(); - xmlr.require(XMLStreamConstants.START_ELEMENT, null, "EnumerationResults"); - - // check if there are more events in the input stream - while (xmlr.hasNext()) { - eventType = xmlr.next(); - - if (eventType == XMLStreamConstants.START_ELEMENT || eventType == XMLStreamConstants.END_ELEMENT) { - final String name = xmlr.getName().toString(); - if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(Constants.MAX_RESULTS_ELEMENT)) { - tempParseString = DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.MAX_RESULTS_ELEMENT); - queues.setMaxResults(Integer.parseInt(tempParseString)); - } - else if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(Constants.MARKER_ELEMENT)) { - queues.setMarker(DeserializationHelper.readElementFromXMLReader(xmlr, Constants.MARKER_ELEMENT)); - } - else if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(Constants.NEXT_MARKER_ELEMENT)) { - queues.setNextMarker(DeserializationHelper.readElementFromXMLReader(xmlr, - Constants.NEXT_MARKER_ELEMENT)); - } - else if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(Constants.PREFIX_ELEMENT)) { - queues.setPrefix(DeserializationHelper.readElementFromXMLReader(xmlr, Constants.PREFIX_ELEMENT)); - } - else if (eventType == XMLStreamConstants.START_ELEMENT && name.equals(QueueConstants.QUEUES_ELEMENT)) { - try { - queues.setResults(readQueues(xmlr, serviceClient)); - } - catch (final URISyntaxException e) { - throw new XMLStreamException(e); - } - catch (final ParseException e) { - throw new XMLStreamException(e); - } - - xmlr.require(XMLStreamConstants.END_ELEMENT, null, QueueConstants.QUEUES_ELEMENT); - // eventType = xmlr.next(); - } - else if (eventType == XMLStreamConstants.END_ELEMENT && "EnumerationResults".equals(name)) { - break; - } - } - } - - return queues; - } - - /** - * Reserved for internal use. - * - * Populates the queue from an XMLStreamReader - * - * @param xmlr - * The XMLStreamReader to read from. - * @param serviceClient - * The {@link CloudQueueClient} to create the return value with. - * - * @return A {@link CloudQueue} populated with the deserialized data. - * - * @throws XMLStreamException - * If there is a parsing exception. - * @throws ParseException - * If a date value is not correctly encoded. - * @throws URISyntaxException - * If the URI is not valid. - * @throws StorageException - * If a storage service error occurred during the operation. - */ - private static CloudQueue readQueue(final XMLStreamReader xmlr, final CloudQueueClient serviceClient) - throws XMLStreamException, ParseException, URISyntaxException, StorageException { - - xmlr.require(XMLStreamConstants.START_ELEMENT, null, QueueConstants.QUEUE_ELEMENT); - - String queueName = null; - HashMap queueMetadata = null; - - int eventType = xmlr.getEventType(); - - while (xmlr.hasNext()) { - eventType = xmlr.next(); - final String name = xmlr.getName().toString(); - if (eventType == XMLStreamConstants.START_ELEMENT) { - if (name.equals(Constants.NAME_ELEMENT)) { - queueName = DeserializationHelper.readElementFromXMLReader(xmlr, Constants.NAME_ELEMENT); - } - else if (name.equals(Constants.METADATA_ELEMENT)) { - // parse metadata - queueMetadata = DeserializationHelper.parseMetadateFromXML(xmlr); - xmlr.require(XMLStreamConstants.END_ELEMENT, null, Constants.METADATA_ELEMENT); - } - } - else if (eventType == XMLStreamConstants.END_ELEMENT && name.equals(QueueConstants.QUEUE_ELEMENT)) { - break; - } - } - - StorageUri queueUri = serviceClient.getStorageUri(); - - queueUri = PathUtility.appendPathToUri(queueUri, queueName); - - final CloudQueue queue = new CloudQueue(queueUri, serviceClient); - queue.setMetadata(queueMetadata); - queue.setName(queueName); - - xmlr.require(XMLStreamConstants.END_ELEMENT, null, QueueConstants.QUEUE_ELEMENT); - return queue; - } - - /** - * Populates CloudQueue objects from the XMLStreamReader; the reader must be - * at the Start element of QueuesElement. - * - * @param xmlr - * The XMLStreamReader to read from. - * @param serviceClient - * The {@link CloudQueueClient} to create the return value with. - * - * @return An ArrayList of{@link CloudQueue} populated with the - * deserialized data. - * - * @throws XMLStreamException - * If there is a parsing exception. - * @throws ParseException - * If a date value is not correctly encoded. - * @throws URISyntaxException - * If the URI is not valid. - * @throws StorageException - * If a storage service error occurred during the operation. - */ - private static ArrayList readQueues(final XMLStreamReader xmlr, final CloudQueueClient serviceClient) - throws XMLStreamException, ParseException, URISyntaxException, StorageException { - int eventType = xmlr.getEventType(); - xmlr.require(XMLStreamConstants.START_ELEMENT, null, QueueConstants.QUEUES_ELEMENT); - - final ArrayList queues = new ArrayList(); - - eventType = xmlr.next(); - while (eventType == XMLStreamConstants.START_ELEMENT && xmlr.hasName() - && QueueConstants.QUEUE_ELEMENT.equals(xmlr.getName().toString())) { - queues.add(readQueue(xmlr, serviceClient)); - eventType = xmlr.next(); - } - - xmlr.require(XMLStreamConstants.END_ELEMENT, null, QueueConstants.QUEUES_ELEMENT); - return queues; - } - - /** - * Populates CloudQueueMessage objects from the XMLStreamReader; the reader - * must be at the Start element of QueuesElement. - * - * @param stream - * The InputStream object to deserialize from. - * @param shouldEncodeMessage - * A flag indicating whether messages should be base-64 encoded. - * - * @return An ArrayList of {@link CloudQueueMessage} from the - * stream. - * - * @throws XMLStreamException - * If there is a parsing exception. - * @throws ParseException - * If a date value is not correctly encoded. - * @throws URISyntaxException - * If the URI is not valid. - * @throws StorageException - * If a storage service error occurred during the operation. - */ - protected static ArrayList readMessages(final InputStream stream, - final boolean shouldEncodeMessage) throws XMLStreamException, ParseException, URISyntaxException, - StorageException { - final XMLStreamReader xmlr = DeserializationHelper.createXMLStreamReaderFromStream(stream); - - // Start document - int eventType = xmlr.getEventType(); - xmlr.require(XMLStreamConstants.START_DOCUMENT, null, null); - - eventType = xmlr.next(); - xmlr.require(XMLStreamConstants.START_ELEMENT, null, QueueConstants.QUEUE_MESSAGES_LIST_ELEMENT); - - final ArrayList messages = new ArrayList(); - - eventType = xmlr.next(); - while (eventType == XMLStreamConstants.START_ELEMENT && xmlr.hasName() - && QueueConstants.QUEUE_MESSAGE_ELEMENT.equals(xmlr.getName().toString())) { - messages.add(readMessage(xmlr, shouldEncodeMessage)); - eventType = xmlr.next(); - } - - xmlr.require(XMLStreamConstants.END_ELEMENT, null, QueueConstants.QUEUE_MESSAGES_LIST_ELEMENT); - return messages; - } - - /** - * Populates the message from an XMLStreamReader. - * - * @param xmlr - * The XMLStreamReader to read from. - * @param shouldEncodeMessage - * A flag indicating whether messages should be base-64 encoded. - * - * @return A {@link CloudQueueMessage} from the stream. - * - * @throws XMLStreamException - * if there is an error parsing the stream - * @throws ParseException - * if there is an error in parsing a date - * @throws URISyntaxException - * if the uri is invalid - * @throws StorageException - * If a storage service error occurred during the operation. - */ - private static CloudQueueMessage readMessage(final XMLStreamReader xmlr, final boolean shouldEncodeMessage) - throws XMLStreamException, ParseException, URISyntaxException, StorageException { - - xmlr.require(XMLStreamConstants.START_ELEMENT, null, QueueConstants.QUEUE_MESSAGE_ELEMENT); - - final CloudQueueMessage message = new CloudQueueMessage(); - message.setMessageType(shouldEncodeMessage ? QueueMessageType.BASE_64_ENCODED : QueueMessageType.RAW_STRING); - - int eventType = xmlr.getEventType(); - - while (xmlr.hasNext()) { - eventType = xmlr.next(); - final String name = xmlr.getName().toString(); - if (eventType == XMLStreamConstants.START_ELEMENT) { - if (name.equals(QueueConstants.MESSAGE_ID_ELEMENT)) { - message.setMessageId(DeserializationHelper.readElementFromXMLReader(xmlr, - QueueConstants.MESSAGE_ID_ELEMENT)); - } - else if (name.equals(QueueConstants.INSERTION_TIME_ELEMENT)) { - message.setInsertionTime(Utility.parseRFC1123DateFromStringInGMT(DeserializationHelper - .readElementFromXMLReader(xmlr, QueueConstants.INSERTION_TIME_ELEMENT))); - } - else if (name.equals(QueueConstants.EXPIRATION_TIME_ELEMENT)) { - message.setExpirationTime(Utility.parseRFC1123DateFromStringInGMT(DeserializationHelper - .readElementFromXMLReader(xmlr, QueueConstants.EXPIRATION_TIME_ELEMENT))); - } - else if (name.equals(QueueConstants.POP_RECEIPT_ELEMENT)) { - message.setPopReceipt(DeserializationHelper.readElementFromXMLReader(xmlr, - QueueConstants.POP_RECEIPT_ELEMENT)); - } - else if (name.equals(QueueConstants.TIME_NEXT_VISIBLE_ELEMENT)) { - message.setNextVisibleTime(Utility.parseRFC1123DateFromStringInGMT(DeserializationHelper - .readElementFromXMLReader(xmlr, QueueConstants.TIME_NEXT_VISIBLE_ELEMENT))); - } - else if (name.equals(QueueConstants.DEQUEUE_COUNT_ELEMENT)) { - message.setDequeueCount(Integer.parseInt(DeserializationHelper.readElementFromXMLReader(xmlr, - QueueConstants.DEQUEUE_COUNT_ELEMENT))); - } - else if (name.equals(QueueConstants.MESSAGE_TEXT_ELEMENT)) { - message.messageContent = DeserializationHelper.readElementFromXMLReader(xmlr, - QueueConstants.MESSAGE_TEXT_ELEMENT); - } - - } - else if (eventType == XMLStreamConstants.END_ELEMENT && name.equals(QueueConstants.QUEUE_MESSAGE_ELEMENT)) { - break; - } - } - - xmlr.require(XMLStreamConstants.END_ELEMENT, null, QueueConstants.QUEUE_MESSAGE_ELEMENT); - return message; - } -} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/package.html b/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/package.html deleted file mode 100644 index 72c5aac9b9f36..0000000000000 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/queue/package.html +++ /dev/null @@ -1,5 +0,0 @@ - - -This package contains the integrated queue service client classes and implementation. - - diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/CloudTableClient.java b/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/CloudTableClient.java deleted file mode 100644 index 2525644fcbb0f..0000000000000 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/CloudTableClient.java +++ /dev/null @@ -1,1235 +0,0 @@ -/** - * 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.windowsazure.storage.table; - -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; - -import com.microsoft.windowsazure.storage.DoesServiceRequest; -import com.microsoft.windowsazure.storage.OperationContext; -import com.microsoft.windowsazure.storage.ResultContinuation; -import com.microsoft.windowsazure.storage.ResultContinuationType; -import com.microsoft.windowsazure.storage.ResultSegment; -import com.microsoft.windowsazure.storage.ServiceClient; -import com.microsoft.windowsazure.storage.ServiceProperties; -import com.microsoft.windowsazure.storage.ServiceStats; -import com.microsoft.windowsazure.storage.StorageCredentials; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.StorageUri; -import com.microsoft.windowsazure.storage.core.ExecutionEngine; -import com.microsoft.windowsazure.storage.core.LazySegmentedIterable; -import com.microsoft.windowsazure.storage.core.SR; -import com.microsoft.windowsazure.storage.core.SegmentedStorageRequest; -import com.microsoft.windowsazure.storage.core.StorageRequest; -import com.microsoft.windowsazure.storage.core.Utility; - -/** - * Provides a service client for accessing the Windows Azure Table service. - *

- * The {@link CloudTableClient} class encapsulates the base URI for the Table service endpoint and the credentials for - * accessing the storage account, and provides methods to create, delete, list, and query tables, as well as methods to - * execute operations and queries on table entities. These methods invoke Storage Service REST API operations to make - * the requests and obtain the results that are returned. - *

- * A Table service endpoint is the base URI for Table service resources, including the DNS name of the storage account: - *
- *     http://myaccount.table.core.windows.net
- * For more information, see the MSDN topic Addressing Table Service Resources. - *

- * The credentials can be a combination of the storage account name and a key, or a shared access signature. For more - * information, see the MSDN topic Authenticating Access to Your Storage - * Account. - * - */ -public final class CloudTableClient extends ServiceClient { - /** - * The {@link TablePayloadFormat} that is used for any table accessed with this CloudTableClient - * object. - * - * Default is Json. - */ - private TablePayloadFormat payloadFormat = TablePayloadFormat.Json; - - /** - * Reserved for internal use. An {@link EntityResolver} that projects table entity data as a String - * containing the table name. - */ - private final EntityResolver tableNameResolver = new EntityResolver() { - @Override - public String resolve(String partitionKey, String rowKey, Date timeStamp, - HashMap properties, String etag) { - return properties.get(TableConstants.TABLE_NAME).getValueAsString(); - } - }; - - /** - * Initializes an instance of the {@link CloudTableClient} class using a Table service endpoint. - *

- * A {@link CloudTableClient} initialized with this constructor must have storage account credentials added before - * it can be used to access the Windows Azure storage service. - * - * @param baseUri - * A java.net.URI that represents the Table service endpoint used to initialize the - * client. - */ - public CloudTableClient(final URI baseUri) { - this(new StorageUri(baseUri)); - } - - /** - * Initializes an instance of the {@link CloudTableClient} class using a Table service endpoint. - *

- * A {@link CloudTableClient} initialized with this constructor must have storage account credentials added before - * it can be used to access the Windows Azure storage service. - * - * @param baseUri - * A StorageUri that represents the Table service endpoint used to initialize the - * client. - */ - public CloudTableClient(final StorageUri baseUri) { - this(baseUri, null); - this.setTimeoutInMs(TableConstants.TABLE_DEFAULT_TIMEOUT_IN_MS); - } - - /** - * Initializes an instance of the {@link CloudTableClient} class using a Table service endpoint and - * storage account credentials. - * - * @param baseUri - * A java.net.URI object that represents the Table service endpoint used to initialize the - * client. - * @param credentials - * A {@link StorageCredentials} object that represents the storage account credentials for access. - */ - public CloudTableClient(final URI baseUri, StorageCredentials credentials) { - this(new StorageUri(baseUri), credentials); - } - - /** - * Initializes an instance of the {@link CloudTableClient} class using a Table service endpoint and - * storage account credentials. - * - * @param baseUri - * A {@link StorageUri} object that represents the Table service endpoint used to initialize the - * client. - * @param credentials - * A {@link StorageCredentials} object that represents the storage account credentials for access. - */ - public CloudTableClient(final StorageUri baseUri, StorageCredentials credentials) { - super(baseUri, credentials); - this.setTimeoutInMs(TableConstants.TABLE_DEFAULT_TIMEOUT_IN_MS); - } - - /** - * Gets a {@link CloudTable} object with the specified name. - * - * @param tableName - * The name of the table, which must adhere to table naming rules. The table name - * should not include any path separator characters (/). - * Table names are case insensitive, must be unique within an account and must be between 3-63 characters - * long. Table names must start with an cannot begin with a numeric character and may only contain - * alphanumeric characters. Some table names are reserved, including "table". - * @return A reference to a {@link CloudTable} object. - * @throws URISyntaxException - * If the resource URI constructed based on the tableName is invalid. - * @throws StorageException - * If a storage service error occurred. - * @see Understanding the Table Service - * Data Model - */ - public CloudTable getTableReference(final String tableName) throws URISyntaxException, StorageException { - Utility.assertNotNullOrEmpty("tableName", tableName); - return new CloudTable(tableName, this); - } - - /** - * Executes the specified batch operation on a table as an atomic operation. A batch operation may contain up to 100 - * individual table operations, with the requirement that each operation entity must have same partition key. Only - * one retrieve operation is allowed per batch. Note that the total payload of a batch operation is limited to 4MB. - *

- * This method invokes an Entity Group - * Transaction on the REST API to execute the specified batch operation on the table as an atomic unit, using - * the Table service endpoint and storage account credentials of this instance. - * - * @deprecated As of release 0.6.0, replaced by {@link CloudTable#execute(TableBatchOperation batch)} - * - * @param tableName - * A String containing the name of the table to execute the operations on. - * @param batch - * The {@link TableBatchOperation} object representing the operations to execute on the table. - * - * @return - * A java.util.ArrayList of {@link TableResult} that contains the results, in order, of - * each {@link TableOperation} in the {@link TableBatchOperation} on the named table. - * - * @throws StorageException - * if an error occurs accessing the storage service, or the operation fails. - */ - @DoesServiceRequest - @Deprecated - public ArrayList execute(final String tableName, final TableBatchOperation batch) - throws StorageException { - return this.execute(tableName, batch, null /* options */, null /* opContext */); - } - - /** - * Executes the specified batch operation on a table as an atomic operation, using the specified - * {@link TableRequestOptions} and {@link OperationContext}. A batch operation may contain up to 100 individual - * table operations, with the requirement that each operation entity must have same partition key. Only one retrieve - * operation is allowed per batch. Note that the total payload of a batch operation is limited to 4MB. - *

- * This method invokes an Entity Group - * Transaction on the REST API to execute the specified batch operation on the table as an atomic unit, using - * the Table service endpoint and storage account credentials of this instance. - * - * Use the {@link TableRequestOptions} to override execution options such as the timeout or retry policy for the - * operation. - * - * @deprecated As of release 0.6.0, replaced by - * {@link CloudTable#execute(TableBatchOperation batch, TableRequestOptions options, OperationContext opContext)} - * - * @param tableName - * A String containing the name of the table to execute the operations on. - * @param batch - * The {@link TableBatchOperation} object representing the operations to execute on the table. - * @param options - * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout - * settings for the operation. Specify null to use the request options specified on the - * {@link CloudTableClient}. - * @param opContext - * An {@link OperationContext} object for tracking the current operation. Specify null to - * safely ignore operation context. - * - * @return - * A java.util.ArrayList of {@link TableResult} that contains the results, in order, of - * each {@link TableOperation} in the {@link TableBatchOperation} on the named table. - * - * @throws StorageException - * if an error occurs accessing the storage service, or the operation fails. - */ - @Deprecated - @DoesServiceRequest - public ArrayList execute(final String tableName, final TableBatchOperation batch, - TableRequestOptions options, OperationContext opContext) throws StorageException { - Utility.assertNotNull("batch", batch); - if (opContext == null) { - opContext = new OperationContext(); - } - - opContext.initialize(); - options = TableRequestOptions.applyDefaults(options, this); - return batch.execute(this, tableName, options, opContext); - } - - /** - * Executes the operation on a table. - *

- * This method will invoke the Table - * Service REST API to execute the specified operation on the table, using the Table service endpoint and - * storage account credentials of this instance. - * - * @deprecated As of release 0.6.0, replaced by {@link CloudTable#execute(TableOperation operation)} - * - * @param tableName - * A String containing the name of the table to execute the operation on. - * @param operation - * The {@link TableOperation} object representing the operation to execute on the table. - * - * @return - * A {@link TableResult} containing the result of executing the {@link TableOperation} on the table. - * - * @throws StorageException - * if an error occurs accessing the storage service, or the operation fails. - */ - @Deprecated - @DoesServiceRequest - public TableResult execute(final String tableName, final TableOperation operation) throws StorageException { - return this.execute(tableName, operation, null /* options */, null /* opContext */); - } - - /** - * Executes the operation on a table, using the specified {@link TableRequestOptions} and {@link OperationContext}. - *

- * This method will invoke the Table - * Service REST API to execute the specified operation on the table, using the Table service endpoint and - * storage account credentials of this instance. - * - * Use the {@link TableRequestOptions} to override execution options such as the timeout or retry policy for the - * operation. - * - * @deprecated As of release 0.6.0, replaced by - * {@link CloudTable#execute(TableOperation operation, TableRequestOptions options, OperationContext opContext)} - * - * @param tableName - * A String containing the name of the table to execute the operation on. - * @param operation - * The {@link TableOperation} object representing the operation to execute on the table. - * @param options - * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout - * settings for the operation. Specify null to use the request options specified on the - * {@link CloudTableClient}. - * @param opContext - * An {@link OperationContext} object for tracking the current operation. Specify null to - * safely ignore operation context. - * - * @return - * A {@link TableResult} containing the result of executing the {@link TableOperation} on the table. - * - * @throws StorageException - * if an error occurs accessing the storage service, or the operation fails. - */ - @Deprecated - @DoesServiceRequest - public TableResult execute(final String tableName, final TableOperation operation, - final TableRequestOptions options, final OperationContext opContext) throws StorageException { - Utility.assertNotNull("operation", operation); - return operation.execute(this, tableName, options, opContext); - } - - /** - * Executes a query, applying the specified {@link EntityResolver} to the result. - *

- * This method will invoke a Query - * Entities operation on the Table - * Service REST API to query the table, using the Table service endpoint and storage account credentials of this - * instance. - * - * @deprecated As of release 0.6.0, replaced by {@link CloudTable#execute(TableQuery, EntityResolver)} - * - * @param query - * A {@link TableQuery} instance specifying the table to query and the query parameters to use. - * @param resolver - * An {@link EntityResolver} instance which creates a projection of the table query result entities into - * the specified type R. - * - * @return - * A collection implementing the Iterable interface containing the projection into type - * R of the results of executing the query. - * @throws StorageException - */ - @Deprecated - @DoesServiceRequest - public Iterable execute(final TableQuery query, final EntityResolver resolver) throws StorageException { - return this.execute(query, resolver, null /* options */, null /* opContext */); - } - - /** - * Executes a query, applying the specified {@link EntityResolver} to the result, using the - * specified {@link TableRequestOptions} and {@link OperationContext}. - *

- * This method will invoke a Query - * Entities operation on the Table - * Service REST API to query the table, using the Table service endpoint and storage account credentials of this - * instance. - * - * Use the {@link TableRequestOptions} to override execution options such as the timeout or retry policy for the - * operation. - * - * @deprecated As of release 0.6.0, replaced by - * {@link CloudTable#execute(TableQuery, EntityResolver, TableRequestOptions, OperationContext)} - * - * @param query - * A {@link TableQuery} instance specifying the table to query and the query parameters to use. - * @param resolver - * An {@link EntityResolver} instance which creates a projection of the table query result entities into - * the specified type R. - * @param options - * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout - * settings for the operation. Specify null to use the request options specified on the - * {@link CloudTableClient}. - * @param opContext - * An {@link OperationContext} object for tracking the current operation. Specify null to - * safely ignore operation context. - * - * @return - * A collection implementing the Iterable interface containing the projection into type - * R of the results of executing the query. - * @throws StorageException - */ - @Deprecated - @DoesServiceRequest - @SuppressWarnings("unchecked") - public Iterable execute(final TableQuery query, final EntityResolver resolver, - final TableRequestOptions options, final OperationContext opContext) throws StorageException { - Utility.assertNotNull("query", query); - Utility.assertNotNull(SR.QUERY_REQUIRES_VALID_CLASSTYPE_OR_RESOLVER, resolver); - return (Iterable) this.generateIteratorForQuery(query, resolver, options, opContext); - } - - /** - * Executes a query. - *

- * This method will invoke a Query - * Entities operation on the Table - * Service REST API to query the table, using the Table service endpoint and storage account credentials of this - * instance. - * - * @deprecated As of release 0.6.0, replaced by {@link CloudTable#execute(TableQuery)} - * - * @param query - * A {@link TableQuery} instance specifying the table to query and the query parameters to use, - * specialized for a type T implementing {@link TableEntity}. - * - * @return - * A collection implementing the Iterable interface specialized for type T of the results of - * executing the query. - * @throws StorageException - */ - @Deprecated - @DoesServiceRequest - public Iterable execute(final TableQuery query) throws StorageException { - return this.execute(query, null /* options */, null /* opContext */); - } - - /** - * Executes a query, using the specified {@link TableRequestOptions} and {@link OperationContext}. - *

- * This method will invoke a Query - * Entities operation on the Table - * Service REST API to query the table, using the Table service endpoint and storage account credentials of this - * instance. - * - * Use the {@link TableRequestOptions} to override execution options such as the timeout or retry policy for the - * operation. - * - * @deprecated As of release 0.6.0, replaced by {@link CloudTable#execute(TableQuery, TableRequestOptions)} - * - * @param query - * A {@link TableQuery} instance specifying the table to query and the query parameters to use, - * specialized for a type T implementing {@link TableEntity}. - * @param options - * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout - * settings for the operation. Specify null to use the request options specified on the - * {@link CloudTableClient}. - * @param opContext - * An {@link OperationContext} object for tracking the current operation. Specify null to - * safely ignore operation context. - * - * @return - * A collection implementing the Iterable interface specialized for type T of the results of - * executing the query. - * @throws StorageException - */ - @Deprecated - @SuppressWarnings("unchecked") - @DoesServiceRequest - public Iterable execute(final TableQuery query, final TableRequestOptions options, - final OperationContext opContext) throws StorageException { - Utility.assertNotNull("query", query); - return (Iterable) this.generateIteratorForQuery(query, null, options, opContext); - } - - /** - * Executes a query in segmented mode with the specified {@link ResultContinuation} continuation token, - * applying the {@link EntityResolver} to the result. - * Executing a query with executeSegmented allows the query to be resumed after returning partial - * results, using information returned by the server in the {@link ResultSegment} object. - *

- * This method will invoke a Query - * Entities operation on the Table - * Service REST API to query the table, using the Table service endpoint and storage account credentials of this - * instance. - * - * @deprecated As of release 0.6.0, replaced by - * {@link CloudTable#executeSegmented(TableQuery, EntityResolver, ResultContinuation)} - * - * @param query - * A {@link TableQuery} instance specifying the table to query and the query parameters to use. - * @param resolver - * An {@link EntityResolver} instance which creates a projection of the table query result entities into - * the specified type R. - * @param continuationToken - * A {@link ResultContinuation} object representing a continuation token from the server when the - * operation returns a partial result. Specify null on the initial call. Call the - * {@link ResultSegment#getContinuationToken()} method on the result to obtain the - * {@link ResultContinuation} object to use in the next call to resume the query. - * - * @return - * A {@link ResultSegment} containing the projection into type R of the results of executing - * the query. - * - * @throws IOException - * if an IO error occurred during the operation. - * @throws URISyntaxException - * if the URI generated for the query is invalid. - * @throws StorageException - * if a storage service error occurred during the operation. - */ - @Deprecated - @DoesServiceRequest - public ResultSegment executeSegmented(final TableQuery query, final EntityResolver resolver, - final ResultContinuation continuationToken) throws IOException, URISyntaxException, StorageException { - return this.executeSegmented(query, resolver, continuationToken, null /* options */, null /* opContext */); - } - - /** - * Executes a query in segmented mode with the specified {@link ResultContinuation} continuation token, - * using the specified {@link TableRequestOptions} and {@link OperationContext}, applying the {@link EntityResolver} - * to the result. - * Executing a query with executeSegmented allows the query to be resumed after returning partial - * results, using information returned by the server in the {@link ResultSegment} object. - *

- * This method will invoke a Query - * Entities operation on the Table - * Service REST API to query the table, using the Table service endpoint and storage account credentials of this - * instance. - * - * Use the {@link TableRequestOptions} to override execution options such as the timeout or retry policy for the - * operation. - * - * @deprecated As of release 0.6.0, replaced by - * {@link CloudTable#executeSegmented(TableQuery, EntityResolver, ResultContinuation, TableRequestOptions, OperationContext) - * - * @param query - * A {@link TableQuery} instance specifying the table to query and the query parameters to use. - * @param resolver - * An {@link EntityResolver} instance which creates a projection of the table query result entities into - * the specified type R. - * @param continuationToken - * A {@link ResultContinuation} object representing a continuation token from the server when the - * operation returns a partial result. Specify null on the initial call. Call the - * {@link ResultSegment#getContinuationToken()} method on the result to obtain the - * {@link ResultContinuation} object to use in the next call to resume the query. - * @param options - * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout - * settings for the operation. Specify null to use the request options specified on the - * {@link CloudTableClient}. - * @param opContext - * An {@link OperationContext} object for tracking the current operation. Specify null to - * safely ignore operation context. - * - * @return - * A {@link ResultSegment} containing the projection into type R of the results of executing - * the query. - * - * @throws IOException - * if an IO error occurred during the operation. - * @throws URISyntaxException - * if the URI generated for the query is invalid. - * @throws StorageException - * if a storage service error occurred during the operation. - */ - @Deprecated - @DoesServiceRequest - @SuppressWarnings("unchecked") - public ResultSegment executeSegmented(final TableQuery query, final EntityResolver resolver, - final ResultContinuation continuationToken, final TableRequestOptions options, - final OperationContext opContext) throws IOException, URISyntaxException, StorageException { - Utility.assertNotNull(SR.QUERY_REQUIRES_VALID_CLASSTYPE_OR_RESOLVER, resolver); - return (ResultSegment) this - .executeQuerySegmentedImpl(query, resolver, continuationToken, options, opContext); - } - - /** - * Executes a query in segmented mode with a {@link ResultContinuation} continuation token. - * Executing a query with executeSegmented allows the query to be resumed after returning partial - * results, using information returned by the server in the {@link ResultSegment} object. - *

- * This method will invoke a Query - * Entities operation on the Table - * Service REST API to query the table, using the Table service endpoint and storage account credentials of this - * instance. - * - * @deprecated As of release 0.6.0, replaced by {@link CloudTable#executeSegmented(TableQuery, ResultContinuation) - * - * @param query - * A {@link TableQuery} instance specifying the table to query and the query parameters to use, - * specialized for a type T implementing {@link TableEntity}. - * @param continuationToken - * A {@link ResultContinuation} object representing a continuation token from the server when the - * operation returns a partial result. Specify null on the initial call. Call the - * {@link ResultSegment#getContinuationToken()} method on the result to obtain the - * {@link ResultContinuation} object to use in the next call to resume the query. - * - * @return - * A {@link ResultSegment} specialized for type T of the results of executing the query. - * - * @throws IOException - * if an IO error occurred during the operation. - * @throws URISyntaxException - * if the URI generated for the query is invalid. - * @throws StorageException - * if a storage service error occurred during the operation. - */ - @Deprecated - @DoesServiceRequest - public ResultSegment executeSegmented(final TableQuery query, - final ResultContinuation continuationToken) throws IOException, URISyntaxException, StorageException { - return this.executeSegmented(query, continuationToken, null /* options */, null /* opContext */); - } - - /** - * Executes a query in segmented mode with a {@link ResultContinuation} continuation token, - * using the specified {@link TableRequestOptions} and {@link OperationContext}. - * Executing a query with executeSegmented allows the query to be resumed after returning partial - * results, using information returned by the server in the {@link ResultSegment} object. - *

- * This method will invoke a Query - * Entities operation on the Table - * Service REST API to query the table, using the Table service endpoint and storage account credentials of this - * instance. - * - * Use the {@link TableRequestOptions} to override execution options such as the timeout or retry policy for the - * operation. - * - * @deprecated As of release 0.6.0, replaced by - * {@link CloudTable#executeSegmented(TableQuery, ResultContinuation, TableRequestOptions, OperationContext) - * - * @param query - * A {@link TableQuery} instance specifying the table to query and the query parameters to use, - * specialized for a type T implementing {@link TableEntity}. - * @param continuationToken - * A {@link ResultContinuation} object representing a continuation token from the server when the - * operation returns a partial result. Specify null on the initial call. Call the - * {@link ResultSegment#getContinuationToken()} method on the result to obtain the - * {@link ResultContinuation} object to use in the next call to resume the query. - * @param options - * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout - * settings for the operation. Specify null to use the request options specified on the - * {@link CloudTableClient}. - * @param opContext - * An {@link OperationContext} object for tracking the current operation. Specify null to - * safely ignore operation context. - * - * @return - * A {@link ResultSegment} specialized for type T of the results of executing the query. - * - * @throws IOException - * if an IO error occurred during the operation. - * @throws URISyntaxException - * if the URI generated for the query is invalid. - * @throws StorageException - * if a storage service error occurred during the operation. - */ - @Deprecated - @DoesServiceRequest - @SuppressWarnings("unchecked") - public ResultSegment executeSegmented(final TableQuery query, - final ResultContinuation continuationToken, final TableRequestOptions options, - final OperationContext opContext) throws IOException, URISyntaxException, StorageException { - Utility.assertNotNull("query", query); - return (ResultSegment) this.executeQuerySegmentedImpl(query, null, continuationToken, options, opContext); - } - - /** - * Lists the table names in the storage account. - *

- * This method invokes the Query - * Tables REST API to list the table names, using the Table service endpoint and storage account credentials of - * this instance. - * - * @return - * An Iterable collection of the table names in the storage account retrieved lazily. - * @throws StorageException - */ - @DoesServiceRequest - public Iterable listTables() throws StorageException { - return this.listTables(null); - } - - /** - * Lists the table names in the storage account that match the specified prefix. - *

- * This method invokes the Query - * Tables REST API to list the table names that match the prefix, using the Table service endpoint and storage - * account credentials of this instance. - * - * @param prefix - * A String containing the prefix to match on table names to return. - * - * @return - * An Iterable collection of the table names in the storage account retrieved lazily that match - * the specified - * prefix. - * @throws StorageException - */ - @DoesServiceRequest - public Iterable listTables(final String prefix) throws StorageException { - return this.listTables(prefix, null /* options */, null /* opContext */); - } - - /** - * Lists the table names in the storage account that match the specified prefix, using the specified - * {@link TableRequestOptions} and {@link OperationContext}. - *

- * This method invokes the Query - * Tables REST API to list the table names that match the prefix, using the Table service endpoint and storage - * account credentials of this instance. - * - * Use the {@link TableRequestOptions} to override execution options such as the timeout or retry policy for the - * operation. - * - * @param prefix - * A String containing the prefix to match on table names to return. - * @param options - * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout - * settings for the operation. Specify null to use the request options specified on the - * {@link CloudTableClient}. - * @param opContext - * An {@link OperationContext} object for tracking the current operation. Specify null to - * safely ignore operation context. - * - * @return - * An Iterable collection of the table names in the storage account retrieved lazily that match - * the specified - * prefix. - * @throws StorageException - */ - @DoesServiceRequest - public Iterable listTables(final String prefix, final TableRequestOptions options, - final OperationContext opContext) throws StorageException { - return this.execute(this.generateListTablesQuery(prefix), this.tableNameResolver, options, opContext); - } - - /** - * Lists the table names in the storage account in segmented mode. This method allows listing of tables to be - * resumed after returning a partial set of results, using information returned by the server in the - * {@link ResultSegment} object. - *

- * This method invokes the Query - * Tables REST API to list the table names, using the Table service endpoint and storage account credentials of - * this instance. - * - * @return - * A {@link ResultSegment} of String objects containing table names in the storage account. - * - * @throws IOException - * if an IO error occurred during the operation. - * @throws URISyntaxException - * if the URI generated for the operation is invalid. - * @throws StorageException - * if a storage service error occurred during the operation. - */ - @DoesServiceRequest - public ResultSegment listTablesSegmented() throws IOException, URISyntaxException, StorageException { - return this.listTablesSegmented(null); - } - - /** - * Lists the table names in the storage account that match the specified prefix in segmented mode. This method - * allows listing of tables to be resumed after returning a partial set of results, using information returned by - * the server in the {@link ResultSegment} object. - *

- * This method invokes the Query - * Tables REST API to list the table names that match the prefix, using the Table service endpoint and storage - * account credentials of this instance. - * - * @param prefix - * A String containing the prefix to match on table names to return. - * - * @return - * A {@link ResultSegment} of String objects containing table names matching the prefix in the - * storage account. - * - * @throws IOException - * if an IO error occurred during the operation. - * @throws URISyntaxException - * if the URI generated for the operation is invalid. - * @throws StorageException - * if a storage service error occurred during the operation. - */ - @DoesServiceRequest - public ResultSegment listTablesSegmented(final String prefix) throws IOException, URISyntaxException, - StorageException { - return this.listTablesSegmented(prefix, null /* maxResults */, null /* continuationToken */, - null /* options */, null /* opContext */); - } - - /** - * Lists up to the specified maximum of the table names in the storage account that match the specified prefix in a - * resumable mode with the specified {@link ResultContinuation} continuation token, using the specified - * {@link TableRequestOptions} and {@link OperationContext}. This method allows listing of tables to be resumed - * after returning a page of results, using information returned by the server in the {@link ResultSegment} object. - *

- * This method invokes the Query - * Tables REST API to list the table names that match the prefix, using the Table service endpoint and storage - * account credentials of this instance. - * - * Use the {@link TableRequestOptions} to override execution options such as the timeout or retry policy for the - * operation. - * - * @param prefix - * A String containing the prefix to match on table names to return. - * @param maxResults - * The maximum number of table names to return in the {@link ResultSegment}. If this parameter is null, - * the query will list up to the maximum 1,000 results. - * @param continuationToken - * A {@link ResultContinuation} object representing a continuation token from the server when the - * operation returns a partial result. Specify null on the initial call. Call the - * {@link ResultSegment#getContinuationToken()} method on the result to obtain the - * {@link ResultContinuation} object to use in the next call to resume the query. - * @param options - * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout - * settings for the operation. Specify null to use the request options specified on the - * {@link CloudTableClient}. - * @param opContext - * An {@link OperationContext} object for tracking the current operation. Specify null to - * safely ignore operation context. - * - * @return - * A {@link ResultSegment} of String objects containing table names in the storage account. - * - * @throws IOException - * if an IO error occurred during the operation. - * @throws URISyntaxException - * if the URI generated for the operation is invalid. - * @throws StorageException - * if a storage service error occurred during the operation. - */ - @DoesServiceRequest - public ResultSegment listTablesSegmented(final String prefix, final Integer maxResults, - final ResultContinuation continuationToken, final TableRequestOptions options, - final OperationContext opContext) throws IOException, URISyntaxException, StorageException { - return this.executeSegmented(this.generateListTablesQuery(prefix).take(maxResults), this.tableNameResolver, - continuationToken, options, opContext); - } - - /** - * Reserved for internal use. Generates a query to list table names with the given prefix. - * - * @param prefix - * A String containing the prefix to match on table names to return. - * @return - * A {@link TableQuery} instance for listing table names with the specified prefix. - */ - @SuppressWarnings("deprecation") - private TableQuery generateListTablesQuery(final String prefix) { - TableQuery listQuery = TableQuery. from( - TableConstants.TABLES_SERVICE_TABLES_NAME, TableServiceEntity.class); - - if (!Utility.isNullOrEmpty(prefix)) { - // Append Max char to end '{' is 1 + 'z' in AsciiTable > uppperBound = prefix + '{' - final String prefixFilter = String.format("(%s ge '%s') and (%s lt '%s{')", TableConstants.TABLE_NAME, - prefix, TableConstants.TABLE_NAME, prefix); - - listQuery = listQuery.where(prefixFilter); - } - - return listQuery; - } - - /** - * Reserved for internal use. Executes a segmented query operation using the specified retry and timeout policies. - * - * @param queryToExecute - * The {@link TableQuery} to execute. - * @param resolver - * An {@link EntityResolver} instance which creates a projection of the table query result entities into - * the specified type R. Pass null to return the results as the table entity - * type. - * @param continuationToken - * The {@link ResultContinuation} to pass with the operation to resume a query, if any. Pass - * null for an initial query. - * @param options - * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout - * settings for the operation. Specify null to use the request options specified on the - * {@link CloudTableClient}. - * @param opContext - * An {@link OperationContext} object for tracking the current operation. Specify null to - * safely ignore operation context. - * @return - * A {@link ResultSegment} containing a collection of the query results specialized for the - * {@link TableEntity} or {@link EntityResolver} type returned by the query. - * @throws StorageException - * if a Storage service error occurs. - */ - protected ResultSegment executeQuerySegmentedImpl(final TableQuery queryToExecute, - final EntityResolver resolver, final ResultContinuation continuationToken, TableRequestOptions options, - OperationContext opContext) throws StorageException { - if (opContext == null) { - opContext = new OperationContext(); - } - - opContext.initialize(); - options = TableRequestOptions.applyDefaults(options, this); - - Utility.assertContinuationType(continuationToken, ResultContinuationType.TABLE); - - SegmentedStorageRequest segmentedRequest = new SegmentedStorageRequest(); - segmentedRequest.setToken(continuationToken); - - return ExecutionEngine.executeWithRetry(this, queryToExecute, - this.executeQuerySegmentedWithResolverCoreImpl(queryToExecute, resolver, options, segmentedRequest), - options.getRetryPolicyFactory(), opContext); - } - - private StorageRequest, ResultSegment> executeQuerySegmentedCoreImpl( - final TableQuery queryToExecute, final EntityResolver resolver, final TableRequestOptions options, - final SegmentedStorageRequest segmentedRequest) throws StorageException { - - if (resolver == null) { - Utility.assertNotNull(SR.QUERY_REQUIRES_VALID_CLASSTYPE_OR_RESOLVER, queryToExecute.getClazzType()); - } - - final StorageRequest, ResultSegment> getRequest = new StorageRequest, ResultSegment>( - options, this.getStorageUri()) { - - @Override - public void setRequestLocationMode() { - this.setRequestLocationMode(Utility.getListingLocationMode(segmentedRequest.getToken())); - } - - @SuppressWarnings("deprecation") - @Override - public HttpURLConnection buildRequest(CloudTableClient client, TableQuery queryRef, - OperationContext context) throws Exception { - return TableRequest.query(client.getTransformedEndPoint(context).getUri(this.getCurrentLocation()), - queryToExecute.getSourceTableName(), null/* identity */, options.getTimeoutIntervalInMs(), - queryToExecute.generateQueryBuilder(), segmentedRequest.getToken(), options, context); - } - - @Override - public void signRequest(HttpURLConnection connection, CloudTableClient client, OperationContext context) - throws Exception { - StorageRequest.signTableRequest(connection, client, -1L, context); - } - - @Override - public ResultSegment preProcessResponse(TableQuery queryRef, CloudTableClient client, - OperationContext context) throws Exception { - if (this.getResult().getStatusCode() != HttpURLConnection.HTTP_OK) { - throw TableServiceException.generateTableServiceException(true, this.getResult(), null, this - .getConnection().getErrorStream(), options.getTablePayloadFormat()); - } - - return null; - } - - @SuppressWarnings("unchecked") - @Override - public ResultSegment postProcessResponse(HttpURLConnection connection, TableQuery queryRef, - CloudTableClient client, OperationContext context, ResultSegment storageObject) throws Exception { - ODataPayload clazzResponse = null; - - InputStream inStream = connection.getInputStream(); - - clazzResponse = (ODataPayload) TableDeserializer.parseQueryResponse(inStream, options, - queryToExecute.getClazzType(), null, context); - - final ResultContinuation nextToken = TableResponse.getTableContinuationFromResponse(connection); - if (nextToken != null) { - nextToken.setTargetLocation(this.getResult().getTargetLocation()); - } - - // Note, setting the token on the SegmentedStorageRequest is - // key, this is how the iterator will share the token across executions - segmentedRequest.setToken(nextToken); - - return new ResultSegment(clazzResponse.results, - queryToExecute.getTakeCount() == null ? clazzResponse.results.size() - : queryToExecute.getTakeCount(), nextToken); - } - }; - - return getRequest; - } - - private StorageRequest, ResultSegment> executeQuerySegmentedWithResolverCoreImpl( - final TableQuery queryToExecute, final EntityResolver resolver, final TableRequestOptions options, - final SegmentedStorageRequest segmentedRequest) throws StorageException { - - if (resolver == null) { - Utility.assertNotNull(SR.QUERY_REQUIRES_VALID_CLASSTYPE_OR_RESOLVER, queryToExecute.getClazzType()); - } - - final StorageRequest, ResultSegment> getRequest = new StorageRequest, ResultSegment>( - options, this.getStorageUri()) { - - @Override - public void setRequestLocationMode() { - this.setRequestLocationMode(Utility.getListingLocationMode(segmentedRequest.getToken())); - } - - @SuppressWarnings("deprecation") - @Override - public HttpURLConnection buildRequest(CloudTableClient client, TableQuery queryRef, - OperationContext context) throws Exception { - return TableRequest.query(client.getTransformedEndPoint(context).getUri(this.getCurrentLocation()), - queryToExecute.getSourceTableName(), null/* identity */, options.getTimeoutIntervalInMs(), - queryToExecute.generateQueryBuilder(), segmentedRequest.getToken(), options, context); - } - - @Override - public void signRequest(HttpURLConnection connection, CloudTableClient client, OperationContext context) - throws Exception { - StorageRequest.signTableRequest(connection, client, -1L, context); - } - - @Override - public ResultSegment preProcessResponse(TableQuery queryRef, CloudTableClient client, - OperationContext context) throws Exception { - if (this.getResult().getStatusCode() != HttpURLConnection.HTTP_OK) { - throw TableServiceException.generateTableServiceException(true, this.getResult(), null, this - .getConnection().getErrorStream(), options.getTablePayloadFormat()); - } - - return null; - } - - @SuppressWarnings("unchecked") - @Override - public ResultSegment postProcessResponse(HttpURLConnection connection, TableQuery queryRef, - CloudTableClient client, OperationContext context, ResultSegment storageObject) throws Exception { - ODataPayload resolvedResponse = null; - - InputStream inStream = connection.getInputStream(); - - resolvedResponse = (ODataPayload) TableDeserializer.parseQueryResponse(inStream, options, - queryToExecute.getClazzType(), resolver, context); - - final ResultContinuation nextToken = TableResponse.getTableContinuationFromResponse(connection); - if (nextToken != null) { - nextToken.setTargetLocation(this.getResult().getTargetLocation()); - } - - // Note, setting the token on the SegmentedStorageRequest is - // key, this is how the iterator will share the token across executions - segmentedRequest.setToken(nextToken); - - return new ResultSegment(resolvedResponse.results, - queryToExecute.getTakeCount() == null ? resolvedResponse.results.size() - : queryToExecute.getTakeCount(), nextToken); - - } - }; - - return getRequest; - } - - protected final StorageUri getTransformedEndPoint(final OperationContext opContext) throws URISyntaxException, - StorageException { - if (this.getCredentials().doCredentialsNeedTransformUri()) { - if (this.getEndpoint().isAbsolute()) { - return this.getCredentials().transformUri(this.getStorageUri(), opContext); - } - else { - final StorageException ex = Utility.generateNewUnexpectedStorageException(null); - ex.getExtendedErrorInformation().setErrorMessage(SR.TABLE_OBJECT_RELATIVE_URIS_NOT_SUPPORTED); - throw ex; - } - } - else { - return this.getStorageUri(); - } - } - - /** - * Reserved for internal use. Generates an iterator for a segmented query operation. - * - * @param queryRef - * The {@link TableQuery} to execute. - * @param resolver - * An {@link EntityResolver} instance which creates a projection of the table query result entities into - * the specified type R. Pass null to return the results as the table entity - * type. - * @param options - * A {@link TableRequestOptions} object that specifies execution options such as retry policy and timeout - * settings for the operation. Specify null to use the request options specified on the - * {@link CloudTableClient}. - * @param opContext - * An {@link OperationContext} object for tracking the current operation. Specify null to - * safely ignore operation context. - * @return - * An instance of Iterable specialized for the {@link TableEntity} or {@link EntityResolver} - * type returned by the query. - * @throws StorageException - */ - protected Iterable generateIteratorForQuery(final TableQuery queryRef, - final EntityResolver resolver, TableRequestOptions options, OperationContext opContext) - throws StorageException { - if (opContext == null) { - opContext = new OperationContext(); - } - - opContext.initialize(); - options = TableRequestOptions.applyDefaults(options, this); - - SegmentedStorageRequest segmentedRequest = new SegmentedStorageRequest(); - - if (resolver == null) { - return new LazySegmentedIterable, T>(this.executeQuerySegmentedCoreImpl( - queryRef, resolver, options, segmentedRequest), this, queryRef, options.getRetryPolicyFactory(), - opContext); - } - else { - return new LazySegmentedIterable, R>( - this.executeQuerySegmentedWithResolverCoreImpl(queryRef, resolver, options, segmentedRequest), - this, queryRef, options.getRetryPolicyFactory(), opContext); - } - } - - /** - * Queries the service to get the service statistics - * - * @return ServiceStats for the given storage service - * @throws StorageException - */ - @DoesServiceRequest - public ServiceStats getServiceStats() throws StorageException { - return this.getServiceStats(null /* options */, null /* opContext */); - } - - /** - * Queries the service to get the service statistics - * - * @param options - * A {@link TableRequestOptions} object that specifies any additional options for the request. Specifying - * null will use the default request options from the associated service client ( - * {@link CloudTableClient}). - * @param opContext - * An {@link OperationContext} object that 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. - * @return ServiceStats for the given storage service - * @throws StorageException - */ - @DoesServiceRequest - public ServiceStats getServiceStats(TableRequestOptions options, OperationContext opContext) - throws StorageException { - if (opContext == null) { - opContext = new OperationContext(); - } - - opContext.initialize(); - options = TableRequestOptions.applyDefaults(options, this); - - return ExecutionEngine.executeWithRetry(this, null, this.getServiceStatsImpl(options, true), - this.getRetryPolicyFactory(), opContext); - } - - /** - * Retrieves the current ServiceProperties for the given storage service. This includes Metrics and Logging - * Configurations. - * - * @return the ServiceProperties object representing the current configuration of the service. - * @throws StorageException - * If a storage service error occurred. - */ - @DoesServiceRequest - public final ServiceProperties downloadServiceProperties() throws StorageException { - return this.downloadServiceProperties(null /* options */, null /* opContext */); - } - - /** - * Retrieves the current ServiceProperties for the given storage service. This includes Metrics and Logging - * Configurations. - * - * @param options - * A {@link TableRequestOptions} object that specifies any additional options for the request. Specifying - * null will use the default request options from the associated service client ( - * {@link CloudTableClient}). - * @param opContext - * An {@link OperationContext} object that 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. - * @return the ServiceProperties object representing the current configuration of the service. - * @throws StorageException - * If a storage service error occurred. - */ - @DoesServiceRequest - public final ServiceProperties downloadServiceProperties(TableRequestOptions options, OperationContext opContext) - throws StorageException { - if (opContext == null) { - opContext = new OperationContext(); - } - - opContext.initialize(); - options = TableRequestOptions.applyDefaults(options, this); - - return ExecutionEngine.executeWithRetry(this, null, this.downloadServicePropertiesImpl(options, true), - options.getRetryPolicyFactory(), opContext); - } - - /** - * Uploads a new configuration to the storage service. This includes Metrics and Logging Configuration. - * - * @param properties - * The ServiceProperties to upload. - * @throws StorageException - * If a storage service error occurred. - */ - @DoesServiceRequest - public void uploadServiceProperties(final ServiceProperties properties) throws StorageException { - this.uploadServiceProperties(properties, null /* options */, null /* opContext */); - } - - /** - * Uploads a new configuration to the storage service. This includes Metrics and Logging Configuration. - * - * @param properties - * The ServiceProperties to upload. - * @param options - * A {@link TableRequestOptions} object that specifies any additional options for the request. Specifying - * null will use the default request options from the associated service client ( - * {@link CloudTableClient}). - * @param opContext - * An {@link OperationContext} object that 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 uploadServiceProperties(final ServiceProperties properties, TableRequestOptions options, - OperationContext opContext) throws StorageException { - if (!Utility.isNullOrEmpty(properties.getDefaultServiceVersion())) { - throw new IllegalArgumentException(SR.DEFAULT_SERVICE_VERSION_ONLY_SET_FOR_BLOB_SERVICE); - } - - if (opContext == null) { - opContext = new OperationContext(); - } - - opContext.initialize(); - options = TableRequestOptions.applyDefaults(options, this); - - Utility.assertNotNull("properties", properties); - - ExecutionEngine.executeWithRetry(this, null, - this.uploadServicePropertiesImpl(properties, options, opContext, true), - options.getRetryPolicyFactory(), opContext); - } - - /** - * Gets the {@link TablePayloadFormat} that is used for any table accessed with this CloudTableClient - * object. Default is {@link TablePayloadFormat#Json} - * - * @return - * The {@link TablePayloadFormat} used by this CloudTableClient - */ - public TablePayloadFormat getTablePayloadFormat() { - return this.payloadFormat; - } - - /** - * Sets the {@link TablePayloadFormat} that is used for any table accessed with this CloudTableClient - * object. - * - * @param payloadFormat - * The TablePayloadFormat to use. - */ - public void setTablePayloadFormat(TablePayloadFormat payloadFormat) { - this.payloadFormat = payloadFormat; - } -} diff --git a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/package.html b/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/package.html deleted file mode 100644 index 6a84c85156b23..0000000000000 --- a/microsoft-azure-storage/src/main/java/com/microsoft/windowsazure/storage/table/package.html +++ /dev/null @@ -1,5 +0,0 @@ - - -This package contains the integrated table service client classes and implementation. - - diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/TestHelper.java b/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/TestHelper.java deleted file mode 100644 index 0111d905fcd3b..0000000000000 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/TestHelper.java +++ /dev/null @@ -1,67 +0,0 @@ -/** - * 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.windowsazure.storage; - -import java.io.ByteArrayInputStream; -import java.io.IOException; - -import junit.framework.Assert; - -public class TestHelper { - - protected static void enableFiddler() { - System.setProperty("http.proxyHost", "localhost"); - System.setProperty("http.proxyPort", "8888"); - } - - public static void verifyServiceStats(ServiceStats stats) { - Assert.assertNotNull(stats); - if (stats.getGeoReplication().getLastSyncTime() != null) { - Assert.assertEquals(GeoReplicationStatus.LIVE, stats.getGeoReplication().getStatus()); - } - else { - Assert.assertTrue(stats.getGeoReplication().getStatus() == GeoReplicationStatus.BOOTSTRAP - || stats.getGeoReplication().getStatus() == GeoReplicationStatus.UNAVAILABLE); - } - } - - public static void assertStreamsAreEqual(ByteArrayInputStream src, ByteArrayInputStream dst) { - dst.reset(); - src.reset(); - Assert.assertEquals(src.available(), dst.available()); - - while (src.available() > 0) { - Assert.assertEquals(src.read(), dst.read()); - } - } - - public static void assertStreamsAreEqualAtIndex(ByteArrayInputStream src, ByteArrayInputStream dst, int srcIndex, - int dstIndex, int length, int bufferSize) throws IOException { - dst.reset(); - src.reset(); - - dst.skip(dstIndex); - src.skip(srcIndex); - byte[] origBuffer = new byte[bufferSize]; - byte[] retrBuffer = new byte[bufferSize]; - src.read(origBuffer); - dst.read(retrBuffer); - - for (int i = 0; i < length; i++) { - Assert.assertEquals(src.read(), dst.read()); - } - - } -} diff --git a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/queue/QueueTestBase.java b/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/queue/QueueTestBase.java deleted file mode 100644 index 314a6399c8ef6..0000000000000 --- a/microsoft-azure-storage/src/test/java/com/microsoft/windowsazure/storage/queue/QueueTestBase.java +++ /dev/null @@ -1,70 +0,0 @@ -/** - * 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.windowsazure.storage.queue; - -import java.net.URI; -import java.net.URISyntaxException; -import java.security.InvalidKeyException; -import java.util.UUID; - -import org.junit.AfterClass; -import org.junit.BeforeClass; - -import com.microsoft.windowsazure.storage.AuthenticationScheme; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.TestBase; - -/** - * Queue Test Base - */ -public class QueueTestBase extends TestBase { - - protected static CloudQueueClient qClient; - protected static String testSuiteQueueName = generateRandomQueueName(); - protected static CloudQueue queue; - - @BeforeClass - public static void setupQueueTestBase() throws URISyntaxException, StorageException, InvalidKeyException { - qClient = createCloudQueueClient(); - qClient.setAuthenticationScheme(AuthenticationScheme.SHAREDKEYFULL); - testSuiteQueueName = generateRandomQueueName(); - queue = qClient.getQueueReference(testSuiteQueueName); - queue.create(); - } - - @AfterClass - public static void teardown() throws StorageException, URISyntaxException { - CloudQueue queue = qClient.getQueueReference(testSuiteQueueName); - queue.delete(); - } - - public static String generateRandomQueueName() { - String queueName = "queue" + UUID.randomUUID().toString(); - return queueName.replace("-", ""); - } - - static String AppendQueueName(URI baseURI, String queueName) throws URISyntaxException { - if (baseURI == null) - return queueName; - - String baseAddress = baseURI.toString(); - if (baseAddress.endsWith("/")) { - return baseAddress + queueName; - } - else { - return baseAddress + "/" + queueName; - } - } -} diff --git a/microsoft-azure-storage/pom.xml b/pom.xml similarity index 90% rename from microsoft-azure-storage/pom.xml rename to pom.xml index 0d11b8259a04f..d9501674096a6 100644 --- a/microsoft-azure-storage/pom.xml +++ b/pom.xml @@ -17,12 +17,12 @@ 4.0.0 com.microsoft.windowsazure.storage microsoft-windowsazure-storage-sdk - 0.6.0 + 0.7.0 jar - Microsoft Windows Azure Storage Client SDK - SDK for Microsoft Windows Azure Storage Clients - https://github.com/WindowsAzure/azure-storage-java + Microsoft Azure Storage Client SDK + SDK for Microsoft Azure Storage Clients + https://github.com/Azure/azure-storage-java @@ -33,8 +33,8 @@ - scm:git:https://github.com/WindowsAzure/azure-storage-java - scm:git:git://github.com/WindowsAzure/azure-storage-java.git + scm:git:https://github.com/Azure/azure-storage-java + scm:git:git://github.com/Azure/azure-storage-java.git @@ -69,6 +69,13 @@ + microsoft-azure-storage/src + microsoft-azure-storage-test/src + + + microsoft-azure-storage-test/res + + org.apache.maven.plugins @@ -190,6 +197,8 @@ maven-surefire-plugin 2.13 + classes + 2 **/Test*.java **/*Test.java diff --git a/windowsazure-storage-samples/src/com/microsoft/windowsazure/storage/table/gettingtstarted/TableBasics.java b/windowsazure-storage-samples/src/com/microsoft/windowsazure/storage/table/gettingtstarted/TableBasics.java deleted file mode 100644 index 423336b02f83b..0000000000000 --- a/windowsazure-storage-samples/src/com/microsoft/windowsazure/storage/table/gettingtstarted/TableBasics.java +++ /dev/null @@ -1,236 +0,0 @@ -/** - * 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.windowsazure.storage.table.gettingtstarted; - -import java.net.URISyntaxException; -import java.security.InvalidKeyException; -import com.microsoft.windowsazure.storage.CloudStorageAccount; -import com.microsoft.windowsazure.storage.StorageException; -import com.microsoft.windowsazure.storage.table.CloudTable; -import com.microsoft.windowsazure.storage.table.CloudTableClient; -import com.microsoft.windowsazure.storage.table.TableBatchOperation; -import com.microsoft.windowsazure.storage.table.TableConstants; -import com.microsoft.windowsazure.storage.table.TableOperation; -import com.microsoft.windowsazure.storage.table.TableQuery; -import com.microsoft.windowsazure.storage.table.TableQuery.QueryComparisons; -import com.microsoft.windowsazure.storage.util.Utility; - -/** - * This sample illustrates basic usage of the various Table Primitives provided - * in the Storage Client Library including TableOperation, TableBatchOperation, - * and TableQuery. - */ -public class TableBasics { - protected static CloudTableClient tableClient; - protected static String tableName = "tablebasics"; - - /** - * Executes the sample. - * - * @param args - * No input args are expected from users. - * @throws URISyntaxException - * @throws InvalidKeyException - */ - public static void main(String[] args) throws InvalidKeyException, URISyntaxException { - Utility.printSampleStartInfo("TableBasics"); - - // Setup the cloud storage account. - CloudStorageAccount account = CloudStorageAccount.parse(Utility.storageConnectionString); - - // Create a table service client. - tableClient = account.createCloudTableClient(); - - try { - // Retrieve a reference to a table. - CloudTable table = tableClient.getTableReference(tableName); - - // Create the table if it doesn't already exist. - table.createIfNotExists(); - - // Illustrates how to list the tables. - BasicListing(); - - // Illustrates how to form and execute a single insert operation. - BasicInsertEntity(); - - // Illustrates how to form and execute a batch operation. - BasicBatch(); - - // Illustrates how to form and execute a query operation. - BasicQuery(); - - // Illustrates how to form and execute an upsert operation. - BasicUpsert(); - - // Illustrates how to form and execute an entity delete operation. - BasicDeleteEntity(); - - // Delete the table. - table.deleteIfExists(); - - } catch (Throwable t) { - Utility.printException(t); - } - - Utility.printSampleCompleteInfo("TableBasics"); - } - - /** - * Illustrates how to form and execute a single insert operation. - * @throws StorageException - */ - public static void BasicInsertEntity() throws StorageException { - // Note: the limitations on an insert operation are - // - the serialized payload must be 1 MB or less - // - up to 252 properties in addition to the partition key, row key and timestamp. 255 properties in total - // - the serialized payload of each property must be 64 KB or less - - // Create a new customer entity. - CustomerEntity customer1 = new CustomerEntity("Harp", "Walter"); - customer1.setEmail("Walter@contoso.com"); - customer1.setPhoneNumber("425-555-0101"); - - // Create an operation to add the new customer to the tablebasics table. - TableOperation insertCustomer1 = TableOperation.insert(customer1); - - // Submit the operation to the table service. - tableClient.execute(tableName, insertCustomer1); - } - - /** - * Illustrates how to form and execute a batch operation. - * @throws StorageException - */ - public static void BasicBatch() throws StorageException { - // Note: the limitations on a batch operation are - // - up to 100 operations - // - all operations must share the same PartitionKey - // - if a retrieve is used it can be the only operation in the batch - // - the serialized batch payload must be 4 MB or less - - // Define a batch operation. - TableBatchOperation batchOperation = new TableBatchOperation(); - - // Create a customer entity to add to the table. - CustomerEntity customer = new CustomerEntity("Smith", "Jeff"); - customer.setEmail("Jeff@contoso.com"); - customer.setPhoneNumber("425-555-0104"); - batchOperation.insert(customer); - - // Create another customer entity to add to the table. - CustomerEntity customer2 = new CustomerEntity("Smith", "Ben"); - customer2.setEmail("Ben@contoso.com"); - customer2.setPhoneNumber("425-555-0102"); - batchOperation.insert(customer2); - - // Create a third customer entity to add to the table. - CustomerEntity customer3 = new CustomerEntity("Smith", "Denise"); - customer3.setEmail("Denise@contoso.com"); - customer3.setPhoneNumber("425-555-0103"); - batchOperation.insert(customer3); - - // Execute the batch of operations on the "tablebasics" table. - tableClient.execute(tableName, batchOperation); - } - - /** - * Illustrates how to form and execute a query operation. - * @throws StorageException - */ - public static void BasicQuery() throws StorageException { - // Retrieve a single entity. - // Retrieve the entity with partition key of "Smith" and row key of "Jeff". - TableOperation retrieveSmithJeff = - TableOperation.retrieve("Smith", "Jeff", CustomerEntity.class); - - // Submit the operation to the table service and get the specific entity. - @SuppressWarnings("unused") - CustomerEntity specificEntity = - tableClient.execute(tableName, retrieveSmithJeff).getResultAsType(); - - // Retrieve all entities in a partition. - // Create a filter condition where the partition key is "Smith". - String partitionFilter = TableQuery.generateFilterCondition( - TableConstants.PARTITION_KEY, - QueryComparisons.EQUAL, - "Smith"); - - // Specify a partition query, using "Smith" as the partition key filter. - TableQuery partitionQuery = - TableQuery.from(tableName, CustomerEntity.class) - .where(partitionFilter); - - // Loop through the results, displaying information about the entity. - for (CustomerEntity entity : tableClient.execute(partitionQuery)) { - System.out.println(entity.getPartitionKey() + " " + entity.getRowKey() + - "\t" + entity.getEmail() + "\t" + entity.getPhoneNumber()); - } - } - - /** - * Illustrates how to form and execute an upsert operation. - * @throws StorageException - */ - public static void BasicUpsert() throws StorageException { - // Retrieve the entity with partition key of "Smith" and row key of "Jeff". - TableOperation retrieveSmithJeff = - TableOperation.retrieve("Smith", "Jeff", CustomerEntity.class); - - // Submit the operation to the table service and get the specific entity. - CustomerEntity specificEntity = - tableClient.execute(tableName, retrieveSmithJeff).getResultAsType(); - - // Specify a new phone number. - specificEntity.setPhoneNumber("425-555-0105"); - - // Create an operation to replace the entity. - TableOperation replaceEntity = TableOperation.merge(specificEntity); - - // Submit the operation to the table service. - tableClient.execute(tableName, replaceEntity); - } - - /** - * Illustrates how to form and execute an entity delete operation. - * @throws StorageException - */ - public static void BasicDeleteEntity() throws StorageException { - // Create an operation to retrieve the entity with partition key of "Smith" and row key of "Jeff". - TableOperation retrieveSmithJeff = TableOperation.retrieve("Smith", "Jeff", CustomerEntity.class); - - // Retrieve the entity with partition key of "Smith" and row key of "Jeff". - CustomerEntity entitySmithJeff = - tableClient.execute(tableName, retrieveSmithJeff).getResultAsType(); - - // Create an operation to delete the entity. - TableOperation deleteSmithJeff = TableOperation.delete(entitySmithJeff); - - // Submit the delete operation to the table service. - tableClient.execute(tableName, deleteSmithJeff); - } - - /** - * Illustrates how to list the tables. - * @throws StorageException - */ - public static void BasicListing() throws StorageException { - // List the tables with a given prefix. - Iterable listTables = tableClient.listTables(tableName, null, null); - for (String s : listTables) { - System.out.println(s); - } - } -}